#64: transit design — unique_icon stations, network-specific badge sprites, docs #65

Merged
art merged 2 commits from issue-64-transit-design into main 2026-08-05 20:19:38 +00:00
Owner

Transit design — first tranche: the unique_icon mechanism, docs, and the icon renames

Issue #64 overrides the per-city transit issues (#24/#25/#38/#63): the design was
missing while the details were being micromanaged. This PR lands the design's
cross-country backbone — the schema/style change every transit network will hang
off — plus the per-country transit documentation the issue asks for first. The heavy
per-country data expansion (importing every city's networks from national sources) is
the follow-up, documented at the bottom.

What the design says, and what this PR does

  1. Icon selection is by unique_icon, never by mode. mode only says
    metro/tram/commuter; a network's iconic symbol is a property of that network.
    The shared stations contract gains a nullable unique_icon text column
    (conf/common.yaml); the style's station_icons layer now filters ["has", "unique_icon"] and selects icon-image: ["get", "unique_icon"], and
    station_dots renders anything without one (html/style.json). A station with
    no symbol renders as the plain dot, which is the correct default for tram,
    heavy rail, and any network that has no logotype.

  2. Sprite names are network-specific, not mode labels. The Stockholm badges are
    renamed metrostockholm-metro (the T) and commuter
    stockholm-commuter (the J), in mapsrv/sprite.go and the SVG files
    themselves (mapsrv/icons/), with icons/README.md documenting the naming rule.
    This fixes the PR #50 bug the issue calls out: the style asked for a sprite
    called metro while the icon was rail-metro, and the mode-based selection
    could never scale past two networks. A future badge (e.g. warszawa-metro) joins
    the list under its own name with no style change.

  3. SE populates it; PL/FI deliberately don't. Sweden's stations query emits
    stockholm-metro/stockholm-commuter for its metro and pendeltåg stops
    (conf/semap.yaml); Poland's tram stops and Finland's railway traffic sites emit
    NULL — no iconic symbol exists for them, and the issue says use the symbol only
    when there is one. Reimported all three countries' stations partitions against
    the live DB (the ALTER'd parent carries the new column through every partition).

Docs (the issue's point 4, and its "docs first" instruction)

  • docs/country-iceland.md — new Transit section: nothing exists (no rail, no
    metro/tram/funicular; Strætó buses are out of the issue's scope) — the "write it
    down even when there's nothing" case, done explicitly.
  • docs/country-sweden.md / docs/country-poland.md / docs/country-finland.md
    the station-badge paragraphs now describe the unique_icon scheme; the stale
    "sprite names equal the mode enum" and "M icon" claims are gone.
  • docs/style.md — the station-icon paragraph rewritten for the network-specific
    naming; docs/workstream-a.md — catalogue rows updated (se_gtfs row now notes
    the national feed covers Gothenburg/Norrköping/Malmö trams, PL work-list item 3
    updated to the unique_icon scheme).

Verification (all against the live DB)

  • make build; go test ./... in importer/ and mapsrv/ — pass.
  • gl-style-validate html/style.json — clean.
  • Reimported stations for SE/PL/FI (single-layer import each; the SE GTFS
    staging re-streams the feed). Live counts unchanged: SE 2059 (100 metro, 55
    commuter, 309 tram, 1595 rail — all named), PL 324 tram, FI 559 (383 named;
    the 176 unnamed are junctions/loops by the documented register rule).
  • unique_icon distribution in map_stations_14_se: exactly 100
    stockholm-metro + 55 stockholm-commuter, 0 NULL-count; PL/FI 0 — as designed.
  • Decoded the z15 tile holding Ropsten: the metro feature carries
    unique_icon='stockholm-metro', tram/rail features none.
  • Real-browser check (CDP, no virtual time): at z15 over Ropsten,
    station_icons renders the T badge (spriteLoaded: true, feature
    unique_icon='stockholm-metro'), tram/rail render as dots; local vision model
    confirms the dark-blue T badge at the station.

Left for the per-country delegation (the issue's own next step)

The issue says to delegate per country after the docs; the heavy data work this PR
does NOT do, now that the mechanism is in place:

  • PL: the national BDOT10k track already carries every city's tram/metro lines;
    stops exist only for Warszawa (ZTM). Per the capital + two biggest rule: Kraków
    and Łódź GTFS feeds next; Warszawa metro badge (warszawa-metro) when ZTM adds
    metro to the feed; commuter reach question still open (#63).
  • FI: metro/tram track is national (MTK); stops are not imported — DR_PYSAKKI
    (Digiroad) is the documented source, and no Finnish network has a logotype so
    unique_icon stays NULL by design.
  • SE: complete — national GTFS covers all cities' metro/tram/commuter stops.
  • Funiculars/cable cars: none exist in our four countries' transit sources; noted
    in the country docs where relevant (Iceland's Transit section spells this out).
# Transit design — first tranche: the `unique_icon` mechanism, docs, and the icon renames Issue #64 overrides the per-city transit issues (#24/#25/#38/#63): the design was missing while the details were being micromanaged. This PR lands the design's **cross-country backbone** — the schema/style change every transit network will hang off — plus the per-country transit documentation the issue asks for first. The heavy per-country data expansion (importing every city's networks from national sources) is the follow-up, documented at the bottom. ## What the design says, and what this PR does 1. **Icon selection is by `unique_icon`, never by `mode`.** `mode` only says metro/tram/commuter; a network's iconic symbol is a property of that network. The shared `stations` contract gains a nullable `unique_icon` text column (`conf/common.yaml`); the style's `station_icons` layer now filters `["has", "unique_icon"]` and selects `icon-image: ["get", "unique_icon"]`, and `station_dots` renders anything without one (`html/style.json`). A station with no symbol renders as the plain dot, which is the correct default for tram, heavy rail, and any network that has no logotype. 2. **Sprite names are network-specific, not mode labels.** The Stockholm badges are renamed `metro` → **`stockholm-metro`** (the T) and `commuter` → **`stockholm-commuter`** (the J), in `mapsrv/sprite.go` and the SVG files themselves (`mapsrv/icons/`), with `icons/README.md` documenting the naming rule. This fixes the PR #50 bug the issue calls out: the style asked for a sprite called `metro` while the icon was `rail-metro`, and the mode-based selection could never scale past two networks. A future badge (e.g. `warszawa-metro`) joins the list under its own name with no style change. 3. **SE populates it; PL/FI deliberately don't.** Sweden's stations query emits `stockholm-metro`/`stockholm-commuter` for its metro and pendeltåg stops (`conf/semap.yaml`); Poland's tram stops and Finland's railway traffic sites emit NULL — no iconic symbol exists for them, and the issue says use the symbol only when there is one. Reimported all three countries' stations partitions against the live DB (the ALTER'd parent carries the new column through every partition). ## Docs (the issue's point 4, and its "docs first" instruction) - `docs/country-iceland.md` — new **Transit** section: nothing exists (no rail, no metro/tram/funicular; Strætó buses are out of the issue's scope) — the "write it down even when there's nothing" case, done explicitly. - `docs/country-sweden.md` / `docs/country-poland.md` / `docs/country-finland.md` — the station-badge paragraphs now describe the `unique_icon` scheme; the stale "sprite names equal the mode enum" and "M icon" claims are gone. - `docs/style.md` — the station-icon paragraph rewritten for the network-specific naming; `docs/workstream-a.md` — catalogue rows updated (`se_gtfs` row now notes the national feed covers Gothenburg/Norrköping/Malmö trams, PL work-list item 3 updated to the `unique_icon` scheme). ## Verification (all against the live DB) - `make build`; `go test ./...` in importer/ and mapsrv/ — pass. - `gl-style-validate html/style.json` — clean. - Reimported `stations` for SE/PL/FI (single-layer import each; the SE GTFS staging re-streams the feed). Live counts unchanged: SE 2059 (100 metro, 55 commuter, 309 tram, 1595 rail — all named), PL 324 tram, FI 559 (383 named; the 176 unnamed are junctions/loops by the documented register rule). - `unique_icon` distribution in `map_stations_14_se`: exactly 100 `stockholm-metro` + 55 `stockholm-commuter`, 0 NULL-count; PL/FI 0 — as designed. - Decoded the z15 tile holding Ropsten: the metro feature carries `unique_icon='stockholm-metro'`, tram/rail features none. - Real-browser check (CDP, no virtual time): at z15 over Ropsten, `station_icons` renders the T badge (`spriteLoaded: true`, feature `unique_icon='stockholm-metro'`), tram/rail render as dots; local vision model confirms the dark-blue T badge at the station. ## Left for the per-country delegation (the issue's own next step) The issue says to delegate per country after the docs; the heavy data work this PR does NOT do, now that the mechanism is in place: - **PL**: the national BDOT10k track already carries every city's tram/metro lines; stops exist only for Warszawa (ZTM). Per the capital + two biggest rule: Kraków and Łódź GTFS feeds next; Warszawa metro badge (`warszawa-metro`) when ZTM adds metro to the feed; commuter reach question still open (#63). - **FI**: metro/tram track is national (MTK); stops are not imported — DR_PYSAKKI (Digiroad) is the documented source, and no Finnish network has a logotype so `unique_icon` stays NULL by design. - **SE**: complete — national GTFS covers all cities' metro/tram/commuter stops. - Funiculars/cable cars: none exist in our four countries' transit sources; noted in the country docs where relevant (Iceland's Transit section spells this out).
The design issue that overrides the per-city transit issues: icon selection
moves off `mode` onto a new `unique_icon` attribute on the shared stations
layer, named after the NETWORK a badge belongs to. Stockholm's badges become
`stockholm-metro` (the T) and `stockholm-commuter` (the J) in both the data
and the sprite sheet — fixing PR #50's style, which asked for a sprite called
`metro` while the icon was `rail-metro` and could never scale past two
networks. Tram, heavy-rail and any network without a logotype keep NULL and
render as the plain dot.

- conf/common.yaml: stations contract gains nullable `unique_icon` text
- conf/semap.yaml: SE emits stockholm-metro/stockholm-commuter; PL/FI NULL
  (no iconic symbol exists for Warsaw trams or Finnish rail sites)
- mapsrv: sprites renamed metro→stockholm-metro, commuter→stockholm-commuter
  (sprite.go + the SVG files), icons/README documents the naming rule
- html/style.json: station_icons selects by ["has","unique_icon"] +
  ["get","unique_icon"]; station_dots draws everything without one
- docs: transit situation written down per country (Iceland's "nothing
  exists" explicitly), style.md icon scheme, workstream-a catalogue rows

Verified against the live DB: build + tests pass, gl-style-validate clean,
stations reimported for SE/PL/FI (counts unchanged; SE 100 metro + 55
commuter carry unique_icon), Ropsten's z15 tile carries
unique_icon='stockholm-metro', and a real-browser CDP run renders the T
badge at Ropsten with tram/rail as dots.

Co-Authored-By: Hermes Agent <noreply@nousresearch.com>
The #25 badges were wrong: the "metro" icon was Maki's generic rail-metro
(a metro-car silhouette whose T-shaped window passed for a T) and the
"commuter" icon was a box with an invisible J — the letter was a black
stroke on a black fill, so the single-alpha tint pipeline flattened it
away entirely. Neither was the symbol its name promised.

Both are now the actual signs, from Wikimedia Commons (public domain),
rendered in their own colours:

- stockholm-metro: the tunnelbana's white disc with the navy ring and T
  (Stockholm metro symbol.svg)
- stockholm-commuter: pendeltåg's black J between two grey bars
  (Stockholm Pendeltag Logo.svg)

The sprite pipeline gains a `colored` icon mode (icon.go / sprite.go):
brand marks carry their colours in the SVG, so tinting them to a single
stationBlue destroys them. Colored icons are un-premultiplied to straight
RGBA for the sheet; the Maki POI icons stay on the tint path.

Verified: build + tests pass; the sprite sheet carries the two badges in
their real colours; browser check at z16 shows the T at Ropsten and the
J at Skogås (queryRenderedFeatures + local vision model).

Co-Authored-By: Hermes Agent <noreply@nousresearch.com>
Author
Owner

Follow-up on review: the station badges were wrong, and the #25 commit message lied about it. The "metro" sprite was Maki's generic rail-metro — a metro-car silhouette whose T-shaped window read as a T — and the "commuter" sprite was a box with an invisible J: the letter was a black stroke on a black fill, and the sprite pipeline's single-alpha tint flattened it to nothing. Neither was the symbol its name promised.

Both are now the actual network signs, public domain from Wikimedia Commons, rendered in their own colours (the pipeline gains a colored icon mode so brand marks are not tinted to one stationBlue):

  • stockholm-metro: the tunnelbana's white disc, navy ring, navy T
  • stockholm-commuter: pendeltåg's black J between two grey bars

Verified against the live server: the sprite sheet carries both badges in their real colours, and a z16 browser check shows the T at Ropsten and the J at Skogås (queryRenderedFeatures + the local vision model, which describes exactly the white-disc-navy-T and grey-bars-black-J signs).

Follow-up on review: the station badges were wrong, and the #25 commit message lied about it. The "metro" sprite was Maki's generic rail-metro — a metro-car silhouette whose T-shaped window read as a T — and the "commuter" sprite was a box with an invisible J: the letter was a black stroke on a black fill, and the sprite pipeline's single-alpha tint flattened it to nothing. Neither was the symbol its name promised. Both are now the actual network signs, public domain from Wikimedia Commons, rendered in their own colours (the pipeline gains a `colored` icon mode so brand marks are not tinted to one stationBlue): - stockholm-metro: the tunnelbana's white disc, navy ring, navy T - stockholm-commuter: pendeltåg's black J between two grey bars Verified against the live server: the sprite sheet carries both badges in their real colours, and a z16 browser check shows the T at Ropsten and the J at Skogås (queryRenderedFeatures + the local vision model, which describes exactly the white-disc-navy-T and grey-bars-black-J signs).
art merged commit 9a3b9a4655 into main 2026-08-05 20:19:38 +00:00
art deleted branch issue-64-transit-design 2026-08-05 20:19:38 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
art/ismap!65
No description provided.