diff --git a/.dockerignore b/.dockerignore
index 5367866e..bf237e8f 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -3,6 +3,7 @@
!features
!import/sql
!import/docker-startup.sh
+!import/tags.lua.js
!import/openrailwaymap.lua
!data/import
!martin
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index fc134605..30e12cbc 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -143,6 +143,21 @@ loading_gauges:
Open a pull request where you provide details about the new loading gauge. Ensure the pull request contains references to documentation and places on the map where the loading gauge exists.
+## I want to visualize a new track class on the map
+
+Edit the file [`features/track_class.yaml`](https://github.com/hiddewie/OpenRailwayMap-vector/edit/master/features/track_class.yaml).
+
+The file contains a list of track classes, each with a value (the value of the `railway:track_class` tag) and a color.
+
+Add a new entry at a certain place in the list. The value is the `railway:track_class` tag value. For example:
+```yaml
+track_classes:
+ - { value: 'Z', color: 'blue' }
+ # ...
+```
+
+Open a pull request where you provide details about the new track class. Ensure the pull request contains references to documentation and places on the map where the track class exists.
+
## I want to improve the user interface
The HTML, Javascript and CSS of the user interface are located in the [proxy](https://github.com/hiddewie/OpenRailwayMap-vector/tree/master/proxy) directory.
diff --git a/SETUP.md b/SETUP.md
index 15e2830d..11ed02a8 100644
--- a/SETUP.md
+++ b/SETUP.md
@@ -89,3 +89,24 @@ Run tests against the tiles:
```shell
hurl --test --verbose --variable base_url=http://localhost:3000 tiles/test/tiles.hurl
```
+
+## Development
+
+### Code generation
+
+The YAML files in the `features` directory are templated into SQL and Lua code.
+
+You can view the generated files:
+```shell
+docker build --target build-signals --tag build-signals --file import/Dockerfile . \
+ && docker run --rm --entrypoint cat build-signals /build/signals_with_azimuth.sql | less
+
+docker build --target build-lua --tag build-lua --file import/Dockerfile . \
+ && docker run --rm --entrypoint cat build-lua /build/tags.lua | less
+
+docker build --target build-styles --tag build-styles --file proxy.Dockerfile . \
+ && docker run --rm --entrypoint ls build-styles
+
+docker build --target build-styles --tag build-styles --file proxy.Dockerfile . \
+ && docker run --rm --entrypoint cat build-styles standard.json | jq . | less
+```
diff --git a/docker-compose.yml b/docker-compose.yml
index 493eda01..abf8fb05 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -88,8 +88,6 @@ services:
depends_on:
db:
condition: service_healthy
- volumes:
- - ./martin:/config
environment:
- DATABASE_URL=postgresql://postgres@db:5432/gis
ulimits:
@@ -97,6 +95,12 @@ services:
nofile:
soft: 26677
hard: 46677
+ develop:
+ watch:
+ - action: rebuild
+ path: martin
+ - action: rebuild
+ path: symbols
martin-static:
build:
diff --git a/features/electrification_signals.yaml b/features/electrification_signals.yaml
index e4e2b20e..d40716c6 100644
--- a/features/electrification_signals.yaml
+++ b/features/electrification_signals.yaml
@@ -6,6 +6,7 @@ electrification_signals:
- 'railway:signal:electricity:form'
- 'railway:signal:electricity:for'
- 'railway:signal:electricity:turn_direction'
+ - 'railway:signal:electricity:voltage'
features:
@@ -25,7 +26,7 @@ electrification_signals:
tags:
- { tag: 'railway:signal:electricity', value: 'AT-V2:ankündigung_hauptschalter_aus' }
- { tag: 'railway:signal:electricity:type', value: 'power_off_advance' }
- - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:form', values: ['sign', 'light'] }
- description: Halt für Fahrzeuge mit angehobenem Stromabnehmer
country: AT
@@ -39,7 +40,7 @@ electrification_signals:
tags:
- { tag: 'railway:signal:electricity', value: 'AT-V2:halt_fuer_fahrzeuge_mit_angehobenem_stromabnehmer' }
- { tag: 'railway:signal:electricity:type', value: 'end_of_catenary' }
- - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:form', values: ['sign', 'light', 'semaphore'] }
- description: Hauptschalter ein
country: AT
@@ -63,7 +64,7 @@ electrification_signals:
tags:
- { tag: 'railway:signal:electricity', value: 'AT-V2:hauptschalter_aus' }
- { tag: 'railway:signal:electricity:type', value: 'power_off' }
- - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:form', values: ['sign', 'light'] }
- description: Stromabnehmer tief
country: AT
@@ -97,6 +98,179 @@ electrification_signals:
- { tag: 'railway:signal:electricity:type', value: 'power_indicator' }
- { tag: 'railway:signal:electricity:form', value: 'semaphore' }
+ # --- BE --- #
+
+ - description: Panto distant
+ country: BE
+ icon: { default: 'be/PBA' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'BE:PBA' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'pantograph_down_advance' }
+
+ - description: Panto down
+ country: BE
+ icon: { default: 'be/PBE' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'BE:PBE' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'pantograph_down' }
+
+ - description: Panto up
+ country: BE
+ icon: { default: 'be/PRL' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'BE:PRL' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'pantograph_up' }
+
+ # --- CH --- #
+
+ - description: Vorsignal zum Senksignal
+ country: CH
+ icon: { default: 'ch/fdv-703' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'CH-FDV:703' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'pantograph_down_advance' }
+
+ - description: Senksignal
+ country: CH
+ icon: { default: 'ch/fdv-704' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'CH-FDV:704' }
+ - { tag: 'railway:signal:electricity:form', values: ['sign', 'semaphore'] }
+ - { tag: 'railway:signal:electricity:type', value: 'pantograph_down' }
+
+ - description: Endsignal zum Senksignal
+ country: CH
+ icon: { default: 'ch/fdv-705' }
+ tags:
+ - { tag: 'railway:signal:electricity', values: ['CH-FDV:705', 'CH-FDV:706'] }
+ - { tag: 'railway:signal:electricity:form', values: ['sign', 'light'] }
+ - { tag: 'railway:signal:electricity:type', value: 'pantograph_up' }
+
+ - description: Aufhebungssignal zum Senksignal
+ country: CH
+ icon: { default: 'ch/fdv-707' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'CH-FDV:707' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'pantograph_up' }
+
+ - description: Vorsignal zum Ausschaltsignal (sign)
+ country: CH
+ icon: { default: 'ch/fdv-708' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'CH-FDV:708' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_off_advance' }
+
+ - description: Vorsignal zum Ausschaltsignal (light)
+ country: CH
+ icon: { default: 'ch/fdv-709' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'CH-FDV:709' }
+ - { tag: 'railway:signal:electricity:form', value: 'light' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_off_advance' }
+
+ - description: Ausschaltsignal (sign)
+ country: CH
+ icon: { default: 'ch/fdv-710' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'CH-FDV:710' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_off' }
+
+ - description: Ausschaltsignal (light)
+ country: CH
+ icon: { default: 'ch/fdv-711' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'CH-FDV:711' }
+ - { tag: 'railway:signal:electricity:form', value: 'light' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_off' }
+
+ - description: Einschaltsignal (sign)
+ country: CH
+ icon: { default: 'ch/fdv-712' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'CH-FDV:712' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_off' }
+
+ - description: Einschaltsignal (light)
+ country: CH
+ icon: { default: 'ch/fdv-713' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'CH-FDV:713' }
+ - { tag: 'railway:signal:electricity:form', value: 'light' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_off' }
+
+ - description: Streckentrennung
+ country: CH
+ icon: { default: 'ch/fdv-714' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'CH-FDV:714' }
+ - { tag: 'railway:signal:electricity:form', values: ['sign', 'light'] }
+ - { tag: 'railway:signal:electricity:type', value: 'joint' } # TODO why joint?
+
+ - description: Zonen-Schutzstreckensignal
+ country: CH
+ icon: { default: 'ch/fdv-715' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'CH-FDV:715' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'main_switch_off' }
+
+ - description: Zonensignal
+ country: CH
+ # TODO support voltage values
+ icon: { default: 'ch/fdv-716' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'CH-FDV:716' }
+ - { tag: 'railway:signal:electricity:form', value: 'light' }
+ - { tag: 'railway:signal:electricity:type', value: 'system_changeable' }
+
+ - description: Vorsignal zum Umschaltsignal
+ country: CH
+ icon: { default: 'ch/fdv-719' }
+ tags:
+ - { tag: 'railway:signal:electricity', values: ['CH-FDV:719', 'CH-SBB:719'] }
+ - { tag: 'railway:signal:electricity:form', value: 'light' }
+ - { tag: 'railway:signal:electricity:type', value: 'system_change_advance' }
+
+ - description: Umschaltsignal anfang (sign)
+ country: CH
+ icon: { default: 'ch/fdv-717' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'CH-FDV:717' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'system_change_start' }
+
+ - description: Umschaltsignal anfang (light)
+ country: CH
+ icon: { default: 'ch/fdv-717.1' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'CH-FDV:717.1' }
+ - { tag: 'railway:signal:electricity:form', value: 'light' }
+ - { tag: 'railway:signal:electricity:type', value: 'system_change_start' }
+
+ - description: Umschaltsignal ende (sign)
+ country: CH
+ icon: { default: 'ch/fdv-718' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'CH-FDV:718' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'system_change_end' }
+
+ - description: Umschaltsignal ende (light)
+ country: CH
+ icon: { default: 'ch/fdv-718.1' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'CH-FDV:718.1' }
+ - { tag: 'railway:signal:electricity:form', value: 'light' }
+ - { tag: 'railway:signal:electricity:type', value: 'system_change_end' }
+
# --- DE --- #
- description: pantograph down advance El 3
@@ -135,7 +309,7 @@ electrification_signals:
tags:
- { tag: 'railway:signal:electricity:type', value: 'power_on' }
- { tag: 'railway:signal:electricity:form', value: 'sign' }
- - { tag: 'railway:signal:electricity', value: 'DE-ESO:el2' }
+ - { tag: 'railway:signal:electricity', values: ['DE-ESO:el2', 'DE-BOStrab:st4', 'DE-HHA:s2'] }
- description: pantograph up El 5
country: DE
@@ -143,7 +317,7 @@ electrification_signals:
tags:
- { tag: 'railway:signal:electricity:type', value: 'pantograph_up' }
- { tag: 'railway:signal:electricity:form', value: 'sign' }
- - { tag: 'railway:signal:electricity', value: 'DE-ESO:el5' }
+ - { tag: 'railway:signal:electricity', values: ['DE-ESO:el5', 'DE-BOStrab:st6'] }
- description: power off sign El 1
country: DE
@@ -151,7 +325,7 @@ electrification_signals:
tags:
- { tag: 'railway:signal:electricity:type', value: 'power_off' }
- { tag: 'railway:signal:electricity:form', value: 'sign' }
- - { tag: 'railway:signal:electricity', value: 'DE-ESO:el1' }
+ - { tag: 'railway:signal:electricity', values: ['DE-ESO:el1', 'DE-BOStrab:st3', 'DE-HHA:s1'] }
- description: pantograph down El 4
country: DE
@@ -159,7 +333,7 @@ electrification_signals:
tags:
- { tag: 'railway:signal:electricity:type', value: 'pantograph_down' }
- { tag: 'railway:signal:electricity:form', value: 'sign' }
- - { tag: 'railway:signal:electricity', value: 'DE-ESO:el4' }
+ - { tag: 'railway:signal:electricity', values: ['DE-ESO:el4', 'DE-BOStrab:st5'] }
- description: tram power off shortly signal (St 7)
country: DE
@@ -169,6 +343,142 @@ electrification_signals:
- { tag: 'railway:signal:electricity:form', value: 'sign' }
- { tag: 'railway:signal:electricity', values: ['DE-BOStrab:st7', 'DE-AVG:st7'] }
+ - description: power off shortly
+ country: DE
+ icon: { default: 'de/el1-el2' }
+ tags:
+ - { tag: 'railway:signal:electricity:type', value: 'power_off_shortly' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity', values: ['DE-ESO:el1;DE-ESO:el2', 'DE-ESO:el2:DE-ESO:el1'] }
+
+ - description: tram sign power off shortly El 1
+ country: DE
+ icon: { default: 'de/el1' }
+ tags:
+ - { tag: 'railway:signal:electricity:type', value: 'power_off_shortly' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity', value: 'DE-AVG:el1' }
+
+ - description: Streckentrennung (anfang)
+ country: DE
+ icon: { default: 'de/streckentrennung-anfang' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'DE-ESO:streckentrennung' }
+ - { tag: 'railway:signal:electricity:type', value: 'begin_of_isolated_overlap' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+
+ - description: Streckentrennung (ende)
+ country: DE
+ icon: { default: 'de/streckentrennung-ende' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'DE-ESO:streckentrennung' }
+ - { tag: 'railway:signal:electricity:type', value: 'end_of_isolated_overlap' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+
+ - description: ICE-Schaltmerkhilfe
+ country: DE
+ icon: { default: 'de/ice-schaltmerkhilfe' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'DE-ESO:ice-schaltmerkhilfe' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_on_for_long_trains' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+
+ - description: VGF st9
+ country: DE
+ icon: { default: 'de/vgf/st9' }
+ tags:
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity', value: 'DE-VGF:st9' }
+
+ - description: VGF st10
+ country: DE
+ icon: { default: 'de/vgf/st10' }
+ tags:
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity', value: 'DE-VGF:st10' }
+
+ - description: VGF st9 & st10
+ country: DE
+ icon: { default: 'de/vgf/st9-st10' }
+ tags:
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity', value: 'DE-VGF:st9;DE-VGF:st10' }
+
+ # --- ES --- #
+
+ - description: end of catenary
+ country: ES
+ # TODO add turn direction
+ icon: { default: 'es/FI14A' }
+ tags:
+ - { tag: 'railway:signal:electricity', values: ['ES:FI14A', 'ES:FI14B'] }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'end_of_catenaxy' }
+
+ - description: power off shortly
+ country: ES
+ icon: { default: 'es/FI14C' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'ES:FI14C' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_off_shortly' }
+
+ - description: power off shortly (full)
+ country: ES
+ icon: { default: 'es/FI14D' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'ES:FI14D' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_off_shortly' }
+
+ - description: pantograph down
+ country: ES
+ icon: { default: 'es/FI14E' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'ES:FI14E' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'pantograph_down' }
+
+ - description: pantograph up
+ country: ES
+ icon: { default: 'es/FI14F' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'ES:FI14F' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'pantograph_up' }
+
+ - description: pantograph down announcement
+ country: ES
+ icon: { default: 'es/FI14G' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'ES:FI14G' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'pantograph_down_advance' }
+
+ - description: power off announcement
+ country: ES
+ icon: { default: 'es/FI14H' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'ES:FI14H' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_off_advance' }
+
+ - description: power off
+ country: ES
+ icon: { default: 'es/FI14I' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'ES:FI14I' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_off' }
+
+ - description: power on
+ country: ES
+ icon: { default: 'es/FI14J' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'ES:FI14J' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_on' }
+
# --- FI --- #
- description: Erotusjakson etumerkki
@@ -220,11 +530,232 @@ electrification_signals:
- { tag: 'railway:signal:electricity', value: 'FI:T-125' }
- { tag: 'railway:signal:electricity:form', value: 'sign' }
+ # --- FR --- #
+
+ - description: Neutral Zone Announcement
+ country: FR
+ icon: { default: 'fr/SECT' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'FR:SECT' }
+ - { tag: 'railway:signal:electricity:form', values: ['sign', 'light'] }
+ - { tag: 'railway:signal:electricity:type', value: 'power_off_advance' }
+
+ - description: Start of Neutral Zone
+ country: FR
+ icon: { default: 'fr/CC_EXE' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'FR:CC_EXE' }
+ - { tag: 'railway:signal:electricity:form', values: ['sign', 'light'] }
+ - { tag: 'railway:signal:electricity:type', value: 'power_off' }
+
+ - description: End of Neutral Zone
+ country: FR
+ icon: { default: 'fr/CC_FIN' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'FR:CC_FIN' }
+ - { tag: 'railway:signal:electricity:form', values: ['sign', 'light'] }
+ - { tag: 'railway:signal:electricity:type', value: 'power_on' }
+
+ - description: End of Neutral Zone (reversible trains)
+ country: FR
+ icon: { default: 'fr/REV' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'FR:REV' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_on' }
+
+ - description: Pantograph Down Announcement
+ country: FR
+ icon: { default: 'fr/BP_DIS' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'FR:BP_DIS' }
+ - { tag: 'railway:signal:electricity:form', values: ['sign', 'light'] }
+ - { tag: 'railway:signal:electricity:type', value: 'pantograph_down_advance' }
+
+ - description: Start of Pantograph Down
+ country: FR
+ icon: { default: 'fr/BP_EXE' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'FR:BP_EXE' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'pantograph_down' }
+
+ - description: End of Pantograph Down
+ country: FR
+ icon: { default: 'fr/BP_FIN' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'FR:BP_FIN' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'pantograph_up' }
+
+ - description: Dual-Mode Traffic
+ country: FR
+ icon: { default: 'fr/BIMODE' }
+ tags:
+ - { tag: 'railway:signal:electricity', values: ['FR:BIMODE', 'FR:BIMODE_A'] }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+
+ - description: End of Catenaries
+ country: FR
+ icon: { default: 'fr/FIN_CAT' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'FR:FIN_CAT' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'end_of_catenary' }
+
+ - description: Stop Markers
+ country: FR
+ icon: { default: 'fr/JALON_ARRET' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'FR:JALON_ARRET' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+
+ - description: Frost Board
+ country: FR
+ icon: { default: 'fr/GIVRE' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'FR:GIVRE' }
+ - { tag: 'railway:signal:electricity:form', values: ['sign', 'light'] }
+
+ # --- LU --- #
+
+ - description: ESFA
+ country: LU
+ icon: { default: 'lu/ESFA' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'LU-CFL:ESFA' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'end_of_catenary' }
+
+ - description: ESFAp/TA
+ country: LU
+ icon: { default: 'lu/ESFAp_TA' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'LU-CFL:ESFAp/TA' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'pantograph_down_advance' }
+
+ - description: ESFAp/TE
+ country: LU
+ icon: { default: 'lu/ESFAp_TE' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'LU-CFL:ESFAp/TE' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'pantograph_down' }
+
+ - description: ESFAp/TR
+ country: LU
+ icon: { default: 'lu/ESFAp_TR' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'LU-CFL:ESFAp/TR' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'pantograph_up' }
+
+ - description: ESFCC/A
+ country: LU
+ icon: { default: 'lu/ESFCC_A' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'LU-CFL:ESFCC/A' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_off_advance' }
+
+ - description: ESFCC/E
+ country: LU
+ icon: { default: 'lu/ESFCC_E' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'LU-CFL:ESFCC/E' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_off' }
+
+ - description: ESFCC/F
+ country: LU
+ icon: { default: 'lu/ESFCC_F' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'LU-CFL:ESFCC/F' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_on' }
+
+ # --- NL --- #
+
+ - description: power off
+ country: NL
+ icon: { default: 'nl/306a' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'NL:306a' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_off' }
+
+ # TODO support carriages
+ - description: power on
+ country: NL
+ icon: { default: 'nl/307a' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'NL:307a' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_on' }
+
+ - description: announcement pantograph down
+ country: NL
+ icon: { default: 'nl/307a' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'NL:308a' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'pantograph_down_advance' }
+
+ # TODO support wash
+ - description: pantograph down
+ country: NL
+ icon: { default: 'nl/309a' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'NL:309a' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'pantograph_down' }
+
+ # TODO support carriages
+ - description: pantograph up
+ country: NL
+ icon: { default: 'nl/310a' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'NL:310a' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'pantograph_up' }
+
+ - description: end of catenary
+ country: NL
+ icon:
+ match: 'railway:signal:electricity:turn_direction'
+ cases:
+ - { regex: '^right$', value: 'nl/311-right' }
+ - { regex: '^left$', value: 'nl/311-left' }
+ default: 'nl/311'
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'NL:311' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'end_of_catenary' }
+
+ - description: voltage change
+ country: NL
+ icon:
+ match: 'railway:signal:electricity:voltage'
+ cases:
+ - { regex: '^1500$', value: 'nl/320-1500' }
+ - { regex: '^25000$', value: 'nl/320-25000' }
+ default: 'nl/320-unknown'
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'NL:320' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'voltage_change' }
+
# --- PL --- #
- description: Wskaźnik uprzedzający o opuszczeniu pantografu (we1)
country: PL
- icon: { default: 'pl/we1' }
+ icon:
+ match: 'railway:signal:electricity:turn_direction'
+ cases:
+ - { regex: '^right$', value: 'pl/we1b' }
+ - { regex: '^left$', value: 'pl/we1c' }
+ default: 'pl/we1a'
tags:
- { tag: 'railway:signal:electricity', value: 'PL-PKP:we1' }
- { tag: 'railway:signal:electricity:form', value: 'sign' }
@@ -251,7 +782,7 @@ electrification_signals:
- { regex: '^locomotive$', value: 'pl/we3b' }
default: 'pl/we3a'
tags:
- - { tag: 'railway:signal:electricity', values: ['PL-PKP:we3a', 'PL-PKP:we3b'] }
+ - { tag: 'railway:signal:electricity', values: ['PL-PKP:we3a', 'PL-PKP:we3b', 'PL-PKP:we3c'] }
- { tag: 'railway:signal:electricity:form', value: 'sign' }
- { tag: 'railway:signal:electricity:type', value: 'pantograph_up' }
@@ -289,6 +820,70 @@ electrification_signals:
- { regex: '^locomotive$', value: 'pl/we9b' }
default: 'pl/we9a'
tags:
- - { tag: 'railway:signal:electricity', values: ['PL-PKP:we9a', 'PL-PKP:we9b'] }
+ - { tag: 'railway:signal:electricity', values: ['PL-PKP:we9a', 'PL-PKP:we9b', 'PL-PKP:we9c'] }
- { tag: 'railway:signal:electricity:form', value: 'sign' }
- { tag: 'railway:signal:electricity:type', value: 'power_on' }
+
+ - description: Wskaźniki zmiany systemu zasilania 25 kV
+ country: PL
+ icon: { default: 'pl/we10a' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'PL-PKP:we10a' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_change' }
+
+ - description: Wskaźniki zmiany systemu zasilania 25 kV
+ country: PL
+ icon: { default: 'pl/we10b' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'PL-PKP:we10b' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_change' }
+
+ - description: Wskaźniki zmiany systemu zasilania 15 kV
+ country: PL
+ icon: { default: 'pl/we10c' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'PL-PKP:we10c' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_change' }
+
+ - description: Wskaźniki zmiany systemu zasilania 15 kV
+ country: PL
+ icon: { default: 'pl/we10d' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'PL-PKP:we10d' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_change' }
+
+ - description: Wskaźniki zmiany systemu zasilania 3 kV
+ country: PL
+ icon: { default: 'pl/we10e' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'PL-PKP:we10e' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_change' }
+
+ - description: Wskaźniki zmiany systemu zasilania 3 kV
+ country: PL
+ icon: { default: 'pl/we10f' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'PL-PKP:we10f' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_change' }
+
+ - description: Tram isolation (ct-1)
+ country: PL
+ icon: { default: 'pl/ct-1' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'PL-tram:ct-1' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'isolation' }
+
+ - description: Tram power limit (ct-2)
+ country: PL
+ icon: { default: 'pl/ct-2' }
+ tags:
+ - { tag: 'railway:signal:electricity', value: 'PL-tram:ct-2' }
+ - { tag: 'railway:signal:electricity:form', value: 'sign' }
+ - { tag: 'railway:signal:electricity:type', value: 'power_limit' }
diff --git a/features/signals_railway_signals.yaml b/features/signals_railway_signals.yaml
index 5bcc2816..3c16e46d 100644
--- a/features/signals_railway_signals.yaml
+++ b/features/signals_railway_signals.yaml
@@ -72,6 +72,7 @@ signals_railway_signals:
- 'railway:signal:steam_locomotive'
- 'railway:signal:steam_locomotive:form'
- 'railway:signal:stop:form'
+ - 'railway:signal:stop:carriages'
- 'railway:signal:stop_demand'
- 'railway:signal:stop_demand:form'
- 'railway:signal:train_protection'
@@ -84,6 +85,7 @@ signals_railway_signals:
- 'railway:signal:wrong_road'
- 'railway:signal:wrong_road:form'
- 'railway:vacancy_detection'
+ - 'railway:signal:position'
features:
@@ -1231,36 +1233,6 @@ signals_railway_signals:
- { tag: 'railway:signal:main_repeated', value: 'NL' }
- { tag: 'railway:signal:main_repeated:form', value: 'light' }
- - description: H signal
- country: NL
- icon: { default: 'nl/H' }
- tags:
- - { tag: 'railway:signal:speed_limit', value: 'NL' }
- - { tag: 'railway:signal:speed_limit:form', value: 'light' }
- - { tag: 'railway:signal:speed_limit:states', value: 'H;off' }
-
- - description: L signal
- country: NL
- icon: { default: 'nl/L' }
- tags:
- - { tag: 'railway:signal:speed_limit', value: 'NL' }
- - { tag: 'railway:signal:speed_limit:form', value: 'light' }
- - { tag: 'railway:signal:speed_limit:states', value: 'L;off' }
-
- - description: main signal with speed limit
- country: NL
- icon: { default: 'nl/main_light_speed_limit' }
- tags:
- - { tag: 'railway:signal:main', value: 'NL' }
- - { tag: 'railway:signal:speed_limit:form', value: 'light' }
-
- - description: distant signal with speed limit
- country: NL
- icon: { default: 'nl/distant_light_speed_limit' }
- tags:
- - { tag: 'railway:signal:distant', value: 'NL' }
- - { tag: 'railway:signal:speed_limit:form', value: 'light' }
-
- description: main light
country: NL
icon: { default: 'nl/main_light' }
@@ -1275,28 +1247,29 @@ signals_railway_signals:
- { tag: 'railway:signal:distant', value: 'NL' }
- { tag: 'railway:signal:distant:form', value: 'light' }
- - description: speed limit only
+ - description: middenvoetbrugsein
country: NL
- icon: { default: 'nl/speed_limit_light' }
+ icon: { default: 'nl/215b' }
tags:
- - { tag: 'railway:signal:speed_limit', value: 'NL' }
- - { tag: 'railway:signal:speed_limit:form', value: 'light' }
+ - { tag: 'railway:signal:minor', value: 'NL:middenvoetbrugsein' }
+ - { tag: 'railway:signal:minor:form', value: 'light' }
- description: Humping ("heuvelen")
country: NL
icon: { default: 'nl/270a' }
tags:
- { tag: 'railway:signal:humping', value: 'NL:270' }
-
- - description: ATB codewissel
- country: NL
- icon: { default: 'nl/atb-codewissel' }
- tags:
- - { tag: 'railway:signal:train_protection', value: 'NL:330' }
+ - { tag: 'railway:signal:humping:form', value: 'light' }
- description: train protection block markers (arrow)
country: NL
- icon: { default: 'general/etcs-stop-marker-arrow-left' }
+ icon:
+ # TODO, support lights (227a / 227c)
+ match: 'railway:signal:position'
+ cases:
+ - { regex: '^left$', value: 'general/etcs-stop-marker-arrow-right' }
+ - { regex: '^overhead$', value: 'general/etcs-stop-marker-arrow-down' }
+ default: 'general/etcs-stop-marker-arrow-left'
tags:
- { tag: 'railway:signal:train_protection', value: 'NL:227b' }
- { tag: 'railway:signal:train_protection:form', value: 'sign' }
@@ -1305,12 +1278,131 @@ signals_railway_signals:
- description: train protection block markers (triangle)
country: NL
- icon: { default: 'general/etcs-stop-marker-triangle-left' }
+ icon:
+ # TODO, support lights (227a / 227c)
+ match: 'railway:signal:position'
+ cases:
+ - { regex: '^left$', value: 'general/etcs-stop-marker-triangle-right' }
+ - { regex: '^overhead$', value: 'general/etcs-stop-marker-triangle-down' }
+ default: 'general/etcs-stop-marker-triangle-left'
tags:
- { tag: 'railway:signal:train_protection', values: ['NL:227b', 'DE-ESO:ne14'] }
- { tag: 'railway:signal:train_protection:form', value: 'sign' }
- { tag: 'railway:signal:train_protection:type', value: 'block_marker' }
+ - description: stopplaatssein
+ country: NL
+ icon: { default: 'nl/303' }
+ tags:
+ - { tag: 'railway:signal:stop', values: ['NL:303', 'NL:stopplaatssein'] }
+ - { tag: 'railway:signal:stop:form', value: 'light' }
+
+ - description: treinlengtebord
+ country: NL
+ # TODO implement partial platform train length values (railway:signal:stop:carriages_partial_platform=*)
+ icon:
+ match: 'railway:signal:stop:carriages'
+ cases:
+ # Free match to allow matching multiple values on a single sign, separated by ;
+ - { regex: '18', value: 'nl/304-18' }
+ - { regex: '16', value: 'nl/304-16' }
+ - { regex: '15', value: 'nl/304-15' }
+ - { regex: '14', value: 'nl/304-14' }
+ - { regex: '13', value: 'nl/304-13' }
+ - { regex: '12', value: 'nl/304-12' }
+ - { regex: '11', value: 'nl/304-11' }
+ - { regex: '10', value: 'nl/304-10' }
+ - { regex: '9', value: 'nl/304-9' }
+ - { regex: '8', value: 'nl/304-8' }
+ - { regex: '7', value: 'nl/304-7' }
+ - { regex: '6', value: 'nl/304-6' }
+ - { regex: '5', value: 'nl/304-5' }
+ - { regex: '4', value: 'nl/304-4' }
+ - { regex: '3', value: 'nl/304-3' }
+ - { regex: '2', value: 'nl/304-2' }
+ default: 'nl/304-empty'
+ tags:
+ - { tag: 'railway:signal:stop', value: 'NL:304' }
+ - { tag: 'railway:signal:stop:form', value: 'sign' }
+
+ - description: distant crossing
+ country: NL
+ # TODO process caption / distant crossing position
+ icon: { default: 'nl/318a' }
+ tags:
+ - { tag: 'railway:signal:crossing_distant', values: ['NL:318a', 'NL:318b'] }
+ - { tag: 'railway:signal:crossing_distant:form', value: 'sign' }
+
+ - description: drive on sight
+ country: NL
+ icon: { default: 'nl/317' }
+ tags:
+ - { tag: 'railway:signal:train_protection', value: 'NL:317' }
+ - { tag: 'railway:signal:train_protection:form', value: 'sign' }
+
+ - description: station
+ country: NL
+ icon: { default: 'nl/305' }
+ tags:
+ - { tag: 'railway:signal:station_distant', value: 'NL:305' }
+ - { tag: 'railway:signal:station_distant:form', value: 'sign' }
+
+ - description: ETCS cab signalling (start)
+ country: NL
+ icon: { default: 'nl/336' }
+ tags:
+ - { tag: 'railway:signal:train_protection', value: 'NL:336' }
+ - { tag: 'railway:signal:train_protection:form', value: 'sign' }
+
+ - description: ETCS cab signalling (end)
+ country: NL
+ icon: { default: 'nl/337' }
+ tags:
+ - { tag: 'railway:signal:train_protection', value: 'NL:337' }
+ - { tag: 'railway:signal:train_protection:form', value: 'sign' }
+
+ - description: ATB distant
+ country: NL
+ icon: { default: 'nl/328a' }
+ tags:
+ - { tag: 'railway:signal:train_protection', value: 'NL:328a' }
+ - { tag: 'railway:signal:train_protection:form', value: 'sign' }
+
+ - description: ATB start
+ country: NL
+ icon: { default: 'nl/328' }
+ tags:
+ - { tag: 'railway:signal:train_protection', value: 'NL:328' }
+ - { tag: 'railway:signal:train_protection:form', value: 'sign' }
+
+ - description: ATB code
+ country: NL
+ icon: { default: 'nl/328b' }
+ tags:
+ - { tag: 'railway:signal:train_protection', value: 'NL:328b' }
+ - { tag: 'railway:signal:train_protection:form', value: 'sign' }
+
+ - description: ATB end
+ country: NL
+ icon: { default: 'nl/329' }
+ tags:
+ - { tag: 'railway:signal:train_protection', value: 'NL:329' }
+ - { tag: 'railway:signal:train_protection:form', value: 'sign' }
+
+ - description: ATB codewissel
+ country: NL
+ icon: { default: 'nl/330' }
+ tags:
+ - { tag: 'railway:signal:train_protection', value: 'NL:330' }
+ - { tag: 'railway:signal:train_protection:form', value: 'light' }
+
+ - description: Einde beveiligd gebied
+ country: NL
+ icon: { default: 'nl/333' }
+ tags:
+ - { tag: 'railway:signal:train_protection', value: 'NL:333' }
+ - { tag: 'railway:signal:train_protection:form', value: 'sign' }
+
# --- PL --- #
- description: Semafor kształtowy
diff --git a/features/speed_railway_signals.yaml b/features/speed_railway_signals.yaml
index 2342bbc9..240ca1c0 100644
--- a/features/speed_railway_signals.yaml
+++ b/features/speed_railway_signals.yaml
@@ -660,14 +660,138 @@ speed_railway_signals:
# --- NL --- #
- - description: speed limit light (part of main signal)
+ - description: L signal
+ country: NL
+ icon: { default: 'nl/276' }
+ tags:
+ - { tag: 'railway:signal:speed_limit', value: 'NL' }
+ - { tag: 'railway:signal:speed_limit:form', value: 'light' }
+ - { tag: 'railway:signal:speed_limit:states', value: 'L;off' }
+
+ - description: H signal
+ country: NL
+ icon: { default: 'nl/277' }
+ tags:
+ - { tag: 'railway:signal:speed_limit', value: 'NL' }
+ - { tag: 'railway:signal:speed_limit:form', value: 'light' }
+ - { tag: 'railway:signal:speed_limit:states', value: 'H;off' }
+
+ - description: X/G signal
+ country: NL
+ icon: { default: 'nl/279' }
+ tags:
+ - { tag: 'railway:signal:speed_limit', value: 'NL' }
+ - { tag: 'railway:signal:speed_limit:form', value: 'light' }
+ - { tag: 'railway:signal:speed_limit:states', value: 'X;G;off' }
+
+ - description: distant speed limit distant (sign)
+ country: NL
+ type: line
+ icon:
+ match: 'railway:signal:speed_limit_distant:speed'
+ cases:
+ - { regex: '^[1-9]0|1[0-4]0|125$', value: 'nl/313-{}', example: 'nl/313-80' }
+ default: 'nl/313-empty'
+ tags:
+ - { tag: 'railway:signal:speed_limit_distant', value: 'NL:313' }
+ - { tag: 'railway:signal:speed_limit_distant:form', value: 'sign' }
+
+ - description: speed limit (sign)
+ country: NL
+ type: line
+ icon:
+ match: 'railway:signal:speed_limit:speed'
+ cases:
+ - { regex: '^[1-9]0|1[0-46]0|[12]5|125$', value: 'nl/314-{}', example: 'nl/314-70' }
+ default: 'nl/314-empty'
+ tags:
+ - { tag: 'railway:signal:speed_limit', value: 'NL:314' }
+ - { tag: 'railway:signal:speed_limit:form', value: 'sign' }
+
+ - description: speed limit increase (sign)
+ country: NL
+ type: line
+ icon:
+ match: 'railway:signal:speed_limit:speed'
+ cases:
+ - { regex: '^[3-9]0|1[0-46]0|125$', value: 'nl/316-{}', example: 'nl/316-130' }
+ default: 'nl/316-empty'
+ tags:
+ - { tag: 'railway:signal:speed_limit', value: 'NL:316' }
+ - { tag: 'railway:signal:speed_limit:form', value: 'sign' }
+
+ - description: distant speed limit (light)
+ country: NL
+ type: line
+ icon:
+ match: 'railway:signal:speed_limit_distant:speed'
+ cases:
+ - { regex: '^[1-9]0|1[0-9]0$', value: 'nl/speed_limit_distant_light-{}', example: 'nl/speed_limit_distant_light-60' }
+ default: 'nl/speed_limit_distant_light-empty'
+ tags:
+ - { tag: 'railway:signal:speed_limit_distant', value: 'NL' }
+ - { tag: 'railway:signal:speed_limit_distant:form', value: 'light' }
+
+ - description: speed limit (light)
country: NL
type: line
- icon: { default: 'nl/speed_limit_light' }
+ icon:
+ match: 'railway:signal:speed_limit:speed'
+ cases:
+ - { regex: '^[1-9]0|1[0-9]0$', value: 'nl/speed_limit_light-{}', example: 'nl/speed_limit_light-60' }
+ default: 'nl/speed_limit_light-empty'
tags:
- { tag: 'railway:signal:speed_limit', value: 'NL' }
- { tag: 'railway:signal:speed_limit:form', value: 'light' }
+ - description: tunnel distant speed limit
+ country: NL
+ type: line
+ icon:
+ match: 'railway:signal:speed_limit_distant:speed'
+ cases:
+ - { regex: '^80$', value: 'nl/286-{}', example: 'nl/286-80' }
+ default: 'nl/286-empty'
+ tags:
+ - { tag: 'railway:signal:speed_limit_distant', value: 'NL:286' }
+ - { tag: 'railway:signal:speed_limit_distant:form', value: 'sign' }
+
+ - description: tunnel entry speed limit
+ country: NL
+ type: line
+ icon:
+ match: 'railway:signal:speed_limit:speed'
+ cases:
+ - { regex: '^[3-8]0$', value: 'nl/281-{}', example: 'nl/281-40' }
+ default: 'nl/281-empty'
+ tags:
+ - { tag: 'railway:signal:speed_limit', value: 'NL:281' }
+ - { tag: 'railway:signal:speed_limit:form', value: 'sign' }
+
+ - description: advisory speed (sign)
+ country: NL
+ type: line
+ icon:
+ match: 'railway:signal:speed_limit:speed'
+ cases:
+ - { regex: '^15|35|[4-9]0|120$', value: 'nl/282-{}', example: 'nl/282-40' }
+ default: 'nl/282-empty'
+ tags:
+ - { tag: 'railway:signal:speed_limit', value: 'NL:282' }
+ - { tag: 'railway:signal:speed_limit:form', value: 'sign' }
+
+ - description: advisory speed (light)
+ country: NL
+ type: line
+ icon:
+ match: 'railway:signal:speed_limit:speed'
+ cases:
+ - { regex: '^15|35|[4-9]0|120$', value: 'nl/282a-{}', example: 'nl/282a-40' }
+ default: 'nl/282a-empty'
+ tags:
+ - { tag: 'railway:signal:speed_limit', value: 'NL:282' }
+ - { tag: 'railway:signal:speed_limit:form', value: 'light' }
+
# --- PL --- #
- description: D6 Tarcza zwolnić bieg
diff --git a/features/track_class.yaml b/features/track_class.yaml
new file mode 100644
index 00000000..12418027
--- /dev/null
+++ b/features/track_class.yaml
@@ -0,0 +1,32 @@
+track_classes:
+ - { value: 'A', color: 'hsl(248, 100%, 40%)' }
+ - { value: 'B1', color: 'hsl(220, 100%, 40%)' }
+ - { value: 'B2', color: 'hsl(200, 100%, 40%)' }
+ - { value: 'C2', color: 'hsl(180, 100%, 40%)' }
+ - { value: 'C3', color: 'hsl(160, 100%, 40%)' }
+ - { value: 'C3L', color: 'hsl(140, 100%, 40%)' }
+ - { value: 'C4', color: 'hsl(120, 100%, 40%)' }
+ - { value: 'CE', color: 'hsl(100, 100%, 40%)' }
+ - { value: 'CM2', color: 'hsl(80, 100%, 40%)' }
+ - { value: 'CM3', color: 'hsl(60, 100%, 40%)' }
+ - { value: 'CM', color: 'hsl(40, 100%, 40%)' }
+ - { value: 'D2', color: 'hsl(30, 100%, 40%)' }
+ - { value: 'D3', color: 'hsl(20, 100%, 40%)' }
+ - { value: 'D4', color: 'hsl(10, 100%, 40%)' }
+ - { value: 'D4L', color: 'hsl(0, 100%, 40%)' }
+ - { value: 'E4', color: 'hsl(340, 100%, 40%)' }
+ - { value: 'E5', color: 'hsl(320, 100%, 40%)' }
+ - { value: 'F', color: 'hsl(300, 100%, 40%)' }
+ - { value: 'G', color: 'hsl(280, 100%, 40%)' }
+ - { value: '1', color: 'hsl(240, 100%, 40%)' }
+ - { value: '2', color: 'hsl(210, 100%, 40%)' }
+ - { value: '3', color: 'hsl(180, 100%, 40%)' }
+ - { value: '4', color: 'hsl(150, 100%, 40%)' }
+ - { value: '5', color: 'hsl(120, 100%, 40%)' }
+ - { value: '6', color: 'hsl(90, 100%, 40%)' }
+ - { value: '7', color: 'hsl(60, 100%, 40%)' }
+ - { value: '8', color: 'hsl(30, 100%, 40%)' }
+ - { value: '9', color: 'hsl(0, 100%, 40%)' }
+ - { value: '10', color: 'hsl(330, 100%, 40%)' }
+ - { value: '11', color: 'hsl(300, 100%, 40%)' }
+ - { value: 'excepted', color: 'black' }
diff --git a/import/Dockerfile b/import/Dockerfile
index 976a9e26..311df098 100644
--- a/import/Dockerfile
+++ b/import/Dockerfile
@@ -1,26 +1,28 @@
-FROM ghcr.io/hiddewie/template:v0.4.1 as build-lua
+FROM node:22-alpine as build-lua
WORKDIR /build
-RUN --mount=type=bind,source=import/openrailwaymap.lua,target=openrailwaymap.lua.tmpl \
+RUN npm install yaml
+
+RUN --mount=type=bind,source=import/tags.lua.js,target=tags.lua.js \
--mount=type=bind,source=features/electrification_signals.yaml,target=electrification_signals.yaml \
--mount=type=bind,source=features/speed_railway_signals.yaml,target=speed_railway_signals.yaml \
--mount=type=bind,source=features/train_protection.yaml,target=train_protection.yaml \
--mount=type=bind,source=features/signals_railway_signals.yaml,target=signals_railway_signals.yaml \
- cat electrification_signals.yaml speed_railway_signals.yaml train_protection.yaml signals_railway_signals.yaml \
- | template --configuration - --format yaml --template openrailwaymap.lua.tmpl \
- > /build/openrailwaymap.lua
+ node tags.lua.js \
+ > /build/tags.lua
-FROM ghcr.io/hiddewie/template:v0.4.1 as build-signals
+FROM node:22-alpine as build-signals
WORKDIR /build
-RUN --mount=type=bind,source=import/sql/signals_with_azimuth.sql,target=signals_with_azimuth.sql.tmpl \
+RUN npm install yaml
+
+RUN --mount=type=bind,source=import/sql/signals_with_azimuth.sql.js,target=signals_with_azimuth.sql.js \
--mount=type=bind,source=features/electrification_signals.yaml,target=electrification_signals.yaml \
--mount=type=bind,source=features/signals_railway_signals.yaml,target=signals_railway_signals.yaml \
--mount=type=bind,source=features/speed_railway_signals.yaml,target=speed_railway_signals.yaml \
- cat electrification_signals.yaml signals_railway_signals.yaml speed_railway_signals.yaml \
- | template --configuration - --format yaml --template signals_with_azimuth.sql.tmpl \
+ node signals_with_azimuth.sql.js \
> /build/signals_with_azimuth.sql
FROM debian:unstable-20240211-slim
@@ -49,9 +51,10 @@ WORKDIR /openrailwaymap
COPY import/sql sql
COPY import/docker-startup.sh docker-startup.sh
+COPY import/openrailwaymap.lua openrailwaymap.lua
COPY --from=build-lua \
- /build/openrailwaymap.lua openrailwaymap.lua
+ /build/tags.lua tags.lua
COPY --from=build-signals \
/build/signals_with_azimuth.sql sql/signals_with_azimuth.sql
diff --git a/import/docker-startup.sh b/import/docker-startup.sh
index c0eb5fa6..2758d225 100755
--- a/import/docker-startup.sh
+++ b/import/docker-startup.sh
@@ -131,5 +131,5 @@ $PSQL --tuples-only -c "with bounds as (SELECT st_transform(st_setsrid(ST_Extent
echo "Import bounds: $(cat /data/import/bounds.json)"
echo "Database summary"
-$PSQL -c "select table_name as table, pg_size_pretty(pg_total_relation_size(quote_ident(table_name))) as size from information_schema.tables where table_schema = 'public' order by table_name;"
-$PSQL -c "select pg_size_pretty(sum(pg_total_relation_size(quote_ident(table_name)))) as total_size from information_schema.tables where table_schema = 'public';"
+$PSQL -c "select concat(relname, ' (', relkind ,')') as name, pg_size_pretty(pg_table_size(oid)) as size from pg_class where relkind in ('m', 'r', 'i') and relname not like 'pg_%' order by pg_table_size(oid) desc;"
+$PSQL -c "select pg_size_pretty(SUM(pg_table_size(oid))) as size from pg_class where relkind in ('m', 'r', 'i') and relname not like 'pg_%';"
diff --git a/import/openrailwaymap.lua b/import/openrailwaymap.lua
index 7078406a..6043b48e 100644
--- a/import/openrailwaymap.lua
+++ b/import/openrailwaymap.lua
@@ -1,3 +1,5 @@
+local tag_functions = require('tags')
+
function dump(o)
if type(o) == 'table' then
local s = '{ '
@@ -137,6 +139,7 @@ local railway_line = osm2pgsql.define_table({
{ column = 'future_voltage', type = 'integer' },
{ column = 'gauges', sql_type = 'text[]' },
{ column = 'loading_gauge', sql_type = 'text' },
+ { column = 'track_class', sql_type = 'text' },
{ column = 'reporting_marks', sql_type = 'text[]' },
{ column = 'construction_railway', type = 'text' },
{ column = 'proposed_railway', type = 'text' },
@@ -202,29 +205,32 @@ local platforms = osm2pgsql.define_table({
},
})
+local signal_columns = {
+ { column = 'id', sql_type = 'serial', create_only = true },
+ { column = 'way', type = 'point' },
+ { column = 'railway', type = 'text' },
+ { column = 'rank', type = 'smallint' },
+ { column = 'deactivated', type = 'boolean' },
+ { column = 'ref', type = 'text' },
+ { column = 'ref_multiline', type = 'text' },
+ { column = 'signal_direction', type = 'text' },
+ { column = 'dominant_speed', type = 'real' },
+}
+for _, tag in ipairs(tag_functions.signal_tags) do
+ table.insert(signal_columns, { column = tag, type = 'text' })
+end
+for _, tag in ipairs(tag_functions.speed_tags) do
+ table.insert(signal_columns, { column = tag, type = 'text' })
+end
+for _, tag in ipairs(tag_functions.electrification_tags) do
+ table.insert(signal_columns, { column = tag, type = 'text' })
+end
local signals = osm2pgsql.define_table({
name = 'signals',
ids = { type = 'node', id_column = 'osm_id' },
- columns = {
- { column = 'id', sql_type = 'serial', create_only = true },
- { column = 'way', type = 'point' },
- { column = 'railway', type = 'text' },
- { column = 'rank', type = 'smallint' },
- { column = 'deactivated', type = 'boolean' },
- { column = 'ref', type = 'text' },
- { column = 'ref_multiline', type = 'text' },
- { column = 'signal_direction', type = 'text' },
- {% for tag in signals_railway_signals.tags %}
- { column = '{% tag %}', type = 'text' },
-{% end %}
- { column = 'dominant_speed', type = 'real' },
- {% for tag in speed_railway_signals.tags %}
- { column = '{% tag %}', type = 'text' },
-{% end %}
- {% for tag in electrification_signals.tags %}
- { column = '{% tag %}', type = 'text' },
-{% end %}
- },
+ columns = signal_columns,
+ -- The queried table is signals_with_azimuth
+ cluster = 'no',
})
local boxes = osm2pgsql.define_table({
@@ -233,6 +239,7 @@ local boxes = osm2pgsql.define_table({
columns = {
{ column = 'id', sql_type = 'serial', create_only = true },
{ column = 'way', type = 'geometry' },
+ { column = 'center', type = 'geometry' },
{ column = 'way_area', type = 'real' },
{ column = 'feature', type = 'text' },
{ column = 'ref', type = 'text' },
@@ -289,32 +296,24 @@ local routes = osm2pgsql.define_table({
},
})
-function train_protection(tags)
- {% for feature in signals_railway_line.features %}
- if {% for tag in feature.tags %}{% unless loop.first %} and{% end %}{% if tag.value %} tags['{% tag.tag %}'] == '{% tag.value %}'{% else %} ({% for value in tag.values %}{% unless loop.first %} or{% end %} tags['{% tag.tag %}'] == '{% value %}'{% end %}){% end %}{% end %} then return '{% feature.train_protection %}', ({% loop.size %} - {% loop.index0 %}) end
-{% end %}
-
- return nil, 0
-end
-
local electrification_values = osm2pgsql.make_check_values_func({'contact_line', 'yes', 'rail', 'ground-level_power_supply', '4th_rail', 'contact_line;rail', 'rail;contact_line'})
-function electrification_state(tags, ignore_future_states)
+function electrification_state(tags)
local electrified = tags['electrified']
if electrification_values(electrified) then
- return 'present', tonumber(tags['voltage']), tonumber(tags['frequency'])
+ return 'present', tonumber(tags['voltage']), tonumber(tags['frequency']), nil, nil
end
- if (not ignore_future_states) and electrification_values(tags['construction:electrified']) then
- return 'construction', tonumber(tags['construction:voltage']), tonumber(tags['construction:frequency'])
+ if electrification_values(tags['construction:electrified']) then
+ return 'construction', nil, nil, tonumber(tags['construction:voltage']), tonumber(tags['construction:frequency'])
end
- if (not ignore_future_states) and electrification_values(tags['proposed:electrified']) then
- return 'proposed', tonumber(tags['proposed:voltage']), tonumber(tags['proposed:frequency'])
+ if electrification_values(tags['proposed:electrified']) then
+ return 'proposed', nil, nil, tonumber(tags['proposed:voltage']), tonumber(tags['proposed:frequency'])
end
if electrified == 'no' and electrification_values(tags['deelectrified']) then
- return 'deelectrified', nil, nil
+ return 'deelectrified', nil, nil, nil, nil
end
if electrified == 'no' and electrification_values(tags['abandoned:electrified']) then
- return 'abandoned', nil, nil
+ return 'abandoned', nil, nil, nil, nil
end
return nil, nil, nil
@@ -333,8 +332,10 @@ function osm2pgsql.process_node(object)
local tags = object.tags
if railway_box_values(tags.railway) then
+ local point = object:as_point()
boxes:insert({
- way = object:as_point(),
+ way = point,
+ center = point,
way_area = 0,
feature = tags.railway,
ref = tags['railway:ref'],
@@ -479,7 +480,7 @@ function osm2pgsql.process_node(object)
local speed_limit_speed = tags['railway:signal:speed_limit'] and largest_speed_noconvert(tags['railway:signal:speed_limit:speed']) or tags['railway:signal:speed_limit:speed']
local speed_limit_distant_speed = tags['railway:signal:speed_limit_distant'] and largest_speed_noconvert(tags['railway:signal:speed_limit_distant:speed']) or tags['railway:signal:speed_limit_distant:speed']
- signals:insert({
+ local signal = {
way = object:as_point(),
railway = tags.railway,
rank = rank,
@@ -487,23 +488,24 @@ function osm2pgsql.process_node(object)
ref = tags.ref,
ref_multiline = ref_multiline ~= '' and ref_multiline or nil,
signal_direction = tags['railway:signal:direction'],
- {% for tag in signals_railway_signals.tags %}
- ["{% tag %}"] = tags['{% tag %}'],
-{% end %}
- {% for tag in speed_railway_signals.tags %}
- {% unless tag | matches("railway:signal:speed_limit:speed") %}
- {% unless tag | matches("railway:signal:speed_limit_distant:speed") %}
- ["{% tag %}"] = tags['{% tag %}'],
-{% end %}
-{% end %}
-{% end %}
["railway:signal:speed_limit:speed"] = speed_limit_speed,
["railway:signal:speed_limit_distant:speed"] = speed_limit_distant_speed,
dominant_speed = speed_int(tostring(speed_limit_speed) or tostring(speed_limit_distant_speed)),
- {% for tag in electrification_signals.tags %}
- ["{% tag %}"] = tags['{% tag %}'],
-{% end %}
- })
+ }
+
+ for _, tag in ipairs(tag_functions.signal_tags) do
+ signal[tag] = tags[tag]
+ end
+ for _, tag in ipairs(tag_functions.speed_tags) do
+ if tag ~= 'railway:signal:speed_limit:speed' and tag ~= 'railway:signal:speed_limit_distant:speed' then
+ signal[tag] = tags[tag]
+ end
+ end
+ for _, tag in ipairs(tag_functions.electrification_tags) do
+ signal[tag] = tags[tag]
+ end
+
+ signals:insert(signal)
end
if railway_position_values(tags.railway) and (tags['railway:position'] or tags['railway:position:exact']) then
@@ -533,10 +535,9 @@ function osm2pgsql.process_way(object)
local tags = object.tags
if railway_values(tags.railway) then
- local railway_train_protection, railway_train_protection_rank = train_protection(tags)
+ local railway_train_protection, railway_train_protection_rank = tag_functions.train_protection(tags)
- local current_electrification_state, voltage, frequency = electrification_state(tags, true)
- local _, future_voltage, future_frequency = electrification_state(tags, false)
+ local current_electrification_state, voltage, frequency, future_voltage, future_frequency = electrification_state(tags)
local gauges = {}
local gauge_tag = tags['gauge'] or tags['construction:gauge']
@@ -591,6 +592,7 @@ function osm2pgsql.process_way(object)
future_voltage = future_voltage,
gauges = '{' .. table.concat(gauges, ',') .. '}',
loading_gauge = tags['loading_gauge'],
+ track_class = tags['railway:track_class'],
reporting_marks = '{' .. table.concat(reporting_marks, ',') .. '}',
construction_railway = tags['construction:railway'],
proposed_railway = tags['proposed:railway'],
@@ -623,6 +625,7 @@ function osm2pgsql.process_way(object)
local polygon = object:as_polygon():transform(3857)
boxes:insert({
way = polygon,
+ center = polygon:centroid(),
way_area = polygon:area(),
feature = tags.railway,
ref = tags['railway:ref'],
diff --git a/import/sql/functions.sql b/import/sql/functions.sql
index 865e0a46..7962ea8e 100644
--- a/import/sql/functions.sql
+++ b/import/sql/functions.sql
@@ -49,7 +49,7 @@ $$ LANGUAGE plpgsql
LEAKPROOF
PARALLEL SAFE;
-CREATE OR REPLACE FUNCTION railway_pos_round(km_pos TEXT) RETURNS NUMERIC AS $$
+CREATE OR REPLACE FUNCTION railway_pos_round(km_pos TEXT, decimals int) RETURNS NUMERIC AS $$
DECLARE
pos_part1 TEXT;
km_float NUMERIC(8, 3);
@@ -59,8 +59,8 @@ BEGIN
RETURN NULL;
END IF;
km_float := pos_part1::NUMERIC(8, 3);
- km_float := round(km_float, 1);
- RETURN trunc(km_float, 1);
+ km_float := round(km_float, decimals);
+ RETURN trunc(km_float, decimals);
END;
$$ LANGUAGE plpgsql
IMMUTABLE
diff --git a/import/sql/signals_with_azimuth.sql b/import/sql/signals_with_azimuth.sql
deleted file mode 100644
index 625d4c8c..00000000
--- a/import/sql/signals_with_azimuth.sql
+++ /dev/null
@@ -1,96 +0,0 @@
--- Table with signals including their azimuth based on the direction of the signal and the railway line
--- and the functional signal feature
-CREATE OR REPLACE VIEW signals_with_azimuth_view AS
- -- TODO investigate signals with null features
- SELECT
- s.*,
- degrees(ST_Azimuth(
- st_lineinterpolatepoint(sl.way, greatest(0, st_linelocatepoint(sl.way, ST_ClosestPoint(sl.way, s.way)) - 0.01)),
- st_lineinterpolatepoint(sl.way, least(1, st_linelocatepoint(sl.way, ST_ClosestPoint(sl.way, s.way)) + 0.01))
- )) + (CASE WHEN signal_direction = 'backward' THEN 180.0 ELSE 0.0 END) as azimuth,
- CASE
-
- {% for feature in signals_railway_signals.features %}
- -- ({% feature.country %}) {% feature.description %}
- WHEN{% for tag in feature.tags %} "{% tag.tag %}"{% if tag.value %}='{% tag.value %}'{% elif tag.values %} IN ({% for value in tag.values %}{% unless loop.first %}, {% end %}'{% value %}'{% end %}){% end %}{% unless loop.last %} AND{% end %}{% end %}
-
- THEN {% if feature.icon.match %} CASE
- {% for case in feature.icon.cases %}
- WHEN "{% feature.icon.match %}" ~ '{% case.regex %}' THEN '{% case.value %}'
-
-{% end %}
- {% if feature.icon.default %}
- ELSE '{% feature.icon.default %}'
-{% end %}
- END{% else %} '{% feature.icon.default %}'{% end %}
-
-
-{% end %}
-
- END as signal_feature,
- CASE
- {% for feature in speed_railway_signals.features %}
- -- ({% feature.country %}) {% feature.description %}
- WHEN{% for tag in feature.tags %} "{% tag.tag %}"{% if tag.value %}='{% tag.value %}'{% elif tag.values %} IN ({% for value in tag.values %}{% unless loop.first %}, {% end %}'{% value %}'{% end %}){% end %}{% unless loop.last %} AND{% end %}{% end %}
-
- THEN {% if feature.icon.match %} CASE
- {% for case in feature.icon.cases %}
- WHEN "{% feature.icon.match %}" ~ '{% case.regex %}' THEN{% if case.value | contains("{}") %} CONCAT('{% case.value | regexReplace("\{\}.*$", "") %}', "{% feature.icon.match %}", '{% case.value | regexReplace("^.*\{\}", "") %}'){% else %} '{% case.value %}'{% end %}
-
-{% end %}
- {% if feature.icon.default %}
- ELSE '{% feature.icon.default %}'
-{% end %}
- END{% else %} '{% feature.icon.default %}'{% end %}
-
-
-{% end %}
-
- END as speed_feature,
- CASE
- {% for feature in speed_railway_signals.features %}
- {% if feature.type %}
- -- ({% feature.country %}) {% feature.description %}
- WHEN{% for tag in feature.tags %} "{% tag.tag %}"{% if tag.value %}='{% tag.value %}'{% elif tag.values %} IN ({% for value in tag.values %}{% unless loop.first %}, {% end %}'{% value %}'{% end %}){% end %}{% unless loop.last %} AND{% end %}{% end %} THEN '{% feature.type %}'
-
-{% end %}
-{% end %}
-
- END as speed_feature_type,
- CASE
- {% for feature in electrification_signals.features %}
- -- ({% feature.country %}) {% feature.description %}
- WHEN{% for tag in feature.tags %} "{% tag.tag %}"{% if tag.value %}='{% tag.value %}'{% elif tag.values %} IN ({% for value in tag.values %}{% unless loop.first %}, {% end %}'{% value %}'{% end %}){% end %}{% unless loop.last %} AND{% end %}{% end %}
-
- THEN {% if feature.icon.match %} CASE
- {% for case in feature.icon.cases %}
- WHEN "{% feature.icon.match %}" ~ '{% case.regex %}' THEN '{% case.value %}'
-{% end %}
- ELSE '{% feature.icon.default %}'
- END{% else %} '{% feature.icon.default %}'{% end %}
-
-
-{% end %}
- END as electrification_feature
- FROM signals s
- LEFT JOIN LATERAL (
- SELECT line.way as way
- FROM railway_line line
- WHERE st_dwithin(s.way, line.way, 10) AND line.railway IN ('rail', 'tram', 'light_rail', 'subway', 'narrow_gauge', 'construction', 'preserved', 'monorail', 'miniature') -- TODO use feature
- ORDER BY s.way <-> line.way
- LIMIT 1
- ) as sl ON true
- WHERE
- (railway IN ('signal', 'buffer_stop') AND signal_direction IS NOT NULL)
- OR railway IN ('derail', 'vacancy_detection');
-
--- Use the view directly such that the query in the view can be updated
-CREATE MATERIALIZED VIEW IF NOT EXISTS signals_with_azimuth AS
- SELECT
- *
- FROM
- signals_with_azimuth_view;
-
-CREATE INDEX IF NOT EXISTS signals_with_azimuth_geom_index
- ON signals_with_azimuth
- USING GIST(way);
diff --git a/import/sql/signals_with_azimuth.sql.js b/import/sql/signals_with_azimuth.sql.js
new file mode 100644
index 00000000..cc2ffcbe
--- /dev/null
+++ b/import/sql/signals_with_azimuth.sql.js
@@ -0,0 +1,95 @@
+import fs from 'fs'
+import yaml from 'yaml'
+
+const speed_railway_signals = yaml.parse(fs.readFileSync('speed_railway_signals.yaml', 'utf8')).speed_railway_signals
+const signals_railway_signals = yaml.parse(fs.readFileSync('signals_railway_signals.yaml', 'utf8')).signals_railway_signals
+const electrification_signals = yaml.parse(fs.readFileSync('electrification_signals.yaml', 'utf8')).electrification_signals
+
+/**
+ * Template that builds the SQL view taking the YAML configuration into account
+ */
+const sql = `
+-- Table with signals including their azimuth based on the direction of the signal and the railway line
+-- and the functional signal feature
+CREATE OR REPLACE VIEW signals_with_azimuth_view AS
+ SELECT
+ id,
+ osm_id,
+ s.way as way,
+ railway,
+ ref,
+ ref_multiline,
+ deactivated,
+ signal_direction,
+ "railway:signal:speed_limit",
+ dominant_speed,
+ rank,
+ degrees(ST_Azimuth(
+ st_lineinterpolatepoint(sl.way, greatest(0, st_linelocatepoint(sl.way, ST_ClosestPoint(sl.way, s.way)) - 0.01)),
+ st_lineinterpolatepoint(sl.way, least(1, st_linelocatepoint(sl.way, ST_ClosestPoint(sl.way, s.way)) + 0.01))
+ )) + (CASE WHEN signal_direction = 'backward' THEN 180.0 ELSE 0.0 END) as azimuth,
+ CASE ${signals_railway_signals.features.map(feature => `
+ -- ${feature.country ? `(${feature.country}) ` : ''}${feature.description}
+ WHEN ${feature.tags.map(tag => `"${tag.tag}" ${tag.value ? `= '${tag.value}'`: tag.values ? `IN (${tag.values.map(value => `'${value}'`).join(', ')})` : ''}`).join(' AND ')}
+ THEN ${feature.icon.match ? `CASE ${feature.icon.cases.map(iconCase => `
+ WHEN "${feature.icon.match}" ~ '${iconCase.regex}' THEN '${iconCase.value}'`).join('')}
+ ${feature.icon.default ? `ELSE '${feature.icon.default}'` : ''}
+ END` : `'${feature.icon.default}'`}
+ `).join('')}
+ END as signal_feature,
+
+ CASE ${speed_railway_signals.features.map(feature => `
+ -- ${feature.country ? `(${feature.country}) ` : ''}${feature.description}
+ WHEN ${feature.tags.map(tag => `"${tag.tag}" ${tag.value ? `= '${tag.value}'`: tag.values ? `IN (${tag.values.map(value => `'${value}'`).join(', ')})` : ''}`).join(' AND ')}
+ THEN ${feature.icon.match ? `CASE ${feature.icon.cases.map(iconCase => `
+ WHEN "${feature.icon.match}" ~ '${iconCase.regex}' THEN ${iconCase.value.includes('{}') ? `CONCAT('${iconCase.value.replace(/\{}.*$/, '')}', "${feature.icon.match}", '${iconCase.value.replace(/^.*\{}/, '')}')` : `'${iconCase.value}'`}`).join('')}
+ ${feature.icon.default ? `ELSE '${feature.icon.default}'` : ''}
+ END` : `'${feature.icon.default}'`}
+ `).join('')}
+ END as speed_feature,
+
+ CASE ${speed_railway_signals.features.map(feature => feature.type ? `
+ -- ${feature.country ? `(${feature.country}) ` : ''}${feature.description}
+ WHEN ${feature.tags.map(tag => `"${tag.tag}" ${tag.value ? `= '${tag.value}'`: tag.values ? `IN (${tag.values.map(value => `'${value}'`).join(', ')})` : ''}`).join(' AND ')} THEN '${feature.type}'
+ ` : '').join('')}
+ END as speed_feature_type,
+
+ CASE ${electrification_signals.features.map(feature => `
+ -- ${feature.country ? `(${feature.country}) ` : ''}${feature.description}
+ WHEN ${feature.tags.map(tag => `"${tag.tag}" ${tag.value ? `= '${tag.value}'`: tag.values ? `IN (${tag.values.map(value => `'${value}'`).join(', ')})` : ''}`).join(' AND ')}
+ THEN ${feature.icon.match ? `CASE ${feature.icon.cases.map(iconCase => `
+ WHEN "${feature.icon.match}" ~ '${iconCase.regex}' THEN '${iconCase.value}'`).join('')}
+ ${feature.icon.default ? `ELSE '${feature.icon.default}'` : ''}
+ END` : `'${feature.icon.default}'`}
+ `).join('')}
+ END as electrification_feature
+
+ FROM signals s
+ LEFT JOIN LATERAL (
+ SELECT line.way as way
+ FROM railway_line line
+ WHERE st_dwithin(s.way, line.way, 10) AND line.railway IN ('rail', 'tram', 'light_rail', 'subway', 'narrow_gauge', 'construction', 'preserved', 'monorail', 'miniature') -- TODO use feature
+ ORDER BY s.way <-> line.way
+ LIMIT 1
+ ) as sl ON true
+ WHERE
+ (railway IN ('signal', 'buffer_stop') AND signal_direction IS NOT NULL)
+ OR railway IN ('derail', 'vacancy_detection');
+
+-- Use the view directly such that the query in the view can be updated
+CREATE MATERIALIZED VIEW IF NOT EXISTS signals_with_azimuth AS
+ SELECT
+ *
+ FROM
+ signals_with_azimuth_view
+ WHERE
+ signal_feature IS NOT NULL
+ OR speed_feature IS NOT NULL
+ OR electrification_feature IS NOT NULL;
+
+CREATE INDEX IF NOT EXISTS signals_with_azimuth_geom_index
+ ON signals_with_azimuth
+ USING GIST(way);
+`
+
+console.log(sql);
diff --git a/import/sql/tile_views.sql b/import/sql/tile_views.sql
index 08c16494..e2d33ddf 100644
--- a/import/sql/tile_views.sql
+++ b/import/sql/tile_views.sql
@@ -3,6 +3,7 @@
CREATE OR REPLACE VIEW railway_line_high AS
SELECT
id,
+ osm_id,
way,
way_length,
railway,
@@ -26,6 +27,7 @@ CREATE OR REPLACE VIEW railway_line_high AS
END AS standard_label,
ref,
track_ref,
+ track_class,
array_to_string(reporting_marks, ', ') as reporting_marks,
preferred_direction,
CASE
@@ -68,6 +70,7 @@ CREATE OR REPLACE VIEW railway_line_high AS
FROM
(SELECT
id,
+ osm_id,
way,
way_length,
railway,
@@ -85,6 +88,7 @@ CREATE OR REPLACE VIEW railway_line_high AS
bridge,
tunnel,
track_ref,
+ track_class,
ref,
CASE
WHEN railway = 'abandoned' THEN railway_label_name(COALESCE(abandoned_name, name), tunnel, tunnel_name, bridge, bridge_name)
@@ -134,6 +138,7 @@ CREATE OR REPLACE VIEW railway_line_low AS
CREATE OR REPLACE VIEW standard_railway_text_stations_low AS
SELECT
id,
+ osm_id,
way,
railway_ref as label
FROM stations_with_route_counts
@@ -147,6 +152,7 @@ CREATE OR REPLACE VIEW standard_railway_text_stations_low AS
CREATE OR REPLACE VIEW standard_railway_text_stations_med AS
SELECT
id,
+ osm_id,
way,
railway_ref as label
FROM stations_with_route_counts
@@ -159,6 +165,7 @@ CREATE OR REPLACE VIEW standard_railway_text_stations_med AS
CREATE OR REPLACE VIEW standard_railway_text_stations AS
SELECT
id,
+ osm_id,
way,
railway,
station,
@@ -182,6 +189,7 @@ CREATE OR REPLACE VIEW standard_railway_text_stations AS
FROM
(SELECT
id,
+ osm_id,
way,
railway,
route_count,
@@ -197,6 +205,7 @@ CREATE OR REPLACE VIEW standard_railway_text_stations AS
CREATE OR REPLACE VIEW standard_railway_symbols AS
SELECT
id,
+ osm_id,
way,
CASE
WHEN railway = 'crossing' THEN 'general/crossing'
@@ -244,16 +253,19 @@ CREATE OR REPLACE VIEW standard_railway_symbols AS
CREATE OR REPLACE VIEW railway_text_km AS
SELECT
id,
+ osm_id,
way,
railway,
pos,
- (railway_pos_decimal(pos) = '0') as zero
+ (railway_pos_decimal(pos) = '0') as zero,
+ railway_pos_round(pos, 0)::text as pos_int
FROM
(SELECT
id,
+ osm_id,
way,
railway,
- COALESCE(railway_position, railway_pos_round(railway_position_exact)::text) AS pos
+ COALESCE(railway_position, railway_pos_round(railway_position_exact, 1)::text) AS pos
FROM railway_positions
) AS r
WHERE pos IS NOT NULL
@@ -262,6 +274,7 @@ CREATE OR REPLACE VIEW railway_text_km AS
CREATE OR REPLACE VIEW standard_railway_switch_ref AS
SELECT
id,
+ osm_id,
way,
railway,
ref,
@@ -275,12 +288,14 @@ CREATE OR REPLACE VIEW standard_railway_switch_ref AS
CREATE OR REPLACE VIEW speed_railway_signals AS
SELECT
id,
+ osm_id,
way,
speed_feature as feature,
speed_feature_type as type,
azimuth,
- (signal_direction = 'both') as direction_both
- FROM signals_with_azimuth s
+ (signal_direction = 'both') as direction_both,
+ ref
+ FROM signals_with_azimuth
WHERE railway = 'signal'
AND speed_feature IS NOT NULL
ORDER BY
@@ -291,19 +306,40 @@ CREATE OR REPLACE VIEW speed_railway_signals AS
--- Signals ---
-CREATE OR REPLACE VIEW signals_signal_boxes AS
- SELECT
- id,
- way,
- feature,
- ref,
- name
- FROM boxes
- ORDER BY way_area DESC NULLS LAST;
+CREATE OR REPLACE FUNCTION signals_signal_boxes(z integer, x integer, y integer)
+ RETURNS bytea
+ LANGUAGE SQL
+ IMMUTABLE
+ STRICT
+ PARALLEL SAFE
+ RETURN (
+ SELECT
+ ST_AsMVT(tile, 'signals_signal_boxes', 4096, 'way')
+ FROM (
+ SELECT
+ ST_AsMVTGeom(
+ CASE
+ WHEN z >= 14 THEN way
+ ELSE center
+ END,
+ ST_TileEnvelope(z, x, y),
+ 4096, 64, true
+ ) AS way,
+ id,
+ osm_id,
+ feature,
+ ref,
+ name
+ FROM boxes
+ WHERE way && ST_TileEnvelope(z, x, y)
+ ) as tile
+ WHERE way IS NOT NULL
+ );
CREATE OR REPLACE VIEW signals_railway_signals AS
SELECT
id,
+ osm_id,
way,
railway,
ref,
@@ -321,10 +357,12 @@ CREATE OR REPLACE VIEW signals_railway_signals AS
CREATE OR REPLACE VIEW electrification_signals AS
SELECT
id,
+ osm_id,
way,
electrification_feature as feature,
azimuth,
- (signal_direction = 'both') as direction_both
+ (signal_direction = 'both') as direction_both,
+ ref
FROM signals_with_azimuth
WHERE
railway = 'signal'
diff --git a/import/tags.lua.js b/import/tags.lua.js
new file mode 100644
index 00000000..1598b72e
--- /dev/null
+++ b/import/tags.lua.js
@@ -0,0 +1,39 @@
+import fs from 'fs'
+import yaml from 'yaml'
+
+const signals_railway_line = yaml.parse(fs.readFileSync('train_protection.yaml', 'utf8')).signals_railway_line
+const speed_railway_signals = yaml.parse(fs.readFileSync('speed_railway_signals.yaml', 'utf8')).speed_railway_signals
+const signals_railway_signals = yaml.parse(fs.readFileSync('signals_railway_signals.yaml', 'utf8')).signals_railway_signals
+const electrification_signals = yaml.parse(fs.readFileSync('electrification_signals.yaml', 'utf8')).electrification_signals
+
+/**
+ * Template that builds Lua functions used in the Osm2Psql Lua import, and taking the YAML configuration into account
+ */
+const lua = `
+function train_protection(tags)${signals_railway_line.features.map((feature, featureIndex) => `
+ if ${feature.tags.map(tag => `${tag.value ? `tags['${tag.tag}'] == '${tag.value}'`: `(${tag.values.map(value => `tags['${tag.tag}'] == '${value}'`).join(' or ')})`}`).join(' and ')} then return '${feature.train_protection}', ${signals_railway_line.features.length - featureIndex} end`).join('')}
+
+ return nil, 0
+end
+
+local signal_tags = {${signals_railway_signals.tags.map(tag => `
+ '${tag}',`).join('')}
+}
+
+local speed_tags = {${speed_railway_signals.tags.map(tag => `
+ '${tag}',`).join('')}
+}
+
+local electrification_tags = {${electrification_signals.tags.map(tag => `
+ '${tag}',`).join('')}
+}
+
+return {
+ train_protection = train_protection,
+ signal_tags = signal_tags,
+ speed_tags = speed_tags,
+ electrification_tags = electrification_tags,
+}
+`;
+
+console.log(lua)
diff --git a/martin/configuration.yml b/martin/configuration.yml
index ad6ba899..2dd1e8e5 100644
--- a/martin/configuration.yml
+++ b/martin/configuration.yml
@@ -35,6 +35,7 @@ postgres:
properties:
# TODO calculate labels in frontend
id: integer
+ osm_id: integer
railway: string
feature: string
usage: string
@@ -64,6 +65,7 @@ postgres:
gaugeint2: number
gauge_label: string
loading_gauge: string
+ track_class: string
reporting_marks: string
railway_line_med:
@@ -75,6 +77,7 @@ postgres:
properties:
# TODO calculate labels in frontend
id: integer
+ osm_id: integer
railway: string
feature: string
usage: string
@@ -104,6 +107,7 @@ postgres:
gaugeint2: number
gauge_label: string
loading_gauge: string
+ track_class: string
reporting_marks: string
railway_line_high:
@@ -115,6 +119,7 @@ postgres:
properties:
# TODO calculate labels in frontend
id: integer
+ osm_id: integer
way_length: number
railway: string
feature: string
@@ -145,6 +150,7 @@ postgres:
gaugeint2: number
gauge_label: string
loading_gauge: string
+ track_class: string
reporting_marks: string
# --- Standard --- #
@@ -157,6 +163,7 @@ postgres:
geometry_type: POINT
properties:
id: integer
+ osm_id: integer
label: string
standard_railway_text_stations_med:
@@ -167,6 +174,7 @@ postgres:
geometry_type: POINT
properties:
id: integer
+ osm_id: integer
label: string
standard_railway_turntables:
@@ -177,6 +185,7 @@ postgres:
geometry_type: POLYGON
properties:
id: integer
+ osm_id: integer
feature: string
standard_railway_text_stations:
@@ -187,6 +196,7 @@ postgres:
geometry_type: POINT
properties:
id: integer
+ osm_id: integer
railway: string
station: string
label: string
@@ -200,6 +210,7 @@ postgres:
geometry_type: POINT
properties:
id: integer
+ osm_id: integer
feature: string
railway_text_km:
@@ -210,8 +221,10 @@ postgres:
geometry_type: POINT
properties:
id: integer
+ osm_id: integer
railway: string
pos: string
+ pos_int: string
zero: boolean
standard_railway_switch_ref:
@@ -222,6 +235,7 @@ postgres:
geometry_type: POINT
properties:
id: integer
+ osm_id: integer
railway: string
ref: string
# TODO: rename local_operated
@@ -237,8 +251,10 @@ postgres:
geometry_type: POINT
properties:
id: integer
+ osm_id: integer
feature: string
type: string
+ ref: string
azimuth: number
direction_both: boolean
@@ -252,6 +268,7 @@ postgres:
geometry_type: POINT
properties:
id: integer
+ osm_id: integer
railway: string
ref: string
ref_multiline: string
@@ -260,17 +277,7 @@ postgres:
azimuth: number
direction_both: boolean
- signals_signal_boxes:
- schema: public
- table: signals_signal_boxes
- srid: 3857
- geometry_column: way
- geometry_type: GEOMETRY
- properties:
- id: integer
- feature: string
- ref: string
- name: string
+ # signals_signal_boxes, see function below
# --- Electrification --- #
@@ -282,9 +289,22 @@ postgres:
geometry_type: POINT
properties:
id: integer
+ osm_id: integer
feature: string
azimuth: number
direction_both: boolean
+ ref: string
+
+
+ functions:
+
+ # --- Signals --- #
+
+ signals_signal_boxes:
+ schema: public
+ function: signals_signal_boxes
+ minzoom: 8
+ maxzoom: 14
fonts:
- /config/fonts
diff --git a/martin/fonts/FiraCode-Bold.ttf b/martin/fonts/FiraCode-Bold.ttf
new file mode 100644
index 00000000..f891bde4
Binary files /dev/null and b/martin/fonts/FiraCode-Bold.ttf differ
diff --git a/martin/fonts/FiraCode-Regular.ttf b/martin/fonts/FiraCode-Regular.ttf
new file mode 100644
index 00000000..bd736851
Binary files /dev/null and b/martin/fonts/FiraCode-Regular.ttf differ
diff --git a/proxy.Dockerfile b/proxy.Dockerfile
index e392d8bd..1561ff57 100644
--- a/proxy.Dockerfile
+++ b/proxy.Dockerfile
@@ -13,6 +13,7 @@ RUN --mount=type=bind,source=proxy/js/styles.mjs,target=styles.mjs \
--mount=type=bind,source=features/electrification_signals.yaml,target=electrification_signals.yaml \
--mount=type=bind,source=features/signals_railway_signals.yaml,target=signals_railway_signals.yaml \
--mount=type=bind,source=features/loading_gauge.yaml,target=loading_gauge.yaml \
+ --mount=type=bind,source=features/track_class.yaml,target=track_class.yaml \
node /build/styles.mjs
FROM nginx:1-alpine
diff --git a/proxy/js/styles.mjs b/proxy/js/styles.mjs
index d911c013..70cc478c 100644
--- a/proxy/js/styles.mjs
+++ b/proxy/js/styles.mjs
@@ -6,6 +6,7 @@ const speed_railway_signals = yaml.parse(fs.readFileSync('speed_railway_signals.
const signals_railway_signals = yaml.parse(fs.readFileSync('signals_railway_signals.yaml', 'utf8')).signals_railway_signals
const electrification_signals = yaml.parse(fs.readFileSync('electrification_signals.yaml', 'utf8')).electrification_signals
const loading_gauges = yaml.parse(fs.readFileSync('loading_gauge.yaml', 'utf8')).loading_gauges
+const track_classes = yaml.parse(fs.readFileSync('track_class.yaml', 'utf8')).track_classes
const origin = `${process.env.PUBLIC_PROTOCOL}://${process.env.PUBLIC_HOST}`
@@ -16,10 +17,11 @@ const knownStyles = [
'electrification',
'gauge',
'loading_gauge',
+ 'track_class',
];
const globalMinZoom = 1;
-const glodalMaxZoom = 18;
+const glodalMaxZoom = 20;
const colors = {
hover: {
@@ -719,8 +721,8 @@ const electrificationColor = (voltageProperty, frequencyProperty) => ['case',
['all', ['==', ['get', frequencyProperty], 50], ['==', ['get', voltageProperty], 25000]], color_25kv_50hz,
['all', ['==', ['get', frequencyProperty], 60], ['==', ['get', voltageProperty], 20000]], color_20kv_60hz,
['all', ['==', ['get', frequencyProperty], 50], ['==', ['get', voltageProperty], 20000]], color_20kv_50hz,
- ['all', ['<', 16.665, ['get', frequencyProperty]], ['<', ['get', frequencyProperty], 16.675], ['==', ['get', voltageProperty], 15000]], color_15kv_16_67hz,
- ['all', ['<', 16.65, ['get', frequencyProperty]], ['<', ['get', frequencyProperty], 16.75], ['==', ['get', voltageProperty], 15000]], color_15kv_16_7hz,
+ ['all', ['!=', ['get', frequencyProperty], null], ['<', 16.665, ['get', frequencyProperty]], ['<', ['get', frequencyProperty], 16.675], ['==', ['get', voltageProperty], 15000]], color_15kv_16_67hz,
+ ['all', ['!=', ['get', frequencyProperty], null], ['<', 16.65, ['get', frequencyProperty]], ['<', ['get', frequencyProperty], 16.75], ['==', ['get', voltageProperty], 15000]], color_15kv_16_7hz,
['all', ['==', ['get', frequencyProperty], 60], ['==', ['get', voltageProperty], 12500]], color_12_5kv_60hz,
['all', ['==', ['get', frequencyProperty], 25], ['==', ['get', voltageProperty], 12000]], color_12kv_25hz,
['all', ['==', ['get', frequencyProperty], 0], ['!=', ['get', voltageProperty], null], ['>', ['get', voltageProperty], 3000]], color_gt3kv_dc,
@@ -731,7 +733,7 @@ const electrificationColor = (voltageProperty, frequencyProperty) => ['case',
['all', ['==', ['get', frequencyProperty], 0], ['==', ['get', voltageProperty], 1000]], color_1kv_dc,
['all', ['==', ['get', frequencyProperty], 0], ['!=', ['get', voltageProperty], null], ['>', 1000, ['get', voltageProperty]], ['>', ['get', voltageProperty], 750]], color_gt750v_lt1kv_dc,
['all', ['==', ['get', frequencyProperty], 0], ['==', ['get', voltageProperty], 750]], color_750v_dc,
- ['all', ['==', ['get', frequencyProperty], 0], ['!=', ['get', voltageProperty], null], ['<', 750, ['get', voltageProperty]]], color_lt750v_dc,
+ ['all', ['==', ['get', frequencyProperty], 0], ['!=', ['get', voltageProperty], null], ['>', 750, ['get', voltageProperty]]], color_lt750v_dc,
['all',
['!=', ['get', frequencyProperty], 0],
['!=', ['get', voltageProperty], null],
@@ -988,6 +990,26 @@ const loadingGaugeLayout = {
'line-cap': 'round',
};
+const trackClassCasingPaint = {
+ 'line-color': 'white',
+ 'line-width': railwayLineWidth,
+ 'line-gap-width': 0.75,
+};
+const trackClassFillPaint = (dashArray) => ({
+ 'line-color': ['match', ['get', 'track_class'],
+ ...track_classes.flatMap(track_class =>
+ [track_class.value, track_class.color]
+ ),
+ 'gray',
+ ],
+ 'line-width': railwayLineWidth,
+ 'line-dasharray': dashArray,
+});
+const trackClassLayout = {
+ 'line-join': 'round',
+ 'line-cap': 'round',
+};
+
const attribution = '© OpenRailwayMap contributors | © OpenStreetMap contributors';
const sources = {
@@ -1078,7 +1100,7 @@ const railwayKmText = {
true,
],
paint: {
- 'text-color': 'black',
+ 'text-color': 'hsl(268, 100%, 40%)',
'text-halo-color': ['case',
['boolean', ['feature-state', 'hover'], false], colors.hover.textHalo,
'white',
@@ -1087,8 +1109,12 @@ const railwayKmText = {
},
layout: {
'symbol-z-order': 'source',
- 'text-field': '{pos}',
- 'text-font': ['Noto Sans Bold'],
+ 'text-field': ['step', ['zoom'],
+ ['get', 'pos_int'],
+ 13,
+ ['get', 'pos'],
+ ],
+ 'text-font': ['Fira Code Bold'],
'text-size': 11,
},
};
@@ -2230,9 +2256,23 @@ const layers = {
16,
['!=', ['get', 'feature'], null],
],
+ paint: {
+ 'text-halo-color': ['case',
+ ['boolean', ['feature-state', 'hover'], false], colors.hover.textHalo,
+ 'white'
+ ],
+ 'text-halo-width': 1.5,
+ 'text-halo-blur': 1,
+ },
layout: {
'symbol-z-order': 'source',
'icon-overlap': 'always',
+ 'text-field': '{ref}',
+ 'text-font': ['Noto Sans Medium'],
+ 'text-size': 9,
+ 'text-optional': true,
+ 'text-anchor': 'top',
+ 'text-offset': ['literal', [0, 1.5]],
},
},
),
@@ -2275,7 +2315,7 @@ const layers = {
'text-font': ['Noto Sans Bold'],
'text-size': 11,
'text-padding': 30,
- 'symbol-spacing': 100,
+ 'symbol-spacing': 200,
},
},
searchResults,
@@ -2381,7 +2421,7 @@ const layers = {
['boolean', ['feature-state', 'hover'], false], colors.hover.main,
'#008206',
],
- 'circle-radius': 6,
+ 'circle-radius': 4,
'circle-stroke-color': 'white',
'circle-stroke-width': 1,
},
@@ -2389,7 +2429,7 @@ const layers = {
{
id: 'signal_boxes_polygon',
type: 'fill',
- minzoom: 12,
+ minzoom: 14,
source: 'openrailwaymap_signals',
'source-layer': 'signals_signal_boxes',
filter: ['any',
@@ -2407,7 +2447,7 @@ const layers = {
{
id: 'signal_boxes_polygon_outline',
type: 'line',
- minzoom: 12,
+ minzoom: 14,
source: 'openrailwaymap_signals',
'source-layer': 'signals_signal_boxes',
filter: ['any',
@@ -2477,9 +2517,35 @@ const layers = {
minzoom: 16,
source: 'openrailwaymap_signals',
'source-layer': 'signals_railway_signals',
+ paint: {
+ 'text-halo-color': ['case',
+ ['boolean', ['feature-state', 'hover'], false], colors.hover.textHalo,
+ 'white'
+ ],
+ 'text-halo-width': ['case',
+ ['==', ['slice', ['get', 'feature'], 0, 20], 'de/blockkennzeichen-'], 2.0,
+ 1.5,
+ ],
+ 'text-halo-blur': 1,
+ },
layout: {
'symbol-z-order': 'source',
'icon-overlap': 'always',
+ 'text-field': ['case',
+ ['==', ['slice', ['get', 'feature'], 0, 20], 'de/blockkennzeichen-'], ['get', 'ref_multiline'],
+ ['get', 'ref'],
+ ],
+ 'text-font': ['Noto Sans Medium'],
+ 'text-size': 9,
+ 'text-optional': true,
+ 'text-anchor': ['case',
+ ['==', ['slice', ['get', 'feature'], 0, 20], 'de/blockkennzeichen-'], 'center',
+ 'top',
+ ],
+ 'text-offset': ['case',
+ ['==', ['slice', ['get', 'feature'], 0, 20], 'de/blockkennzeichen-'], ['literal', [0, 0]],
+ ['literal', [0, 1.5]],
+ ],
},
},
),
@@ -2515,6 +2581,7 @@ const layers = {
'text-field': '{ref}',
'text-font': ['Noto Sans Bold'],
'text-size': 11,
+ 'text-offset': ['literal', [0, 1]],
}
},
railwayKmText,
@@ -2538,71 +2605,6 @@ const layers = {
'text-size': 11,
}
},
- {
- id: 'railway_signals_blockkennzeichen_text',
- type: 'symbol',
- minzoom: 16,
- source: 'openrailwaymap_signals',
- 'source-layer': 'signals_railway_signals',
- filter: ['all',
- ['!=', ['get', 'ref_multiline'], null],
- ['==', ['slice', ['get', 'feature'], 0, 20], 'de/blockkennzeichen-'],
- ],
- paint: {
- 'text-halo-color': ['case',
- ['boolean', ['feature-state', 'hover'], false], colors.hover.textHalo,
- 'white'
- ],
- 'text-halo-width': 2,
- },
- layout: {
- 'text-field': '{ref_multiline}',
- 'text-font': ['Noto Sans Bold'],
- 'text-size': 9,
- 'text-anchor': 'center',
- 'text-overlap': 'always',
- },
- },
- {
- id: 'railway_signals_text',
- type: 'symbol',
- minzoom: 13,
- source: 'openrailwaymap_signals',
- 'source-layer': 'signals_railway_signals',
- filter: ['all',
- ['!=', ['get', 'ref'], null],
- ['!=', ['get', 'feature'], ''],
- ['!=', ['slice', ['get', 'feature'], 0, 20], 'de/blockkennzeichen-'],
- ],
- paint: {
- 'text-halo-color': ['case',
- ['boolean', ['feature-state', 'hover'], false], colors.hover.textHalo,
- 'white'
- ],
- 'text-halo-width': 1.5,
- 'text-halo-blur': 1,
- },
- layout: {
- 'text-field': '{ref}',
- 'text-font': ['Noto Sans Medium'],
- 'text-size': 9,
- 'text-anchor': 'top',
- 'text-offset': ['case',
- ['==', ['get', 'main_height'], 'dwarf'], ['literal', [0, 1]],
- ['any',
- ['all',
- ['==', ['get', 'main_form'], 'light'],
- ['==', ['get', 'speed_limit_form'], 'light'],
- ],
- ['all',
- ['==', ['get', 'distant_form'], 'light'],
- ['==', ['get', 'speed_limit_form'], 'light'],
- ],
- ], ['literal', [0, 2]],
- ['literal', [0, 1.5]],
- ],
- }
- },
searchResults,
],
@@ -2695,7 +2697,7 @@ const layers = {
{
id: 'electrification_signals_direction',
type: 'symbol',
- minzoom: 16,
+ minzoom: 15,
source: 'openrailwaymap_electrification',
'source-layer': 'electrification_signals',
filter: ['all',
@@ -2729,12 +2731,26 @@ const layers = {
['get', 'feature'],
{
type: 'symbol',
- minzoom: 16,
+ minzoom: 15,
source: 'openrailwaymap_electrification',
'source-layer': 'electrification_signals',
+ paint: {
+ 'text-halo-color': ['case',
+ ['boolean', ['feature-state', 'hover'], false], colors.hover.textHalo,
+ 'white'
+ ],
+ 'text-halo-width': 1.5,
+ 'text-halo-blur': 1,
+ },
layout: {
'symbol-z-order': 'source',
'icon-overlap': 'always',
+ 'text-field': '{ref}',
+ 'text-font': ['Noto Sans Medium'],
+ 'text-size': 9,
+ 'text-optional': true,
+ 'text-anchor': 'top',
+ 'text-offset': ['literal', [0, 1.5]],
},
},
),
@@ -3404,6 +3420,239 @@ const layers = {
},
searchResults,
],
+
+ track_class: [
+ {
+ id: 'track_class_railway_line_low_casing',
+ type: 'line',
+ maxzoom: 7,
+ source: 'openrailwaymap_low',
+ 'source-layer': 'railway_line_low',
+ paint: trackClassCasingPaint,
+ layout: trackClassLayout,
+ },
+ {
+ id: 'track_class_railway_line_low_fill',
+ type: 'line',
+ maxzoom: 7,
+ source: 'openrailwaymap_low',
+ 'source-layer': 'railway_line_low',
+ paint: trackClassFillPaint([1]),
+ layout: trackClassLayout,
+ },
+ {
+ id: 'track_class_railway_line_med_casing',
+ type: 'line',
+ minzoom: 7,
+ maxzoom: 8,
+ source: 'openrailwaymap_med',
+ 'source-layer': 'railway_line_med',
+ paint: trackClassCasingPaint,
+ layout: trackClassLayout,
+ },
+ {
+ id: 'track_class_railway_line_med_fill',
+ type: 'line',
+ minzoom: 7,
+ maxzoom: 8,
+ source: 'openrailwaymap_med',
+ 'source-layer': 'railway_line_med',
+ paint: trackClassFillPaint([1]),
+ layout: trackClassLayout,
+ },
+ {
+ id: 'track_class_railway_line_casing',
+ type: 'line',
+ minzoom: 8,
+ source: 'high',
+ 'source-layer': 'railway_line_high',
+ filter: ['!=', ['get', 'railway'], 'construction'],
+ paint: trackClassCasingPaint,
+ layout: trackClassLayout,
+ },
+ {
+ id: 'track_class_railway_line_casing_construction',
+ type: 'line',
+ minzoom: 8,
+ source: 'high',
+ 'source-layer': 'railway_line_high',
+ filter: ['==', ['get', 'railway'], 'construction'],
+ paint: {
+ 'line-color': 'white',
+ 'line-width': railwayLineWidth,
+ 'line-gap-width': 0.75,
+ 'line-dasharray': gauge_construction_dashes,
+ },
+ },
+ {
+ id: 'track_class_railway_line_fill',
+ type: 'line',
+ minzoom: 8,
+ source: 'high',
+ 'source-layer': 'railway_line_high',
+ filter: ['!=', ['get', 'railway'], 'construction'],
+ paint: trackClassFillPaint([1]),
+ layout: trackClassLayout,
+ },
+ {
+ id: 'track_class_railway_line_fill_construction',
+ type: 'line',
+ minzoom: 8,
+ source: 'high',
+ 'source-layer': 'railway_line_high',
+ filter: ['==', ['get', 'railway'], 'construction'],
+ paint: trackClassFillPaint(gauge_construction_dashes),
+ layout: loadingGaugeLayout,
+ },
+ preferredDirectionLayer('railway_preferred_direction', ['any',
+ ['==', ['get', 'preferred_direction'], 'forward'],
+ ['==', ['get', 'preferred_direction'], 'backward'],
+ ['==', ['get', 'preferred_direction'], 'both'],
+ ]),
+ railwayKmText,
+ {
+ id: 'track_class_railway_text_high',
+ type: 'symbol',
+ minzoom: 8,
+ source: 'high',
+ 'source-layer': 'railway_line_high',
+ filter: ['step', ['zoom'],
+ ['all',
+ ['==', ['get', 'feature'], 'rail'],
+ ['any',
+ ['==', ['get', 'usage'], 'main'],
+ ['==', ['get', 'usage'], 'branch'],
+ ],
+ ['==', ['get', 'service'], null],
+ ],
+ 9,
+ ['all',
+ ['==', ['get', 'feature'], 'rail'],
+ ['any',
+ ['==', ['get', 'usage'], 'main'],
+ ['==', ['get', 'usage'], 'branch'],
+ ['==', ['get', 'usage'], 'industrial'],
+ ],
+ ['==', ['get', 'service'], null],
+ ],
+ 10,
+ ['any',
+ ['all',
+ ['==', ['get', 'feature'], 'rail'],
+ ['any',
+ ['==', ['get', 'usage'], 'main'],
+ ['==', ['get', 'usage'], 'branch'],
+ ],
+ ['==', ['get', 'service'], null],
+ ],
+ ['all',
+ ['==', ['get', 'feature'], 'rail'],
+ ['==', ['get', 'usage'], 'industrial'],
+ ],
+ ['all',
+ ['==', ['get', 'feature'], 'rail'],
+ ['==', ['get', 'usage'], null],
+ ['any',
+ ['==', ['get', 'service'], 'siding'],
+ ['==', ['get', 'service'], 'crossover'],
+ ['==', ['get', 'service'], 'spur'],
+ ],
+ ],
+ ['all',
+ ['==', ['get', 'feature'], 'narrow_gauge'],
+ ['any',
+ ['==', ['get', 'service'], null],
+ ['==', ['get', 'service'], 'siding'],
+ ['==', ['get', 'service'], 'crossover'],
+ ['==', ['get', 'service'], 'spur'],
+ ],
+ ],
+ ['all',
+ ['==', ['get', 'railway'], 'construction'],
+ ['==', ['get', 'feature'], 'rail'],
+ ['any',
+ ['==', ['get', 'usage'], 'main'],
+ ['==', ['get', 'usage'], 'branch'],
+ ],
+ ['==', ['get', 'service'], null],
+ ],
+ ],
+ 11,
+ ['any',
+ ['all',
+ ['==', ['get', 'feature'], 'rail'],
+ ['any',
+ ['==', ['get', 'usage'], 'main'],
+ ['==', ['get', 'usage'], 'branch'],
+ ],
+ ['==', ['get', 'service'], null],
+ ],
+ ['all',
+ ['==', ['get', 'railway'], 'rail'],
+ ['==', ['get', 'usage'], 'industrial'],
+ ],
+ ['all',
+ ['==', ['get', 'feature'], 'rail'],
+ ['==', ['get', 'usage'], null],
+ ['any',
+ ['==', ['get', 'service'], 'siding'],
+ ['==', ['get', 'service'], 'crossover'],
+ ['==', ['get', 'service'], 'spur'],
+ ['==', ['get', 'service'], 'yard'],
+ ],
+ ],
+ ['all',
+ ['==', ['get', 'feature'], 'narrow_gauge'],
+ ['any',
+ ['==', ['get', 'service'], null],
+ ['==', ['get', 'service'], 'siding'],
+ ['==', ['get', 'service'], 'crossover'],
+ ['==', ['get', 'service'], 'spur'],
+ ['==', ['get', 'service'], 'yard'],
+ ],
+ ],
+ ['all',
+ ['==', ['get', 'railway'], 'construction'],
+ ['==', ['get', 'feature'], 'rail'],
+ ['any',
+ ['==', ['get', 'usage'], 'main'],
+ ['==', ['get', 'usage'], 'branch'],
+ ['==', ['get', 'usage'], 'subway'],
+ ['==', ['get', 'usage'], 'light_rail'],
+ ],
+ ['==', ['get', 'service'], null],
+ ],
+ ['all',
+ ['any',
+ ['==', ['get', 'feature'], 'subway'],
+ ['==', ['get', 'feature'], 'light_rail'],
+ ],
+ ['==', ['get', 'service'], null],
+ ],
+ ],
+ 12,
+ true,
+ ],
+ paint: {
+ 'text-halo-color': ['case',
+ ['boolean', ['feature-state', 'hover'], false], colors.hover.textHalo,
+ 'white'
+ ],
+ 'text-halo-width': 1.5,
+ },
+ layout: {
+ 'symbol-z-order': 'source',
+ 'symbol-placement': 'line',
+ 'text-field': '{loading_gauge}',
+ // TODO not present: oblique font
+ 'text-font': ['Noto Sans Bold'],
+ 'text-size': 11,
+ 'text-padding': 30,
+ 'symbol-spacing': 250,
+ },
+ },
+ searchResults,
+ ],
};
const makeStyle = selectedStyle => ({
@@ -3940,6 +4189,7 @@ const legendData = {
type: 'point',
properties: {
zero: true,
+ pos_int: '47',
pos: '47.0',
},
},
@@ -4034,6 +4284,17 @@ const legendData = {
},
},
],
+ "high-railway_text_km": [
+ {
+ legend: 'Milestone',
+ type: 'point',
+ properties: {
+ zero: true,
+ pos_int: '47',
+ pos: '47.0',
+ },
+ },
+ ],
'openrailwaymap_speed-speed_railway_signals': [
// TODO filter per country polygon
...speed_railway_signals.features.map(feature => ({
@@ -4192,6 +4453,17 @@ const legendData = {
],
},
],
+ "high-railway_text_km": [
+ {
+ legend: 'Milestone',
+ type: 'point',
+ properties: {
+ zero: true,
+ pos_int: '47',
+ pos: '47.0',
+ },
+ },
+ ],
'openrailwaymap_signals-signals_railway_signals': [
...signals_railway_signals.features.map(feature => ({
legend: `${feature.country ? `(${feature.country}) ` : ''}${feature.description}`,
@@ -4442,6 +4714,17 @@ const legendData = {
},
},
],
+ "high-railway_text_km": [
+ {
+ legend: 'Milestone',
+ type: 'point',
+ properties: {
+ zero: true,
+ pos_int: '47',
+ pos: '47.0',
+ },
+ },
+ ],
'openrailwaymap_electrification-electrification_signals': [
...electrification_signals.features.map(feature => ({
legend: `(${feature.country}) ${feature.description}`,
@@ -4797,6 +5080,17 @@ const legendData = {
},
},
],
+ "high-railway_text_km": [
+ {
+ legend: 'Milestone',
+ type: 'point',
+ properties: {
+ zero: true,
+ pos_int: '47',
+ pos: '47.0',
+ },
+ },
+ ],
},
loading_gauge: {
'openrailwaymap_low-railway_line_low': [
@@ -4871,6 +5165,102 @@ const legendData = {
},
},
],
+ "high-railway_text_km": [
+ {
+ legend: 'Milestone',
+ type: 'point',
+ properties: {
+ zero: true,
+ pos_int: '47',
+ pos: '47.0',
+ },
+ },
+ ],
+ },
+ track_class: {
+ 'openrailwaymap_low-railway_line_low': [
+ ...track_classes.map(track_class => ({
+ legend: track_class.value,
+ type: 'line',
+ properties: {
+ track_class: track_class.value,
+ railway: 'rail',
+ feature: 'rail',
+ usage: 'main',
+ service: null,
+ },
+ })),
+ {
+ legend: '(unknown)',
+ type: 'line',
+ properties: {
+ track_class: null,
+ railway: 'rail',
+ feature: 'rail',
+ usage: 'main',
+ service: null,
+ },
+ },
+ ],
+ 'openrailwaymap_med-railway_line_med': [
+ ...track_classes.map(track_class => ({
+ legend: track_class.value,
+ type: 'line',
+ properties: {
+ track_class: track_class.value,
+ railway: 'rail',
+ feature: 'rail',
+ usage: 'main',
+ service: null,
+ },
+ })),
+ {
+ legend: '(unknown)',
+ type: 'line',
+ properties: {
+ track_class: null,
+ railway: 'rail',
+ feature: 'rail',
+ usage: 'main',
+ service: null,
+ },
+ },
+ ],
+ 'high-railway_line_high': [
+ ...track_classes.map(track_class => ({
+ legend: track_class.value,
+ type: 'line',
+ properties: {
+ track_class: track_class.value,
+ railway: 'rail',
+ feature: 'rail',
+ usage: 'main',
+ service: null,
+ },
+ })),
+ {
+ legend: '(unknown)',
+ type: 'line',
+ properties: {
+ track_class: null,
+ railway: 'rail',
+ feature: 'rail',
+ usage: 'main',
+ service: null,
+ },
+ },
+ ],
+ "high-railway_text_km": [
+ {
+ legend: 'Milestone',
+ type: 'point',
+ properties: {
+ zero: true,
+ pos_int: '47',
+ pos: '47.0',
+ },
+ },
+ ],
},
}
diff --git a/proxy/js/ui.js b/proxy/js/ui.js
index ff6e502f..cbf39adf 100644
--- a/proxy/js/ui.js
+++ b/proxy/js/ui.js
@@ -273,7 +273,7 @@ function removeDomElement(node) {
}
const globalMinZoom = 1;
-const globalMaxZoom = 18;
+const globalMaxZoom = 20;
const knownStyles = {
standard: 'Infrastructure',
@@ -282,6 +282,7 @@ const knownStyles = {
electrification: 'Electrification',
gauge: 'Gauge',
loading_gauge: 'Loading gauge',
+ track_class: 'Track class',
};
function hashToObject(hash) {
@@ -732,7 +733,7 @@ function popupContent(properties) {
${properties.tunnel === true ? `tunnel` : ''}
${properties.bridge === true ? `bridge` : ''}
${properties.railway_local_operated === true ? `operated locally` : ''}
- ${properties.maxspeed ? `maximum speed: ${properties.maxspeed} km/h` : ''}
+ ${properties.track_class ? `track class: ${properties.track_class}` : ''}
${properties.direction_both ? `both directions` : ''}
${properties.train_protection ? `train protection: ${properties.train_protection}` : ''}
${properties.deactivated === true ? `deactivated` : ''}
@@ -741,6 +742,8 @@ function popupContent(properties) {
${properties.speed_label ? `speed: ${properties.speed_label}` : ''}
${properties.voltage ? `voltage: ${properties.voltage} V` : ''}
${properties.frequency ? `frequency: ${properties.frequency.toFixed(2)} Hz` : ''}
+ ${properties.future_voltage ? `voltage (future): ${properties.future_voltage} V` : ''}
+ ${properties.future_frequency ? `frequency (future): ${properties.future_frequency.toFixed(2)} Hz` : ''}
${properties.gauge_label ? `gauge: ${properties.gauge_label}` : ''}
${properties.loading_gauge ? `loading gauge: ${properties.loading_gauge}` : ''}
diff --git a/proxy/test/ui/cypress/e2e/home.cy.js b/proxy/test/ui/cypress/e2e/home.cy.js
index e3a31a54..3c8c286c 100644
--- a/proxy/test/ui/cypress/e2e/home.cy.js
+++ b/proxy/test/ui/cypress/e2e/home.cy.js
@@ -39,6 +39,9 @@ describe('home page', () => {
cy.contains('Loading gauge').click()
cy.url().should('include', 'style=loading_gauge')
+ cy.contains('Track class').click()
+ cy.url().should('include', 'style=track_class')
+
cy.wait(3000)
cy.screenshot()
})
diff --git a/symbols/be/PBA.svg b/symbols/be/PBA.svg
new file mode 100644
index 00000000..21e9eb25
--- /dev/null
+++ b/symbols/be/PBA.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/symbols/be/PBE.svg b/symbols/be/PBE.svg
new file mode 100644
index 00000000..8a5936e8
--- /dev/null
+++ b/symbols/be/PBE.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/symbols/be/PRL.svg b/symbols/be/PRL.svg
new file mode 100644
index 00000000..9ed5f572
--- /dev/null
+++ b/symbols/be/PRL.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/symbols/ch/fdv-703.svg b/symbols/ch/fdv-703.svg
new file mode 100644
index 00000000..9795f57a
--- /dev/null
+++ b/symbols/ch/fdv-703.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/symbols/ch/fdv-704.svg b/symbols/ch/fdv-704.svg
new file mode 100644
index 00000000..be54ce30
--- /dev/null
+++ b/symbols/ch/fdv-704.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/symbols/ch/fdv-705.svg b/symbols/ch/fdv-705.svg
new file mode 100644
index 00000000..39c95044
--- /dev/null
+++ b/symbols/ch/fdv-705.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/symbols/ch/fdv-707.svg b/symbols/ch/fdv-707.svg
new file mode 100644
index 00000000..85b7cad3
--- /dev/null
+++ b/symbols/ch/fdv-707.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/symbols/ch/fdv-708.svg b/symbols/ch/fdv-708.svg
new file mode 100644
index 00000000..55887b7e
--- /dev/null
+++ b/symbols/ch/fdv-708.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/symbols/ch/fdv-709.svg b/symbols/ch/fdv-709.svg
new file mode 100644
index 00000000..44998e3a
--- /dev/null
+++ b/symbols/ch/fdv-709.svg
@@ -0,0 +1,10 @@
+
+
diff --git a/symbols/ch/fdv-710.svg b/symbols/ch/fdv-710.svg
new file mode 100644
index 00000000..8b2d8b04
--- /dev/null
+++ b/symbols/ch/fdv-710.svg
@@ -0,0 +1,8 @@
+
+
diff --git a/symbols/ch/fdv-711.svg b/symbols/ch/fdv-711.svg
new file mode 100644
index 00000000..54a05e1f
--- /dev/null
+++ b/symbols/ch/fdv-711.svg
@@ -0,0 +1,13 @@
+
+
diff --git a/symbols/ch/fdv-712.svg b/symbols/ch/fdv-712.svg
new file mode 100644
index 00000000..9e7d374e
--- /dev/null
+++ b/symbols/ch/fdv-712.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/symbols/ch/fdv-713.svg b/symbols/ch/fdv-713.svg
new file mode 100644
index 00000000..65bd81bb
--- /dev/null
+++ b/symbols/ch/fdv-713.svg
@@ -0,0 +1,13 @@
+
+
diff --git a/symbols/ch/fdv-714.svg b/symbols/ch/fdv-714.svg
new file mode 100644
index 00000000..a917a15d
--- /dev/null
+++ b/symbols/ch/fdv-714.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/symbols/ch/fdv-715.svg b/symbols/ch/fdv-715.svg
new file mode 100644
index 00000000..42b9dfb5
--- /dev/null
+++ b/symbols/ch/fdv-715.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/symbols/ch/fdv-716.svg b/symbols/ch/fdv-716.svg
new file mode 100644
index 00000000..4df8310c
--- /dev/null
+++ b/symbols/ch/fdv-716.svg
@@ -0,0 +1,38 @@
+
+
diff --git a/symbols/ch/fdv-717.1.svg b/symbols/ch/fdv-717.1.svg
new file mode 100644
index 00000000..26ce8506
--- /dev/null
+++ b/symbols/ch/fdv-717.1.svg
@@ -0,0 +1,9 @@
+
+
diff --git a/symbols/ch/fdv-717.svg b/symbols/ch/fdv-717.svg
new file mode 100644
index 00000000..8fcfe2d3
--- /dev/null
+++ b/symbols/ch/fdv-717.svg
@@ -0,0 +1,9 @@
+
+
diff --git a/symbols/ch/fdv-718.1.svg b/symbols/ch/fdv-718.1.svg
new file mode 100644
index 00000000..e20e75c1
--- /dev/null
+++ b/symbols/ch/fdv-718.1.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/symbols/ch/fdv-718.svg b/symbols/ch/fdv-718.svg
new file mode 100644
index 00000000..097fb5b0
--- /dev/null
+++ b/symbols/ch/fdv-718.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/symbols/ch/fdv-719.svg b/symbols/ch/fdv-719.svg
new file mode 100644
index 00000000..2989b21f
--- /dev/null
+++ b/symbols/ch/fdv-719.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/symbols/de/bostrab/f0.svg b/symbols/de/bostrab/f0.svg
index e960eb2a..bfa9d5cb 100644
--- a/symbols/de/bostrab/f0.svg
+++ b/symbols/de/bostrab/f0.svg
@@ -1,6 +1,6 @@