From 746ed6eb91d07983a273b8e444a5cdad4495eda6 Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sun, 5 Oct 2025 19:03:08 +0200 Subject: [PATCH 01/19] future and historical selection UI --- proxy/index.html | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/proxy/index.html b/proxy/index.html index 9222e9d8..c156d9c5 100644 --- a/proxy/index.html +++ b/proxy/index.html @@ -156,6 +156,47 @@ Control the theme of OpenRailwayMap. The default is to follow the system and browser preferences. A light or dark theme can also be configured. +
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + Control which future infrastructure should be shown on the map. + +
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + Control which future railway infrastructure should be shown on the map.
+ Note: Tagging and non-existing features in OpenStreetMap like demolished railways is discouraged. It is encouraged instead to use the OpenHistoricalMap to create and maintain historical data. +
+
From 2b6781c52673c90cfa97c09342921b20d8b79db9 Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sun, 5 Oct 2025 19:05:58 +0200 Subject: [PATCH 02/19] store historical and future infrastructure --- proxy/js/ui.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/proxy/js/ui.js b/proxy/js/ui.js index 7c072e5b..2b23e9d0 100644 --- a/proxy/js/ui.js +++ b/proxy/js/ui.js @@ -598,6 +598,14 @@ function onEditorChange(editor) { updateConfiguration('editor', editor); } +function onHistoricalInfrastructureChange(historicalInfrastructure) { + updateConfiguration('historicalInfrastructure', historicalInfrastructure); +} + +function onFutureInfrastructureChange(futureInfrastructure) { + updateConfiguration('futureInfrastructure', futureInfrastructure); +} + function updateBackgroundMapContainer() { backgroundMapContainer.style.filter = `saturate(${clamp(configuration.backgroundSaturation ?? defaultConfiguration.backgroundSaturation, 0.0, 1.0)}) opacity(${clamp(configuration.backgroundOpacity ?? defaultConfiguration.backgroundOpacity, 0.0, 1.0)})`; } @@ -608,6 +616,8 @@ const defaultConfiguration = { backgroundType: 'raster', backgroundUrl: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', theme: 'system', + historicalInfrastructure: 'openhistoricalmap', + futureInfrastructure: 'construction-proposed', editor: 'id', view: {}, }; From 2d745abef480433aa05dab12c517b65ce233acd1 Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sun, 5 Oct 2025 19:10:28 +0200 Subject: [PATCH 03/19] configure UI --- proxy/js/ui.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/proxy/js/ui.js b/proxy/js/ui.js index 2b23e9d0..d9ea5ec7 100644 --- a/proxy/js/ui.js +++ b/proxy/js/ui.js @@ -18,6 +18,12 @@ const backgroundUrlControl = document.getElementById('backgroundUrl'); const themeSystemControl = document.getElementById('themeSystem'); const themeDarkControl = document.getElementById('themeDark'); const themeLightControl = document.getElementById('themeLight'); +const historicalInfrastructureNoneControl = document.getElementById('historicalInfrastructureNone'); +const historicalInfrastructureOpenHistoricalMapControl = document.getElementById('historicalInfrastructureOpenHistoricalMap'); +const historicalInfrastructureOpenStreetMapControl = document.getElementById('historicalInfrastructureOpenStreetMap'); +const futureInfrastructureNoneControl = document.getElementById('futureInfrastructureNone'); +const futureInfrastructureConstructionControl = document.getElementById('futureInfrastructureConstruction'); +const futureInfrastructureConstructionProposedControl = document.getElementById('futureInfrastructureConstructionProposed'); const editorIDControl = document.getElementById('editorID'); const editorJOSMControl = document.getElementById('editorJOSM'); const backgroundMapContainer = document.getElementById('background-map'); @@ -242,6 +248,24 @@ function showConfiguration() { themeLightControl.checked = true; } + const futureInfrastructure = configuration.futureInfrastructure ?? defaultConfiguration.futureInfrastructure; + if (futureInfrastructure === 'none') { + futureInfrastructureNoneControl.checked = true; + } else if (futureInfrastructure === 'construction') { + futureInfrastructureConstructionControl.checked = true + } else if (futureInfrastructure === 'construction-proposed') { + futureInfrastructureConstructionProposedControl.checked = true; + } + + const historicalInfrastructure = configuration.historicalInfrastructure ?? defaultConfiguration.historicalInfrastructure; + if (historicalInfrastructure === 'none') { + historicalInfrastructureNoneControl.checked = true; + } else if (historicalInfrastructure === 'openhistoricalmap') { + historicalInfrastructureOpenHistoricalMapControl.checked = true + } else if (historicalInfrastructure === 'openstreetmap') { + historicalInfrastructureOpenStreetMapControl.checked = true; + } + const editor = configuration.editor ?? defaultConfiguration.editor; if (editor === 'josm') { editorJOSMControl.checked = true; From 1c04cd5d7fb74d1bf35d2d77a1677658b007383d Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sun, 5 Oct 2025 19:38:51 +0200 Subject: [PATCH 04/19] render abandoned and razed railways --- proxy/js/styles.mjs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/proxy/js/styles.mjs b/proxy/js/styles.mjs index 6416b541..6f82464b 100644 --- a/proxy/js/styles.mjs +++ b/proxy/js/styles.mjs @@ -1601,7 +1601,21 @@ const layers = { // High zooms // ensure that width interpolation matches medium zooms - + { + id: 'railway_line_abandoned_razed', + minzoom: 12, + source: 'high', + states: { + abandoned: abandoned_dasharray, + razed: razed_dasharray, + }, + filter: ['any', + ['==', ['get', 'state'], 'abandoned'], + ['==', ['get', 'state'], 'razed'], + ], + width: 2, + color: colors.styles.standard.abandoned, + }, { id: 'railway_line_miniature', minzoom: 12, From 519f829d1a9ffa88193b309c06bd82a5524395fb Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sun, 5 Oct 2025 19:38:59 +0200 Subject: [PATCH 05/19] render openhistorical map always --- proxy/js/styles.mjs | 258 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) diff --git a/proxy/js/styles.mjs b/proxy/js/styles.mjs index 6f82464b..fdd4510f 100644 --- a/proxy/js/styles.mjs +++ b/proxy/js/styles.mjs @@ -1388,6 +1388,216 @@ const imageLayerWithOutline = (id, spriteExpression, layer) => [ */ const layers = { standard: [ + ...historicalRailwayLine( + ['step', ['zoom'], + ['coalesce', ['get', 'ref'], ''], + 11, + ['coalesce', ['get', 'name'], ''], + ], + [ + { + id: 'railway_line_historical_miniature', + minzoom: 12, + filter: ['==', ['get', 'type'], 'miniature'], + color: colors.styles.standard.miniature, + dash: abandoned_dasharray, + width: 2, + }, + { + id: 'railway_line_historical_funicular', + minzoom: 12, + filter: ['==', ['get', 'type'], 'funicular'], + color: colors.styles.standard.funicular, + dash: abandoned_dasharray, + width: 2, + }, + { + id: 'railway_line_historical_disused', + minzoom: 11, + filter: ['==', ['get', 'type'], 'disused'], + color: colors.styles.standard.disused, + dash: abandoned_dasharray, + width: 1.5, + }, + { + id: 'railway_line_historical_abandoned', + minzoom: 11, + filter: ['==', ['get', 'type'], 'abandoned'], + color: colors.styles.standard.abandoned, + dash: abandoned_dasharray, + width: 1.5, + }, + // TODO + // { + // id: 'railway_line_historical_construction', + // minzoom: 10, + // filter: ['==', ['get', 'type'], 'construction'], + // color: colors.styles.standard.main, + // dash: construction_dasharray, + // width: 1.5, + // }, + // TODO + // { + // id: 'railway_line_historical_proposed', + // minzoom: 10, + // filter: ['==', ['get', 'type'], 'proposed'], + // color: colors.styles.standard.main, + // dash: proposed_dasharray, + // width: 1.5, + // }, + { + id: 'railway_line_historical_narrow_gauge', + minzoom: 10, + filter: ['all', + ['==', ['get', 'type'], 'narrow_gauge'], + ['!', + // Covered by industrial case + ['==', ['get', 'usage'], 'industrial'], + ], + ], + color: colors.styles.standard.narrowGauge, + dash: abandoned_dasharray, + width: 2, + }, + { + id: 'railway_line_historical_service', + minzoom: 10, + filter: ['all', + ['==', ['get', 'type'], 'rail'], + ['==', ['get', 'usage'], null], + ], + color: ['match', ['get', 'service'], + 'spur', colors.styles.standard.spur, + 'siding', colors.styles.standard.siding, + 'yard', colors.styles.standard.yard, + 'crossover', colors.styles.standard.crossover, + colors.styles.standard.unknown, + ], + dash: abandoned_dasharray, + width: ["interpolate", ["exponential", 1.2], ["zoom"], + 8, ['match', ['get', 'service'], + 'yard', 1, + 1.5, + ], + 15, ['match', ['get', 'service'], + 'yard', 1, + 1.5, + ], + 16, 2, + ], + }, + { + id: 'railway_line_historical_light_rail', + minzoom: 9, + filter: ['any', + ['==', ['get', 'type'], 'subway'], + ['==', ['get', 'type'], 'tram'], + ['==', ['get', 'type'], 'light_rail'], + ['==', ['get', 'type'], 'monorail'], + ], + width: 2, + color: ['match', ['get', 'type'], + 'light_rail', colors.styles.standard.light_rail, + 'monorail', colors.styles.standard.monorail, + 'subway', colors.styles.standard.subway, + 'tram', colors.styles.standard.tram, + colors.styles.standard.unknown, + ], + dash: abandoned_dasharray, + }, + { + id: 'railway_line_historical_test_military', + minzoom: 9, + filter: ['all', + ['==', ['get', 'type'], 'rail'], + ['any', + ['==', ['get', 'usage'], 'test'], + ['==', ['get', 'usage'], 'military'], + ], + ], + width: ["interpolate", ["exponential", 1.2], ["zoom"], + 8, 1.5, + 14, 1.5, + 16, 2, + ], + color: ['match', ['get', 'usage'], + 'test', colors.styles.standard.test, + 'military', colors.styles.standard.military, + colors.styles.standard.unknown, + ], + dash: abandoned_dasharray, + }, + { + id: 'railway_line_historical_tourism', + minzoom: 9, + filter: ['any', + ['all', + ['==', ['get', 'type'], 'rail'], + ['==', ['get', 'usage'], 'tourism'], + ], + ['==', ['get', 'type'], 'preserved'], + ], + width: 2, + color: colors.styles.standard.tourism, + dash: abandoned_dasharray, + }, + { + id: 'railway_line_historical_industrial', + minzoom: 9, + filter: ['all', + ['==', ['get', 'usage'], 'industrial'], + ['any', + ['==', ['get', 'type'], 'rail'], + ['==', ['get', 'type'], 'narrow_gauge'], + ], + ], + width: ["interpolate", ["exponential", 1.2], ["zoom"], + 8, 1.5, + 14, 1.5, + 16, 2, + ], + color: colors.styles.standard.industrial, + dash: abandoned_dasharray, + }, + { + id: 'railway_line_historical_branch', + minzoom: 7, + filter: ['all', + ['==', ['get', 'type'], 'rail'], + ['==', ['get', 'usage'], 'branch'], + ], + width: ["interpolate", ["exponential", 1.2], ["zoom"], + 8, 2, + 14, 2, + 16, 3, + ], + color: colors.styles.standard.branch, + dash: abandoned_dasharray, + }, + { + id: 'railway_line_historical_main', + minzoom: 5, + filter: ['all', + ['==', ['get', 'type'], 'rail'], + ['==', ['get', 'usage'], 'main'], + ], + width: ["interpolate", ["exponential", 1.2], ["zoom"], + 8, 2, + 14, 2, + 16, 3, + ], + color: ['case', + ['==', ['get', 'highspeed'], 'yes'], colors.styles.standard.highspeed, + colors.styles.standard.main, + ], + hoverColor: ['case', + ['==', ['get', 'highspeed'], 'yes'], colors.hover.alternative, + colors.hover.main, + ], + dash: abandoned_dasharray, + }, + ], + ), { id: 'railway_grouped_stations', type: 'fill', @@ -2362,6 +2572,54 @@ const layers = { 'text-max-width': 5, }, }, + { + id: 'historical_stations', + type: 'symbol', + minzoom: 14, + source: 'openhistoricalmap', + 'source-layer': 'transport_points_centroids', + filter: ['all', + ['<=', ['coalesce', ['get', 'start_decdate'], 0.0], ['global-state', 'date']], + ['<=', ['global-state', 'date'], ['coalesce', ['get', 'end_decdate'], 9999.0]], + ['==', ['get', 'class'], 'railway'], + ['any', + ['==', ['get', 'type'], 'station'], + ['==', ['get', 'type'], 'halt'], + ] + ], + paint: { + 'text-color': ['case', + ['==', ['get', 'type'], 'halt'], colors.styles.standard.tramStopText, + colors.styles.standard.stationsText, + ], + 'text-halo-color': ['case', + ['boolean', ['feature-state', 'hover'], false], colors.hover.textHalo, + colors.halo, + ], + 'text-halo-width': 1.5, + 'icon-color': ['case', + ['==', ['get', 'type'], 'halt'], colors.styles.standard.tramStopText, + colors.styles.standard.stationsText, + ], + 'icon-halo-width': 1, + 'icon-halo-color': ['case', + ['boolean', ['feature-state', 'hover'], false], colors.hover.textHalo, + colors.halo, + ], + }, + layout: { + 'symbol-z-order': 'source', + 'icon-image': 'sdf:general/station-small', + 'icon-overlap': 'always', + 'text-field': '{name}', + 'text-font': font.bold, + 'text-size': 11, + 'text-padding': 10, + 'text-max-width': 5, + 'text-optional': true, + 'text-variable-anchor': ['top', 'bottom', 'left', 'right'], + }, + }, searchResults, ], historical: [ From 4673c730dcef43071a055fd9ad6a9ae84dc564c7 Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sun, 5 Oct 2025 19:40:57 +0200 Subject: [PATCH 06/19] open OpenHistoricalMap attribution in new tab --- proxy/js/styles.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proxy/js/styles.mjs b/proxy/js/styles.mjs index fdd4510f..bfe88fa0 100644 --- a/proxy/js/styles.mjs +++ b/proxy/js/styles.mjs @@ -696,7 +696,7 @@ const sources = { openhistoricalmap: { type: 'vector', tiles: [`https://vtiles.openhistoricalmap.org/maps/osm/{z}/{x}/{y}.pbf`], - attribution: 'OpenHistoricalMap', + attribution: 'OpenHistoricalMap', }, }; From b6c2afa5854d14eaca0ab887028b4136b971b370 Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sun, 5 Oct 2025 19:41:12 +0200 Subject: [PATCH 07/19] open OpenHistoricalMap attribution in new tab --- proxy/js/styles.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proxy/js/styles.mjs b/proxy/js/styles.mjs index bfe88fa0..d52bc2c4 100644 --- a/proxy/js/styles.mjs +++ b/proxy/js/styles.mjs @@ -695,7 +695,7 @@ const sources = { }, openhistoricalmap: { type: 'vector', - tiles: [`https://vtiles.openhistoricalmap.org/maps/osm/{z}/{x}/{y}.pbf`], + tiles: ['https://vtiles.openhistoricalmap.org/maps/osm/{z}/{x}/{y}.pbf'], attribution: 'OpenHistoricalMap', }, }; From 6e4a6f751c28d6db750e5a7fe1f5c7516f213aa3 Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sun, 5 Oct 2025 19:43:01 +0200 Subject: [PATCH 08/19] razed state --- import/openrailwaymap.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/import/openrailwaymap.lua b/import/openrailwaymap.lua index 8a3d3501..2abdcd08 100644 --- a/import/openrailwaymap.lua +++ b/import/openrailwaymap.lua @@ -660,7 +660,7 @@ local railway_state_tags = { disused = 'disused:railway', abandoned = 'abandoned:railway', preserved = 'preserved:railway', - -- Razed is not included + razed = 'razed:railway', } function railway_feature_and_state(tags, railway_value_func) for state, railway_tag in pairs(railway_state_tags) do From c2541a9b42c4fc03c9975498cae8319a63867244 Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sun, 5 Oct 2025 19:44:39 +0200 Subject: [PATCH 09/19] razed state --- proxy/js/styles.mjs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/proxy/js/styles.mjs b/proxy/js/styles.mjs index d52bc2c4..9c2b086a 100644 --- a/proxy/js/styles.mjs +++ b/proxy/js/styles.mjs @@ -1812,17 +1812,24 @@ const layers = { // High zooms // ensure that width interpolation matches medium zooms { - id: 'railway_line_abandoned_razed', + id: 'railway_line_razed', minzoom: 12, source: 'high', states: { - abandoned: abandoned_dasharray, razed: razed_dasharray, }, - filter: ['any', - ['==', ['get', 'state'], 'abandoned'], - ['==', ['get', 'state'], 'razed'], - ], + filter: ['==', ['get', 'state'], 'razed'], + width: 2, + color: colors.styles.standard.razed, + }, + { + id: 'railway_line_abandoned', + minzoom: 12, + source: 'high', + states: { + abandoned: abandoned_dasharray, + }, + filter: ['==', ['get', 'state'], 'abandoned'], width: 2, color: colors.styles.standard.abandoned, }, From a1a2b42f1783fe2b3807e95e8da8b74d6c1721e5 Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sun, 5 Oct 2025 20:15:35 +0200 Subject: [PATCH 10/19] filter layers on global state matching line state --- proxy/js/styles.mjs | 89 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 74 insertions(+), 15 deletions(-) diff --git a/proxy/js/styles.mjs b/proxy/js/styles.mjs index 9c2b086a..30f83e12 100644 --- a/proxy/js/styles.mjs +++ b/proxy/js/styles.mjs @@ -725,10 +725,14 @@ const railwayLine = (text, layers) => [ source, 'source-layer': 'railway_line_high', filter: ['all', + state === 'construction' ? ['global-state', 'showConstructionInfrastructure'] : true, + state === 'proposed' ? ['global-state', 'showProposedInfrastructure'] : true, + state === 'abandoned' ? ['global-state', 'showAbandonedInfrastructure'] : true, + state === 'razed' ? ['global-state', 'showRazedInfrastructure'] : true, ['==', ['get', 'state'], state], ['get', 'tunnel'], filter ?? true, - ], + ].filter(it => it !== true), layout: { 'line-join': 'round', 'line-cap': dash ? 'butt' : 'round', @@ -751,10 +755,14 @@ const railwayLine = (text, layers) => [ source, 'source-layer': 'railway_line_high', filter: ['all', + state === 'construction' ? ['global-state', 'showConstructionInfrastructure'] : true, + state === 'proposed' ? ['global-state', 'showProposedInfrastructure'] : true, + state === 'abandoned' ? ['global-state', 'showAbandonedInfrastructure'] : true, + state === 'razed' ? ['global-state', 'showRazedInfrastructure'] : true, ['==', ['get', 'state'], state], ['get', 'tunnel'], filter ?? true, - ], + ].filter(it => it !== true), layout: { 'line-join': 'round', 'line-cap': dash ? 'butt' : 'round', @@ -778,10 +786,16 @@ const railwayLine = (text, layers) => [ source, 'source-layer': 'railway_line_high', filter: ['all', - ['any', ...Object.keys(states).map(state => ['==', ['get', 'state'], state])], + ['any', ...Object.keys(states).map(state => + state === 'construction' ? ['all', ['global-state', 'showConstructionInfrastructure'], ['==', ['get', 'state'], state]] + : state === 'proposed' ? ['all', ['global-state', 'showProposedInfrastructure'], ['==', ['get', 'state'], state]] + : state === 'abandoned' ? ['all', ['global-state', 'showAbandonedInfrastructure'], ['==', ['get', 'state'], state]] + : state === 'razed' ? ['all', ['global-state', 'showRazedInfrastructure'], ['==', ['get', 'state'], state]] + : ['==', ['get', 'state'], state]) + ], ['get', 'tunnel'], filter ?? true, - ], + ].filter(it => it !== true), layout: { 'line-join': 'round', 'line-cap': 'butt', @@ -796,14 +810,20 @@ const railwayLine = (text, layers) => [ preferredDirectionLayer(`${id}_tunnel_preferred_direction`, ['all', ['get', 'tunnel'], - ['any', ...Object.keys(states).map(state => ['==', ['get', 'state'], state])], + ['any', ...Object.keys(states).map(state => + state === 'construction' ? ['all', ['global-state', 'showConstructionInfrastructure'], ['==', ['get', 'state'], state]] + : state === 'proposed' ? ['all', ['global-state', 'showProposedInfrastructure'], ['==', ['get', 'state'], state]] + : state === 'abandoned' ? ['all', ['global-state', 'showAbandonedInfrastructure'], ['==', ['get', 'state'], state]] + : state === 'razed' ? ['all', ['global-state', 'showRazedInfrastructure'], ['==', ['get', 'state'], state]] + : ['==', ['get', 'state'], state]) + ], ['any', ['==', ['get', 'preferred_direction'], 'forward'], ['==', ['get', 'preferred_direction'], 'backward'], ['==', ['get', 'preferred_direction'], 'both'], ], filter ?? true, - ], + ].filter(it => it !== true), color, ), ), @@ -819,11 +839,15 @@ const railwayLine = (text, layers) => [ source, 'source-layer': 'railway_line_high', filter: ['all', + state === 'construction' ? ['global-state', 'showConstructionInfrastructure'] : true, + state === 'proposed' ? ['global-state', 'showProposedInfrastructure'] : true, + state === 'abandoned' ? ['global-state', 'showAbandonedInfrastructure'] : true, + state === 'razed' ? ['global-state', 'showRazedInfrastructure'] : true, ['==', ['get', 'state'], state], ['!', ['get', 'bridge']], ['!', ['get', 'tunnel']], filter ?? true, - ], + ].filter(it => it !== true), layout: { 'line-join': 'round', 'line-cap': 'butt', @@ -846,11 +870,15 @@ const railwayLine = (text, layers) => [ source, 'source-layer': 'railway_line_high', filter: ['all', + state === 'construction' ? ['global-state', 'showConstructionInfrastructure'] : true, + state === 'proposed' ? ['global-state', 'showProposedInfrastructure'] : true, + state === 'abandoned' ? ['global-state', 'showAbandonedInfrastructure'] : true, + state === 'razed' ? ['global-state', 'showRazedInfrastructure'] : true, ['==', ['get', 'state'], state], ['!', ['get', 'bridge']], ['!', ['get', 'tunnel']], filter ?? true, - ], + ].filter(it => it !== true), layout: { 'line-join': 'round', 'line-cap': dash ? 'butt' : 'round', @@ -890,7 +918,7 @@ const railwayLine = (text, layers) => [ ], ], filter ?? true, - ], + ].filter(it => it !== true), layout: { 'line-join': 'round', 'line-cap': 'butt', @@ -920,7 +948,7 @@ const railwayLine = (text, layers) => [ ], ], filter ?? true, - ], + ].filter(it => it !== true), layout: { 'line-join': 'round', 'line-cap': 'butt', @@ -943,10 +971,14 @@ const railwayLine = (text, layers) => [ source, 'source-layer': 'railway_line_high', filter: ['all', + state === 'construction' ? ['global-state', 'showConstructionInfrastructure'] : true, + state === 'proposed' ? ['global-state', 'showProposedInfrastructure'] : true, + state === 'abandoned' ? ['global-state', 'showAbandonedInfrastructure'] : true, + state === 'razed' ? ['global-state', 'showRazedInfrastructure'] : true, ['==', ['get', 'state'], state], ['get', 'bridge'], filter ?? true, - ], + ].filter(it => it !== true), layout: { 'line-join': 'round', 'line-cap': dash ? 'butt' : 'round', @@ -969,7 +1001,13 @@ const railwayLine = (text, layers) => [ preferredDirectionLayer( `${id}_preferred_direction`, ['all', - ['any', ...Object.keys(states).map(state => ['==', ['get', 'state'], state])], + ['any', ...Object.keys(states).map(state => + state === 'construction' ? ['all', ['global-state', 'showConstructionInfrastructure'], ['==', ['get', 'state'], state]] + : state === 'proposed' ? ['all', ['global-state', 'showProposedInfrastructure'], ['==', ['get', 'state'], state]] + : state === 'abandoned' ? ['all', ['global-state', 'showAbandonedInfrastructure'], ['==', ['get', 'state'], state]] + : state === 'razed' ? ['all', ['global-state', 'showRazedInfrastructure'], ['==', ['get', 'state'], state]] + : ['==', ['get', 'state'], state]) + ], ['!', ['get', 'tunnel']], ['any', ['==', ['get', 'preferred_direction'], 'forward'], @@ -977,7 +1015,7 @@ const railwayLine = (text, layers) => [ ['==', ['get', 'preferred_direction'], 'both'], ], filter ?? true, - ], + ].filter(it => it !== true), color, ), ), @@ -994,9 +1032,15 @@ const railwayLine = (text, layers) => [ source, 'source-layer': 'railway_line_high', filter: ['all', - ['any', ...Object.keys(states).map(state => ['==', ['get', 'state'], state])], + ['any', ...Object.keys(states).map(state => + state === 'construction' ? ['all', ['global-state', 'showConstructionInfrastructure'], ['==', ['get', 'state'], state]] + : state === 'proposed' ? ['all', ['global-state', 'showProposedInfrastructure'], ['==', ['get', 'state'], state]] + : state === 'abandoned' ? ['all', ['global-state', 'showAbandonedInfrastructure'], ['==', ['get', 'state'], state]] + : state === 'razed' ? ['all', ['global-state', 'showRazedInfrastructure'], ['==', ['get', 'state'], state]] + : ['==', ['get', 'state'], state]) + ], filter ?? true, - ], + ].filter(it => it !== true), paint: { 'text-color': colors.railwayLine.text, 'text-halo-color': ['case', @@ -4498,6 +4542,21 @@ const makeStyle = selectedStyle => ({ theme: { default: 'light', }, + showConstructionInfrastructure: { + default: true, + }, + showProposedInfrastructure: { + default: true, + }, + showAbandonedInfrastructure: { + default: true, + }, + showRazedInfrastructure: { + default: true, + }, + openHistoricalMap: { + default: true, + }, }, }); From 63732402f1e964147363796630872f7ef818d743 Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sun, 5 Oct 2025 20:29:27 +0200 Subject: [PATCH 11/19] openhistoricalmap global state check --- proxy/js/styles.mjs | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/proxy/js/styles.mjs b/proxy/js/styles.mjs index 30f83e12..c011ca2a 100644 --- a/proxy/js/styles.mjs +++ b/proxy/js/styles.mjs @@ -1075,11 +1075,12 @@ const historicalRailwayLine = (text, layers) => [ source: 'openhistoricalmap', 'source-layer': 'transport_lines', filter: ['all', + ['global-state', 'openHistoricalMap'], ['<=', ['coalesce', ['get', 'start_decdate'], 0.0], ['global-state', 'date']], ['<=', ['global-state', 'date'], ['coalesce', ['get', 'end_decdate'], 9999.0]], ['==', ['get', 'tunnel'], 1], filter ?? true, - ], + ].filter(it => it !== true), layout: { 'line-join': 'round', 'line-cap': dash ? 'butt' : 'round', @@ -1100,11 +1101,12 @@ const historicalRailwayLine = (text, layers) => [ source: 'openhistoricalmap', 'source-layer': 'transport_lines', filter: ['all', + ['global-state', 'openHistoricalMap'], ['<=', ['coalesce', ['get', 'start_decdate'], 0.0], ['global-state', 'date']], ['<=', ['global-state', 'date'], ['coalesce', ['get', 'end_decdate'], 9999.0]], ['==', ['get', 'tunnel'], 1], filter ?? true, - ], + ].filter(it => it !== true), layout: { 'line-join': 'round', 'line-cap': dash ? 'butt' : 'round', @@ -1127,11 +1129,12 @@ const historicalRailwayLine = (text, layers) => [ source: 'openhistoricalmap', 'source-layer': 'transport_lines', filter: ['all', + ['global-state', 'openHistoricalMap'], ['<=', ['coalesce', ['get', 'start_decdate'], 0.0], ['global-state', 'date']], ['<=', ['global-state', 'date'], ['coalesce', ['get', 'end_decdate'], 9999.0]], ['==', ['get', 'tunnel'], 1], filter ?? true, - ], + ].filter(it => it !== true), layout: { 'line-join': 'round', 'line-cap': 'butt', @@ -1153,12 +1156,13 @@ const historicalRailwayLine = (text, layers) => [ source: 'openhistoricalmap', 'source-layer': 'transport_lines', filter: ['all', + ['global-state', 'openHistoricalMap'], ['<=', ['coalesce', ['get', 'start_decdate'], 0.0], ['global-state', 'date']], ['<=', ['global-state', 'date'], ['coalesce', ['get', 'end_decdate'], 9999.0]], ['!=', ['get', 'bridge'], 1], ['!=', ['get', 'tunnel'], 1], filter ?? true, - ], + ].filter(it => it !== true), layout: { 'line-join': 'round', 'line-cap': 'butt', @@ -1179,12 +1183,13 @@ const historicalRailwayLine = (text, layers) => [ source: 'openhistoricalmap', 'source-layer': 'transport_lines', filter: ['all', + ['global-state', 'openHistoricalMap'], ['<=', ['coalesce', ['get', 'start_decdate'], 0.0], ['global-state', 'date']], ['<=', ['global-state', 'date'], ['coalesce', ['get', 'end_decdate'], 9999.0]], ['!=', ['get', 'bridge'], 1], ['!=', ['get', 'tunnel'], 1], filter ?? true, - ], + ].filter(it => it !== true), layout: { 'line-join': 'round', 'line-cap': dash ? 'butt' : 'round', @@ -1211,11 +1216,12 @@ const historicalRailwayLine = (text, layers) => [ source: 'openhistoricalmap', 'source-layer': 'transport_lines', filter: ['all', + ['global-state', 'openHistoricalMap'], ['<=', ['coalesce', ['get', 'start_decdate'], 0.0], ['global-state', 'date']], ['<=', ['global-state', 'date'], ['coalesce', ['get', 'end_decdate'], 9999.0]], ['==', ['get', 'bridge'], 1], filter ?? true, - ], + ].filter(it => it !== true), layout: { 'line-join': 'round', 'line-cap': 'butt', @@ -1235,11 +1241,12 @@ const historicalRailwayLine = (text, layers) => [ source: 'openhistoricalmap', 'source-layer': 'transport_lines', filter: ['all', + ['global-state', 'openHistoricalMap'], ['<=', ['coalesce', ['get', 'start_decdate'], 0.0], ['global-state', 'date']], ['<=', ['global-state', 'date'], ['coalesce', ['get', 'end_decdate'], 9999.0]], ['==', ['get', 'bridge'], 1], filter ?? true, - ], + ].filter(it => it !== true), layout: { 'line-join': 'round', 'line-cap': 'butt', @@ -1261,11 +1268,12 @@ const historicalRailwayLine = (text, layers) => [ source: 'openhistoricalmap', 'source-layer': 'transport_lines', filter: ['all', + ['global-state', 'openHistoricalMap'], ['<=', ['coalesce', ['get', 'start_decdate'], 0.0], ['global-state', 'date']], ['<=', ['global-state', 'date'], ['coalesce', ['get', 'end_decdate'], 9999.0]], ['==', ['get', 'bridge'], 1], filter ?? true, - ], + ].filter(it => it !== true), layout: { 'line-join': 'round', 'line-cap': dash ? 'butt' : 'round', @@ -1291,10 +1299,11 @@ const historicalRailwayLine = (text, layers) => [ source: 'openhistoricalmap', 'source-layer': 'transport_lines', filter: ['all', + ['global-state', 'openHistoricalMap'], ['<=', ['coalesce', ['get', 'start_decdate'], 0.0], ['global-state', 'date']], ['<=', ['global-state', 'date'], ['coalesce', ['get', 'end_decdate'], 9999.0]], filter ?? true, - ], + ].filter(it => it !== true), paint: { 'text-color': colors.railwayLine.text, 'text-halo-color': ['case', @@ -2630,6 +2639,7 @@ const layers = { source: 'openhistoricalmap', 'source-layer': 'transport_points_centroids', filter: ['all', + ['global-state', 'openHistoricalMap'], ['<=', ['coalesce', ['get', 'start_decdate'], 0.0], ['global-state', 'date']], ['<=', ['global-state', 'date'], ['coalesce', ['get', 'end_decdate'], 9999.0]], ['==', ['get', 'class'], 'railway'], @@ -2879,6 +2889,7 @@ const layers = { source: 'openhistoricalmap', 'source-layer': 'transport_points_centroids', filter: ['all', + ['global-state', 'openHistoricalMap'], ['<=', ['coalesce', ['get', 'start_decdate'], 0.0], ['global-state', 'date']], ['<=', ['global-state', 'date'], ['coalesce', ['get', 'end_decdate'], 9999.0]], ['==', ['get', 'class'], 'railway'], From 62f11108d996053a6bbe9c0ea013d94be81e58b4 Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sun, 5 Oct 2025 20:29:34 +0200 Subject: [PATCH 12/19] defaults --- proxy/index.html | 2 +- proxy/js/styles.mjs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/proxy/index.html b/proxy/index.html index c156d9c5..6c11a300 100644 --- a/proxy/index.html +++ b/proxy/index.html @@ -189,7 +189,7 @@
- +
diff --git a/proxy/js/styles.mjs b/proxy/js/styles.mjs index c011ca2a..7973d195 100644 --- a/proxy/js/styles.mjs +++ b/proxy/js/styles.mjs @@ -4560,10 +4560,10 @@ const makeStyle = selectedStyle => ({ default: true, }, showAbandonedInfrastructure: { - default: true, + default: false, }, showRazedInfrastructure: { - default: true, + default: false, }, openHistoricalMap: { default: true, From 85ed34b6ffd541073d56a49666bd6224a47c2d53 Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sun, 5 Oct 2025 20:36:45 +0200 Subject: [PATCH 13/19] put configuration on the map --- proxy/js/ui.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/proxy/js/ui.js b/proxy/js/ui.js index d9ea5ec7..440eb578 100644 --- a/proxy/js/ui.js +++ b/proxy/js/ui.js @@ -624,10 +624,17 @@ function onEditorChange(editor) { function onHistoricalInfrastructureChange(historicalInfrastructure) { updateConfiguration('historicalInfrastructure', historicalInfrastructure); + + map.setGlobalStateProperty('openHistoricalMap', historicalInfrastructure === 'openhistoricalmap'); + map.setGlobalStateProperty('showAbandonedInfrastructure', historicalInfrastructure === 'openstreetmap'); + map.setGlobalStateProperty('showRazedInfrastructure', historicalInfrastructure === 'openstreetmap'); } function onFutureInfrastructureChange(futureInfrastructure) { updateConfiguration('futureInfrastructure', futureInfrastructure); + + map.setGlobalStateProperty('showConstructionInfrastructure', futureInfrastructure === 'construction' || futureInfrastructure === 'construction-proposed'); + map.setGlobalStateProperty('showProposedInfrastructure', futureInfrastructure === 'construction-proposed'); } function updateBackgroundMapContainer() { @@ -753,6 +760,15 @@ function rewriteStylePathsToOrigin(style) { function rewriteGlobalStateDefaults(style) { style.state.date.default = selectedDate; style.state.theme.default = selectedTheme; + + const historicalInfrastructure = configuration.historicalInfrastructure ?? defaultConfiguration.historicalInfrastructure + style.state.openHistoricalMap.default = historicalInfrastructure === 'openhistoricalmap'; + style.state.showAbandonedInfrastructure.default = historicalInfrastructure === 'openstreetmap'; + style.state.showRazedInfrastructure.default = historicalInfrastructure === 'openstreetmap'; + + const futureInfrastructure = configuration.futureInfrastructure ?? defaultConfiguration.futureInfrastructure; + style.state.showConstructionInfrastructure.default = futureInfrastructure === 'construction' || futureInfrastructure === 'construction-proposed'; + style.state.showProposedInfrastructure.default = futureInfrastructure === 'construction-proposed'; } let lastSetMapStyle = null; From a5c8f06e18214147431d93d58bd7050e63de24f4 Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sun, 5 Oct 2025 20:43:40 +0200 Subject: [PATCH 14/19] hide date picker if openhistoricalmap is disabled in configuration --- proxy/js/ui.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/proxy/js/ui.js b/proxy/js/ui.js index 440eb578..8ef3caf7 100644 --- a/proxy/js/ui.js +++ b/proxy/js/ui.js @@ -628,6 +628,8 @@ function onHistoricalInfrastructureChange(historicalInfrastructure) { map.setGlobalStateProperty('openHistoricalMap', historicalInfrastructure === 'openhistoricalmap'); map.setGlobalStateProperty('showAbandonedInfrastructure', historicalInfrastructure === 'openstreetmap'); map.setGlobalStateProperty('showRazedInfrastructure', historicalInfrastructure === 'openstreetmap'); + + onStyleChange(); } function onFutureInfrastructureChange(futureInfrastructure) { @@ -773,7 +775,8 @@ function rewriteGlobalStateDefaults(style) { let lastSetMapStyle = null; const onStyleChange = () => { - const supportsDate = knownStyles[selectedStyle].styles.date; + const historicalInfrastructure = configuration.historicalInfrastructure ?? defaultConfiguration.historicalInfrastructure + const supportsDate = knownStyles[selectedStyle].styles.date && historicalInfrastructure === 'openhistoricalmap'; const dateActive = supportsDate && dateControl.active; const mapStyle = dateActive ? knownStyles[selectedStyle].styles.date From 4e1aafa59d1ad4e6694ed8b200a238e2c0defb6e Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sun, 5 Oct 2025 21:05:50 +0200 Subject: [PATCH 15/19] filter stations for their state --- proxy/js/styles.mjs | 68 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/proxy/js/styles.mjs b/proxy/js/styles.mjs index 7973d195..35171707 100644 --- a/proxy/js/styles.mjs +++ b/proxy/js/styles.mjs @@ -1657,6 +1657,12 @@ const layers = { minzoom: 13, source: 'openrailwaymap_standard', 'source-layer': 'standard_railway_grouped_stations', + filter: ['match', ['get', 'state'], + 'construction', ['global-state', 'showConstructionInfrastructure'], + 'proposed', ['global-state', 'showProposedInfrastructure'], + 'abandoned', ['global-state', 'showAbandonedInfrastructure'], + true, + ], paint: { 'fill-color': ['case', ['in', ['get', 'state'], ['literal', ['disused', 'abandoned', 'preserved']]], colors.styles.standard.past, @@ -1740,7 +1746,12 @@ const layers = { minzoom: 13, source: 'openrailwaymap_standard', 'source-layer': 'standard_railway_grouped_stations', - filter: ['==', ['get', 'state'], state], + filter: ['all', + state === 'construction' ? ['global-state', 'showConstructionInfrastructure'] : true, + state === 'proposed' ? ['global-state', 'showProposedInfrastructure'] : true, + state === 'abandoned' ? ['global-state', 'showAbandonedInfrastructure'] : true, + ['==', ['get', 'state'], state], + ].filter(it => it !== true), paint: { 'line-color': ['case', // Use outline color of feature, without taking state into account @@ -2390,7 +2401,15 @@ const layers = { minzoom: 16, source: 'high', 'source-layer': 'railway_line_high', - filter: ['!=', ['get', 'track_ref'], null], + filter: ['all', + ['!=', ['get', 'track_ref'], null], + ['match', ['get', 'state'], + 'construction', ['global-state', 'showConstructionInfrastructure'], + 'proposed', ['global-state', 'showProposedInfrastructure'], + 'abandoned', ['global-state', 'showAbandonedInfrastructure'], + true, + ], + ], paint: { 'text-color': ['case', ['boolean', ['feature-state', 'hover'], false], colors.styles.standard.track.hover, @@ -2509,15 +2528,35 @@ const layers = { ], 10, ['all', + ['match', ['get', 'state'], + 'construction', ['global-state', 'showConstructionInfrastructure'], + 'proposed', ['global-state', 'showProposedInfrastructure'], + 'disused', false, + 'abandoned', false, + true, + ], ['!=', ['get', 'station'], 'tram'], ['!=', ['get', 'station'], 'funicular'], ['!=', ['get', 'station'], 'miniature'], ], 11, ['all', + ['match', ['get', 'state'], + 'construction', ['global-state', 'showConstructionInfrastructure'], + 'proposed', ['global-state', 'showProposedInfrastructure'], + 'abandoned', false, + true, + ], ['!=', ['get', 'station'], 'funicular'], ['!=', ['get', 'station'], 'miniature'], ], + 12, + ['match', ['get', 'state'], + 'construction', ['global-state', 'showConstructionInfrastructure'], + 'proposed', ['global-state', 'showProposedInfrastructure'], + 'abandoned', ['global-state', 'showAbandonedInfrastructure'], + true, + ], ], paint: { 'text-color': ['case', @@ -2530,6 +2569,8 @@ const layers = { ['==', ['get', 'station'], 'light_rail'], colors.styles.standard.lightRailText, ['==', ['get', 'station'], 'monorail'], colors.styles.standard.monorailText, ['==', ['get', 'station'], 'tram'], colors.styles.standard.tramStopText, + ['==', ['get', 'station'], 'miniature'], colors.styles.standard.miniatureText, + ['==', ['get', 'station'], 'funicular'], colors.styles.standard.funicularText, colors.styles.standard.stationsText, ], colors.styles.standard.defaultText, @@ -2549,6 +2590,8 @@ const layers = { ['==', ['get', 'station'], 'light_rail'], colors.styles.standard.lightRailText, ['==', ['get', 'station'], 'monorail'], colors.styles.standard.monorailText, ['==', ['get', 'station'], 'tram'], colors.styles.standard.tramStopText, + ['==', ['get', 'station'], 'miniature'], colors.styles.standard.miniatureText, + ['==', ['get', 'station'], 'funicular'], colors.styles.standard.funicularText, colors.styles.standard.stationsText, ], colors.styles.standard.defaultText, @@ -2589,6 +2632,12 @@ const layers = { minzoom: 13, source: 'openrailwaymap_standard', 'source-layer': 'standard_railway_text_stations', + filter: ['match', ['get', 'state'], + 'construction', ['global-state', 'showConstructionInfrastructure'], + 'proposed', ['global-state', 'showProposedInfrastructure'], + 'abandoned', ['global-state', 'showAbandonedInfrastructure'], + true, + ], paint: { 'text-color': ['case', ['==', ['get', 'feature'], 'yard'], colors.styles.standard.yardText, @@ -4060,7 +4109,15 @@ const layers = { minzoom: 13, source: 'openrailwaymap_standard', 'source-layer': 'standard_railway_grouped_stations', - filter: ['!=', ['get', 'operator'], null], + filter: ['all', + ['!=', ['get', 'operator'], null], + ['match', ['get', 'state'], + 'construction', ['global-state', 'showConstructionInfrastructure'], + 'proposed', ['global-state', 'showProposedInfrastructure'], + 'abandoned', ['global-state', 'showAbandonedInfrastructure'], + true, + ], + ], paint: { 'fill-color': ['concat', 'hsl(', ['get', 'operator_hash'], ', 100%, 40%)'], 'fill-opacity': ['case', @@ -4083,9 +4140,12 @@ const layers = { source: 'openrailwaymap_standard', 'source-layer': 'standard_railway_grouped_stations', filter: ['all', + state === 'construction' ? ['global-state', 'showConstructionInfrastructure'] : true, + state === 'proposed' ? ['global-state', 'showProposedInfrastructure'] : true, + state === 'abandoned' ? ['global-state', 'showAbandonedInfrastructure'] : true, ['!=', ['get', 'operator'], null], ['==', ['get', 'state'], state], - ], + ].filter(it => it !== true), paint: { 'line-color': ['concat', 'hsl(', ['get', 'operator_hash'], ', 100%, 40%)'], 'line-opacity': 0.3, From 9756ce64b4d6ff4c88de92a8a650c45d630e7956 Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sun, 5 Oct 2025 21:13:29 +0200 Subject: [PATCH 16/19] historical --- proxy/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proxy/index.html b/proxy/index.html index 6c11a300..b390c6df 100644 --- a/proxy/index.html +++ b/proxy/index.html @@ -193,7 +193,7 @@ - Control which future railway infrastructure should be shown on the map.
+ Control how historical railway infrastructure should be shown on the map.
Note: Tagging and non-existing features in OpenStreetMap like demolished railways is discouraged. It is encouraged instead to use the OpenHistoricalMap to create and maintain historical data.
From 2b6c4a4293b0b8d918a7b9e8116146e26a121484 Mon Sep 17 00:00:00 2001 From: Hidde Wieringa Date: Sun, 5 Oct 2025 21:21:24 +0200 Subject: [PATCH 17/19] margin bottom in configuration --- proxy/index.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/proxy/index.html b/proxy/index.html index b390c6df..b91cacc2 100644 --- a/proxy/index.html +++ b/proxy/index.html @@ -103,21 +103,21 @@