#81: Finland's stations get their importance-3 rung, and Helsinki's metro its stops #99

Merged
art-bot merged 2 commits from issue-81-fi-stations into main 2026-08-13 05:07:11 +00:00
Owner

Closes #81


Finland's stations get their importance-3 rung, and Helsinki's metro its stops

What and why

Two R-failures from the #77 audit, both fixed in the stations layer
(conf/fimap.yaml):

1. The empty importance-3 rung (R75/R76). Finland's only station-importance signal
was name-present-vs-absent, which fills rungs 1 and 2 and can never reach 3 — so
map_stations_9_fi was an empty partition and Finland's stations started at z11 next
to Sweden's z9. This is exactly #68, which Poland's note said would generalize. The
recipe, applied: a rail station is importance 3 iff it is the principal station of a
city the MML register prints at its top display tier
— kohdeluokka 48111/48112,
the large-font towns the places layer scores 3, from the same fi_paikannimi_cl
staging table (same staging, same "which places matter" judgement). The principal is
the station named exactly after the town, one per town via DISTINCT ON (every
matched town has exactly one such station, so the dedupe is a guard, not a choice).
112 towns match (the #68 note's "69 sites" was measured without the R94 casing
normalisation; with it, and with both 48111+48112 as the top tier the way places
scores them, the count is 112). The station-name side of the match needed the R94
casing normalisation the places/railways layers already apply — the 14201 register
stores most rows in capitals — so the rail branch now initcaps all-caps register
names (HELSINKI → Helsinki), which also fixes the shouting labels the layer used to
emit. Tram 1, metro 2, rail 2/3 as before; only the rung-3 derivation is new.

2. Metro lines with no metro stations (R70), and the R6 answer. The stops were
never unavailable — MTK's own rautatieliikennepaikka class carries 25 of them
(Kamppi, Ruoholahti, Rautatientori, Tapiola, …: all 25 lie within 100 EPSG:3857
units of a metro segment, next nearest site is Helsinki main at 335, so a 200-unit
cut separates them cleanly) — but the class stops at Matinkylä: Finnoo, Kaitaa,
Soukka, Espoonlahti and Kivenlahti (open since 2022-12, and present as 14201
labels) have no 14200 site even in the April 2025 vintage. Checked against the
full product lists per R6: MML's Maastotietokanta has no more metro sites than the
theme file we already fetch; HSL's GTFS (the Helsinki region authority's official
static timetable, https://infopalvelut.storage.hsldev.com/gtfs/hsl.zip, open data
CC BY 4.0) has every station. So the new source is HSL's GTFS: a downloads: entry
(the ?download=1 trick keeps the zip whole, as with Poland's feeds), a
fi_gtfs_metro_stops staging table via the existing GTFS stops loader (route_type 1,
platforms collapsed to parent stations), and a metro branch in the stations query.
All 30 metro stations now import. The 25 MTK metro sites are excluded from the rail
branch (NOT EXISTS against a 14131 segment within 200 units) rather than re-labelled,
so no station draws twice — 0 rail rows sit within 200 units of a metro line after the
reimport.

HSL supplies the geometry, the register supplies the name (review fix, commit 2).
The feed's stop names are operational rather than cartographic: every one reads
"<town>n metroasema" — a genitive stem plus the words "metro station" — so taking
them verbatim labelled all 30 stations "Kampin metroasema", "Rautatientorin
metroasema", where Stockholm draws Karlaplan and Warszawa Centrum, in a form that
does not even match the place name beside it. The metro branch therefore runs the
same 14201 register lookup the rail branch runs, anchored on the HSL point instead
of the MTK site, and all 30 resolve: Kampin metroasema → Kamppi, Kivenlahden
metroasema → Kivenlahti, Koivusaaren metroasema → Koivusaari. A name join rather
than a suffix strip, because stripping " metroasema" would leave the genitive
("Kampin"). COALESCE keeps the feed name as the fallback for a station opened before
the register catches up; it fires on nothing today.

R74, documented rather than guessed. 176 of the 559 traffic sites had no register
name before this issue; after it, 175 — Koivusaari's MTK site is one of the 25 the
metro exclusion removes, and its HSL point finds the register's "Koivusaari" label. The
country doc now states what they are: MTK operating points the 14201 register does
not label — junctions, passing loops and goods yards, the same population as the
named ", TAVARA" sites (Hanko, Tavara; Hyvinkää, Tavara — "tavara" is Finnish for
goods). Genuinely unnamed source features, not a dropped-name bug.

Verification (live DB, after -layer stations reimport)

  • SELECT importance, count(*) FROM map_stations_14_fi GROUP BY 1 → 1:463, 2:277,
    3:112 — no gap 1..3 (the issue's acceptance query).
  • map_stations_9_fi → 112 (was 0), one principal per top-tier town; z9 tile over
    Helsinki decodes to Helsinki/Espoo/Kauniainen; z10/z11 389, z12+ 852.
  • Metro: map_stations_14_fi mode='metro' → 30 rows, min distance to the metro
    line 0.23 units, max 131 (all on the line); 0 rail rows within 200 units of a metro
    segment (no double-draw); 0 NULL importance; no NULL names in metro/tram, 175 NULL
    in rail (the documented R74 set); partitions present at z9–z14.
  • Decoded z11 tile over Helsinki (11/1165/592): 28 station features — 16 rail + 12
    metro, 0 names carrying "metroasema", the register names present (Kamppi,
    Koivusaari, Keilaniemi, Hakaniemi …) alongside the rail ones (Helsinki, Ilmala,
    Huopalahti …).
  • Real-browser CDP render (scripts/cdp-map-check.mjs, never virtual time): z9 over
    Helsinki draws 8 station_dots (all rail, the principals); z11 draws 40 dots — 22
    metro + 18 rail — with 3 metro labels placed; the blue metro dots sit on the blue
    metro line.
  • se/pl untouched: map_stations_14 2059/4052, map_stations_9 485/60, same as
    before the reimport.
  • make build, go test ./... importer/ + mapsrv/ green; git diff --check clean.

Left undone / notes for the reviewer

  • The one new fetch (HSL GTFS, 57 MB) went through the importer's declared-downloads
    path; the file is cached with a .fetchmeta sidecar like every other download.
  • Metro names come from the 14201 register, not the feed (see above). Two consequences,
    both recorded in docs/country-finland.md:
    • three Finnish stations now share a name across modes — Hakaniemi and Rautatientori
      (metro + tram, 150 m and 290 m apart, genuine interchanges) and Vuosaari (metro
      station vs harbour goods yard, 2.6 km apart, genuinely two places). Sweden already
      has 107 such pairs, so this is the house pattern, not a collision to fix.
    • the documented initcap limit is now visible on two metro labels, "Aalto-Yliopisto"
      and "Helsingin Yliopisto", where Finnish wants a lower-case second word. 47 of the
      register's all-caps 14201 labels are multi-word and so exposed to it. Fixing it
      needs Finnish-aware casing rules and would touch places and railways too, so it
      stays one documented limit of the shared R94 idiom rather than a per-layer patch.
  • The Helsinki main station stays rail (335 units from the metro tunnel — the
    register's own HELSINKI site); metro stations are rung 2 like Sweden's and
    Poland's, so they draw from z11, not z9.
  • Finland's unique_icon stays NULL (R72) — no network badge, plain dots, unchanged.
  • Not touched: the commuter-rail reach question (#63), rail_class branch (#69's
    Väylä rail data), bus stops (future bus-stop layer).
Closes #81 --- # Finland's stations get their importance-3 rung, and Helsinki's metro its stops ## What and why Two R-failures from the #77 audit, both fixed in the `stations` layer (`conf/fimap.yaml`): **1. The empty importance-3 rung (R75/R76).** Finland's only station-importance signal was name-present-vs-absent, which fills rungs 1 and 2 and can never reach 3 — so `map_stations_9_fi` was an empty partition and Finland's stations started at z11 next to Sweden's z9. This is exactly #68, which Poland's note said would generalize. The recipe, applied: a rail station is importance 3 iff it is the **principal station of a city the MML register prints at its top display tier** — `kohdeluokka 48111/48112`, the large-font towns the `places` layer scores 3, from the same `fi_paikannimi_cl` staging table (same staging, same "which places matter" judgement). The principal is the station named exactly after the town, one per town via `DISTINCT ON` (every matched town has exactly one such station, so the dedupe is a guard, not a choice). **112 towns match** (the #68 note's "69 sites" was measured without the R94 casing normalisation; with it, and with both 48111+48112 as the top tier the way `places` scores them, the count is 112). The station-name side of the match needed the R94 casing normalisation the places/railways layers already apply — the 14201 register stores most rows in capitals — so the rail branch now initcaps all-caps register names (HELSINKI → Helsinki), which also fixes the shouting labels the layer used to emit. Tram 1, metro 2, rail 2/3 as before; only the rung-3 derivation is new. **2. Metro lines with no metro stations (R70), and the R6 answer.** The stops were never unavailable — MTK's own `rautatieliikennepaikka` class carries 25 of them (Kamppi, Ruoholahti, Rautatientori, Tapiola, …: all 25 lie within 100 EPSG:3857 units of a metro segment, next nearest site is Helsinki main at 335, so a 200-unit cut separates them cleanly) — but the class stops at Matinkylä: Finnoo, Kaitaa, Soukka, Espoonlahti and Kivenlahti (open since 2022-12, and present as 14201 *labels*) have no 14200 site even in the April 2025 vintage. Checked against the full product lists per R6: MML's Maastotietokanta has no more metro sites than the theme file we already fetch; **HSL's GTFS** (the Helsinki region authority's official static timetable, `https://infopalvelut.storage.hsldev.com/gtfs/hsl.zip`, open data CC BY 4.0) has every station. So the new source is HSL's GTFS: a `downloads:` entry (the `?download=1` trick keeps the zip whole, as with Poland's feeds), a `fi_gtfs_metro_stops` staging table via the existing GTFS stops loader (route_type 1, platforms collapsed to parent stations), and a metro branch in the `stations` query. All **30 metro stations** now import. The 25 MTK metro sites are excluded from the rail branch (`NOT EXISTS` against a 14131 segment within 200 units) rather than re-labelled, so no station draws twice — 0 rail rows sit within 200 units of a metro line after the reimport. **HSL supplies the geometry, the register supplies the name** (review fix, commit 2). The feed's stop names are operational rather than cartographic: every one reads *"&lt;town&gt;n metroasema"* — a genitive stem plus the words "metro station" — so taking them verbatim labelled all 30 stations "Kampin metroasema", "Rautatientorin metroasema", where Stockholm draws `Karlaplan` and Warszawa `Centrum`, in a form that does not even match the place name beside it. The metro branch therefore runs the **same 14201 register lookup the rail branch runs**, anchored on the HSL point instead of the MTK site, and all 30 resolve: Kampin metroasema → `Kamppi`, Kivenlahden metroasema → `Kivenlahti`, Koivusaaren metroasema → `Koivusaari`. A name join rather than a suffix strip, because stripping `" metroasema"` would leave the genitive ("Kampin"). `COALESCE` keeps the feed name as the fallback for a station opened before the register catches up; it fires on nothing today. **R74, documented rather than guessed.** 176 of the 559 traffic sites had no register name before this issue; after it, 175 — Koivusaari's MTK site is one of the 25 the metro exclusion removes, and its HSL point finds the register's "Koivusaari" label. The country doc now states what they are: MTK operating points the 14201 register does not label — junctions, passing loops and goods yards, the same population as the *named* ", TAVARA" sites (Hanko, Tavara; Hyvinkää, Tavara — "tavara" is Finnish for goods). Genuinely unnamed source features, not a dropped-name bug. ## Verification (live DB, after `-layer stations` reimport) - `SELECT importance, count(*) FROM map_stations_14_fi GROUP BY 1` → 1:463, 2:277, 3:112 — **no gap 1..3** (the issue's acceptance query). - `map_stations_9_fi` → 112 (was 0), one principal per top-tier town; z9 tile over Helsinki decodes to Helsinki/Espoo/Kauniainen; z10/z11 389, z12+ 852. - Metro: `map_stations_14_fi` mode='metro' → **30 rows**, min distance to the metro line 0.23 units, max 131 (all on the line); 0 rail rows within 200 units of a metro segment (no double-draw); 0 NULL `importance`; no NULL names in metro/tram, 175 NULL in rail (the documented R74 set); partitions present at z9–z14. - Decoded z11 tile over Helsinki (11/1165/592): 28 station features — 16 rail + 12 metro, **0 names carrying "metroasema"**, the register names present (Kamppi, Koivusaari, Keilaniemi, Hakaniemi …) alongside the rail ones (Helsinki, Ilmala, Huopalahti …). - Real-browser CDP render (`scripts/cdp-map-check.mjs`, never virtual time): z9 over Helsinki draws 8 `station_dots` (all rail, the principals); z11 draws 40 dots — 22 metro + 18 rail — with 3 metro labels placed; the blue metro dots sit on the blue metro line. - se/pl untouched: `map_stations_14` 2059/4052, `map_stations_9` 485/60, same as before the reimport. - `make build`, `go test ./...` importer/ + mapsrv/ green; `git diff --check` clean. ## Left undone / notes for the reviewer - The one new fetch (HSL GTFS, 57 MB) went through the importer's declared-downloads path; the file is cached with a `.fetchmeta` sidecar like every other download. - Metro names come from the 14201 register, not the feed (see above). Two consequences, both recorded in `docs/country-finland.md`: - three Finnish stations now share a name across modes — Hakaniemi and Rautatientori (metro + tram, 150 m and 290 m apart, genuine interchanges) and Vuosaari (metro station vs harbour goods yard, 2.6 km apart, genuinely two places). Sweden already has 107 such pairs, so this is the house pattern, not a collision to fix. - the documented initcap limit is now visible on two metro labels, "Aalto-Yliopisto" and "Helsingin Yliopisto", where Finnish wants a lower-case second word. 47 of the register's all-caps 14201 labels are multi-word and so exposed to it. Fixing it needs Finnish-aware casing rules and would touch `places` and `railways` too, so it stays one documented limit of the shared R94 idiom rather than a per-layer patch. - The Helsinki main station stays rail (335 units from the metro tunnel — the register's own HELSINKI site); metro stations are rung 2 like Sweden's and Poland's, so they draw from z11, not z9. - Finland's `unique_icon` stays NULL (R72) — no network badge, plain dots, unchanged. - Not touched: the commuter-rail reach question (#63), `rail_class` branch (#69's Väylä rail data), bus stops (future bus-stop layer).
Finland's stations had no importance-3 rung (R75: z9 empty, stations from z11 next to
Sweden's z9) and 306 metro line segments with zero metro stations (R70). Both fixed in
the stations layer.

Rung 3 is the #68 recipe, applied — the note that issue left in fimap.yaml said it
would generalize, this is that change: a rail station is importance 3 iff it is the
principal station of a city the MML register prints at its top display tier
(kohdeluokka 48111/48112, the large-font towns the places layer scores 3, same
fi_paikannimi_cl staging table), found by the station being named exactly after the
town. 112 towns match (the #68 note's 69 was measured without the R94 casing
normalisation; with it, and with 48111+48112 as the tier places uses, it is 112).
The rail branch now initcaps all-caps register names (R94, the places/railways idiom)
— the principal match needs it, and it fixes the shouting labels.

Metro: the stops were never unavailable (R6 checked both product lists). MTK's own
rautatieliikennepaikka carries 25 of them but stops at Matinkylä — Finnoo, Kaitaa,
Soukka, Espoonlahti and Kivenlahti have 14201 labels but no 14200 site even in the
April 2025 vintage. HSL's GTFS (the network's own feed, open data) has all 30, so it
is the new source: downloads entry (?download=1 keeps the zip whole), a
fi_gtfs_metro_stops staging table via the existing GTFS stops loader (route_type 1,
parent-station collapse), and a metro branch in the stations query. The 25 MTK metro
sites are excluded from the rail branch (200-unit cut against a 14131 segment;
measured: all 25 within 100 units, next nearest site Helsinki main at 335) so nothing
draws twice; Koivusaari, unnamed in MML's register, gets its name from HSL.

R74 documented: 175 rail sites have no register name — junctions, passing loops and
goods yards, the same population as the named ", TAVARA" sites, genuinely unnamed
source features.

Verification (live DB, -layer stations reimport): map_stations_14_fi importance
1:463 2:277 3:112 (no gap), map_stations_9_fi 112 (was 0), mode metro 30 rows all
within 131 units of the metro line, 0 rail rows within 200 units of a metro segment,
no NULL importance, partitions z9-z14. Decoded z11 tile over Helsinki: 16 rail + 12
metro features with names. CDP render z9 (8 dots) and z11 (22 metro + 18 rail dots,
3 metro labels) over Helsinki. se/pl untouched (2059/4052, 485/60). make build, go
test importer/ + mapsrv/ green, git diff --check clean.
art-bot force-pushed issue-81-fi-stations from b506fb2b0a to b3cee2ea08 2026-08-13 05:02:35 +00:00 Compare
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
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!99
No description provided.