Skip to content

Commit 138e0a8

Browse files
authored
Signals: support multiple icons per feature (#657)
Part of #545 Requires decoupling the icon from the signal "feature". Goal: instead of duplicating the same signal features because they have similar tags but need different icons: ```yaml - description: 1ª categoria quadro (Avvio & Avanzamento) (1 light) country: IT icon: match: 'railway:signal:main:states' cases: - { any: ['(Y)', 'Y'], value: 'it/main-s-1v-AVV-AVA-Y' } - { exact: 'G', value: 'it/main-s-1v-AVV-AVA-G' } default: 'it/main-s-1v-AVV-AVA-R' tags: - { tag: 'railway:signal:main', value: 'IT:1V' } - { tag: 'railway:signal:main:form', value: 'light' } - { tag: 'railway:signal:main:shape', value: 'square' } - { tag: 'railway:signal:main:substitute_signal', all: ['IT:AVA', 'IT:AVV'] } - description: 1ª categoria quadro (Avanzamento) (1 light) country: IT icon: match: 'railway:signal:main:states' cases: - { any: ['(Y)', 'Y'], value: 'it/main-s-1v-AVA-Y' } - { exact: 'G', value: 'it/main-s-1v-AVA-G' } default: 'it/main-s-1v-AVA-R' tags: - { tag: 'railway:signal:main', value: 'IT:1V' } - { tag: 'railway:signal:main:form', value: 'light' } - { tag: 'railway:signal:main:shape', value: 'square' } - { tag: 'railway:signal:main:substitute_signal', value: 'IT:AVA' } ``` instead, allow multiple icons, composed with each other: ```yaml - description: 1ª categoria quadro (1 light) country: IT icon: - default: 'it/main-1v-s' - match: 'railway:signal:main:states' cases: - { any: ['(Y)', 'Y'], value: 'it/1v-Y' } - { exact: 'G', value: 'it/1v-G' } - { exact: 'R', value: 'it/1v-R' } - match: 'railway:signal:main:substitute_signal' cases: - { all: ['IT:AVA', 'IT:AVV'], value: 'it/AVV-AVA', description: 'Avvio & Avanzamento' } - { exact: 'IT:AVA', value: 'it/AVA', description: 'Avanzamento' } - { exact: 'IT:AVV', value: 'it/AVV', description: 'Avvio' } tags: - { tag: 'railway:signal:main', value: 'IT:1V' } - { tag: 'railway:signal:main:form', value: 'light' } - { tag: 'railway:signal:main:shape', value: 'square' } ``` (this example is only combining 2 signals, the Italian signals will have more variants composed together) For a full example, see #639 which has huge duplication because of the large variety in tagging. (A good thing, but currently the YAML configuration does not support such use cases well.) This requires changes in many different places: - [x] UI icon map rendering #656 - [x] Icon size determination - [x] Signal feature SQL - [x] YAML signal configuration - [x] Taginfo - [x] JOSM preset - [x] Documentation - [x] Signal feature performance - [x] Duplicated features in popup - [x] Make offsets work - [x] Split off commit 66a7eae into separate PR --> #659
1 parent e3bfc37 commit 138e0a8

File tree

8 files changed

+2483
-2123
lines changed

8 files changed

+2483
-2123
lines changed

CONTRIBUTING.md

Lines changed: 75 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ For example, to match railway signals with tags `railway:signal:shunting=AT-V2:v
4141
features:
4242
- description: Verschubhalttafel
4343
country: AT
44-
icon: { default: 'at/verschubhalttafel' }
44+
icon: [ default: 'at/verschubhalttafel' ]
4545
tags:
4646
- { tag: 'railway:signal:shunting', value: 'AT-V2:verschubhalttafel' }
4747
- { tag: 'railway:signal:shunting:form', value: 'sign' }
@@ -53,15 +53,15 @@ features:
5353
- description: train protection block markers
5454
country: BE
5555
icon:
56-
match: 'railway:signal:position'
57-
cases:
58-
- exact: 'left'
59-
value: 'be/PRA-arrow-right'
60-
description: 'left'
61-
- exact: 'overhead'
62-
value: 'be/PRA-arrow-down'
63-
description: 'overhead'
64-
default: 'be/PRA-arrow-left'
56+
- match: 'railway:signal:position'
57+
cases:
58+
- exact: 'left'
59+
value: 'be/PRA-arrow-right'
60+
description: 'left'
61+
- exact: 'overhead'
62+
value: 'be/PRA-arrow-down'
63+
description: 'overhead'
64+
default: 'be/PRA-arrow-left'
6565
tags:
6666
- { tag: 'railway:signal:train_protection', value: 'BE:PRA' }
6767
- { tag: 'railway:signal:train_protection:form', value: 'sign' }
@@ -75,10 +75,10 @@ features:
7575
- description: Signalnachahmer
7676
country: AT
7777
icon:
78-
match: 'railway:signal:main_repeated:magnet'
79-
cases:
80-
- { value: 'at/signalnachahmer-magnet', description: '1000Hz magnet' }
81-
default: 'at/signalnachahmer'
78+
- match: 'railway:signal:main_repeated:magnet'
79+
cases:
80+
- { value: 'at/signalnachahmer-magnet', description: '1000Hz magnet' }
81+
default: 'at/signalnachahmer'
8282
tags:
8383
- { tag: 'railway:signal:main_repeated', value: 'AT-V2:signalnachahmer' }
8484
- { tag: 'railway:signal:main_repeated:form', value: 'light' }
@@ -96,12 +96,12 @@ features:
9696
- description: distant (light)
9797
country: AT
9898
icon:
99-
match: 'railway:signal:distant:states'
100-
cases:
101-
- { exact: 'AT-V2:hauptsignal_frei_mit_60', value: 'at/vorsignal-frei-mit-60', description: '60 km/h' }
102-
- { any: ['AT-V2:hauptsignal_frei_mit_40', 'AT-V2:hauptsignal_frei_mit_20'], value: 'at/vorsignal-frei-mit-40', description: '20/40 km/h' }
103-
- { exact: 'AT-V2:hauptsignal_frei', value: 'at/vorsignal-frei', description: 'clear' }
104-
default: 'at/vorsignal-vorsicht'
99+
- match: 'railway:signal:distant:states'
100+
cases:
101+
- { exact: 'AT-V2:hauptsignal_frei_mit_60', value: 'at/vorsignal-frei-mit-60', description: '60 km/h' }
102+
- { any: ['AT-V2:hauptsignal_frei_mit_40', 'AT-V2:hauptsignal_frei_mit_20'], value: 'at/vorsignal-frei-mit-40', description: '20/40 km/h' }
103+
- { exact: 'AT-V2:hauptsignal_frei', value: 'at/vorsignal-frei', description: 'clear' }
104+
default: 'at/vorsignal-vorsicht'
105105
tags:
106106
- { tag: 'railway:signal:distant', value: 'AT-V2:vorsignal' }
107107
- { tag: 'railway:signal:distant:form', value: 'light' }
@@ -113,11 +113,11 @@ features:
113113
- description: Semafor kształtowy
114114
country: PL
115115
icon:
116-
match: 'railway:signal:main:states'
117-
cases:
118-
- { exact: 'PL-PKP:sr3', value: 'pl/sr3' }
119-
- { all: ['PL-PKP:sr1', 'PL-PKP:sr2'], value: 'pl/sr2' }
120-
default: 'pl/sr1'
116+
- match: 'railway:signal:main:states'
117+
cases:
118+
- { exact: 'PL-PKP:sr3', value: 'pl/sr3' }
119+
- { all: ['PL-PKP:sr1', 'PL-PKP:sr2'], value: 'pl/sr2' }
120+
default: 'pl/sr1'
121121
tags:
122122
- { tag: 'railway:signal:main', value: 'PL-PKP:sr' }
123123
- { tag: 'railway:signal:main:form', value: 'semaphore' }
@@ -129,26 +129,70 @@ features:
129129
- description: Geschwindigkeitsvoranzeiger (light)
130130
country: AT
131131
icon:
132-
match: 'railway:signal:speed_limit_distant:speed'
133-
cases:
134-
- { regex: '^(1[0-4]|[2-9])0$', value: 'at/geschwindigkeitsvoranzeiger-light-{}', example: 'at/geschwindigkeitsvoranzeiger-light-{140}' }
135-
default: 'at/geschwindigkeitsvoranzeiger-empty-light'
132+
- match: 'railway:signal:speed_limit_distant:speed'
133+
cases:
134+
- { regex: '^(1[0-4]|[2-9])0$', value: 'at/geschwindigkeitsvoranzeiger-light-{}', example: 'at/geschwindigkeitsvoranzeiger-light-{140}' }
135+
default: 'at/geschwindigkeitsvoranzeiger-empty-light'
136136
tags:
137137
- { tag: 'railway:signal:speed_limit_distant', value: 'AT-V2:geschwindigkeitsvoranzeiger' }
138138
- { tag: 'railway:signal:speed_limit_distant:form', value: 'light' }
139139
```
140140
Note that the icon files will also contain the `{` and `}` characters, the filename will be for example `at/geschwindigkeitsvoranzeiger-light-{80}.svg`.
141141

142+
Signal features can use multiple icons by specifying more than one item for `icon`:
143+
```yaml
144+
features:
145+
- description: 1ª categoria (1 light)
146+
country: IT
147+
icon:
148+
- match: 'railway:signal:main:shape'
149+
cases:
150+
- { exact: 'square', value: 'it/main-s-1v', description: 'quadro' }
151+
default: 'it/main-1v'
152+
- match: 'railway:signal:main:states'
153+
cases:
154+
- { any: [ '(Y)', 'Y' ], value: "it/1v-Y" }
155+
- { exact: 'G', value: "it/1v-G" }
156+
default: "it/1v-R"
157+
- match: 'railway:signal:main:substitute_signal'
158+
cases:
159+
- { all: ['IT:AVA', 'IT:AVV'], value: 'it/AVV-AVA', description: 'Avvio & Avanzamento' }
160+
- { exact: 'IT:AVA', value: 'it/AVA', description: 'Avanzamento' }
161+
- { exact: 'IT:AVV', value: 'it/AVV', description: 'Avvio' }
162+
position: 'bottom'
163+
tags:
164+
- { tag: 'railway:signal:main', value: 'IT:1V' }
165+
- { tag: 'railway:signal:main:form', value: 'light' }
166+
```
167+
In this example the shape, the states, and the substitute signal each define an (optional) icon to use. The icons are composed together, starting with the first one and layering every following icon on top. The (optional) `default` icon is used if the `match` cases do not match.
168+
169+
The icons can have an `position` with a value of `center` (default), `bottom`, `top`, `left` or `right` to determine where the icon will be placed in relation to the previously placed icons. When an icon is placed below, above, left or right of the other icons, the icon is centered along the other axis.
170+
171+
For complex signals, an additional property `exampleIcon` can be specified to designate an icon used for the feature as a whole, for example in the JOSM preset or TagInfo.
172+
```yaml
173+
features:
174+
- description: Geschwindigkeitsvoranzeiger
175+
country: AT
176+
icon:
177+
- match: ...
178+
- match: ...
179+
- match: ...
180+
exampleIcon: 'at/geschwindigkeitsvoranzeiger-example'
181+
tags:
182+
- ...
183+
- ...
184+
```
185+
142186
If the railway signal uses tags that are not in the list at the top of the file, ensure the tag is added there. For example:
143187
```yaml
144188
tags:
145189
# ...
146-
- { tag: 'railway:signal:combined:form' }
190+
- { tag: 'railway:signal:combined:form', title: 'Combined form' }
147191
# ...
148192
```
149193
If the tag has a `yes`/`no` value, add `type: boolean`. If the tag has a semicolon (`;`) separated value, add `type: array`. If the value of the tag should be displayed formatted or with a unit, add `format: { template: ... }` where the value is a template like `%.2d Hz` or `%s V` to format the tag value into a string for display in the popup.
150194

151-
Next, ensure the icon exists in the [symbols directory](https://github.com/hiddewie/OpenRailwayMap-vector/tree/master/symbols). The icon must be an SVG file, minified and of the correct dimensions (most icons are between 10 and 24 pixels wide / high).
195+
Next, ensure the icon exists in the [symbols directory](https://github.com/hiddewie/OpenRailwayMap-vector/tree/master/symbols). The icon must be an SVG file, minified and of the correct dimensions (most icons are between 10 and 24 pixels wide / high). Icons with an even number of pixels in the width and height give the best visual results.
152196

153197
The icon must not contain text. Using an SVG tool, convert the text to the shape of the text. In Inkscape, use the menu item *Path* > *Object to Path*.
154198

0 commit comments

Comments
 (0)