#113: R94 casing is one shared rule — the register's cased twin, else first word only #130
No reviewers
Labels
No labels
blocked
claude-wip
map-report
map:is
map:se
needs-review
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
art/ismap!130
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "issue-113-fi-name-casing"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #113
R94 casing: one shared rule, first-word unless the register says otherwise
What changed
The R94 casing idiom (
CASE WHEN teksti = upper(teksti) THEN initcap(teksti) ELSE teksti END) was written out separately in four places:fi_paikannimi_cl,railways, and twice instations(rail + metro branches). It now lives once, in a new staging tablefi_paikannimi_cased(conf/fimap.yaml), which carries the display-cased name for exactly the series the label layers read (48111/48112/48120/48130 + 14201). All four consumers readnamefrom it — the places side and the stations side cannot drift apart, which is what the #81 principal-station match depends on.The rule, in order of authority:
AALTO-YLIOPISTO→Aalto-yliopisto(via the 42101 row),S:T MICHEL→S:t Michel(via the 14201 row),NORRA HAGA→Norra Haga(via the 48130 row).MÄNTTÄ-VILPPULAstaysMänttä-Vilppulabecause Mänttä and Vilppula are both register places; a twin-lessAALTO-YLIOPISTOwould becomeAalto-yliopistobecause Yliopisto is not. This is the answer to the issue's "the register does not mark which is which": for hyphen compounds it does, via the parts.HELSINGIN YLIOPISTO→Helsingin yliopisto,PASILA, TAVARA→Pasila, tavara(matching the register's own cased ", TAVARA" twins: Hausjärvi, tavara; Imatra, tavara), and a twin-lessS:T MICHEL→S:t michel— which is why the colon shape needs no special tokeniser: the fallback never splits a word.Why this rule
The issue measured the three obvious fixes and found each partial. The combination is what the register itself supports:
HELSINGIN YLIOPISTO— the more visible of the two metro cases — broken (it has no cased row anywhere).MÄNTTÄ-VILPPULA,JAKOBSTAD-PEDERSÖRE) — the hyphen-parts rule rescues exactly those.Measured against the live register: the rule changes 47 all-caps (teksti, kohdeluokka) pairs of the read series, 43 of them to the register-cased or linguistically correct form.
Known remaining limit (documented on the staging table and in docs/country-finland.md): a twin-less all-caps name whose second element the register does not name at all comes out fully lower-cased —
KOSKI TL→Koski tl,S:T KARINS→S:t karins,PIEKSÄMÄKI TEMU→Pieksämäki temu,ELÄINPUISTO-ZOO→Eläinpuisto-zoo. Four names; the register carries no cased form and no row for the element, so no signal exists to do better.Verification (against the live DB)
Reimported the three touched layers (
importer/importer -layer places,railways,stations conf/fimap.yaml) plus the new/changed staging tables.Helsingin yliopisto, Otaniemi z13 showsAalto-yliopisto, Mänttä area z10 showsMänttä-Vilppula.Aalto-yliopistoandHelsingin yliopistoat z14, and place labelsMänttä-Vilppula(z10) andMikkeli(z11).make acceptance): ismap 11/11, semap 12/12 (+1 in the 100 s bucket, pre-existing), plmap 13/13, fimap 13/13, world 9/9 — 0 failed anywhere.Two new acceptance tests were added, in the same commit:
stations: "R94: multi-word station names come back in the register's display casing" — the two metro names are present cased and the initcap shapes absent onmap_stations_14_fi, and the S:t abbreviation shape is asserted on the register side (the 14201S:T MICHELrows normalise toS:t Michelinfi_paikannimi_cased; the map itself shows Mikkeli, the Finnish name).places: "R94: no all-caps Finland place labels, and compound town names keep their parts" — no all-caps label, andMänttä-Vilppulapresent whileMänttä-vilppulais absent.The 2 remaining all-caps station names (
TAYS A,TAYS B, Tampere tram stops) are Digiroad's own abbreviations from the tram source (fi_pysakki), not the 14201 register — out of the issue's scope, kept as the source writes them, and noted in docs/country-finland.md.Docs
docs/country-finland.md's three R94 passages (places, railways, stations) updated to describe the shared rule and its four-name residual limit instead of the old initcap behaviour.
Closes #113to #113: R94 casing is one shared rule — the register's cased twin, else first word onlyaa4a6e3c04to1b6b1bcde3#133 is now landed on this branch — water_bodies is the fifth consumer of the register, and it reads
namefrom the shared pass like everywhere else.What landed (commit
676b753, on top of the origin/main merge):36201, 36301joined the kohdeluokka WHERE list — the whole fix, exactly as #133 specified. The rule needed no extension; measured against the rebuilt register, 0 of 155 844 water-name rows come out all-caps, and all 25 all-caps names in the two series come back correct (Bottniska viken / Skärgårdshavet / Hangon itäinen selkä via cased twins, the lakes via the first-word rule, Ala-Keitele keeping its capital because Keitele is itself a register name).fi_paikannimi→fi_paikannimi_cased, and the lateral join readsp.nameinstead ofp.teksti.Verified against the live DB after
importer/importer -layer water_bodies conf/fimap.yaml(fetch was a no-op — the MTK sources were on disk, so no 5.65 GB re-download):-acceptance all15/15,make acceptancegreen across all five configs.Also reworded the now-stale notes: the "NOT YET every consumer … Issue #133" block on the staging pass (added in
1b6b1bc) now records water_bodies as covered, and R94's entry in docs/country-requirements.md describes the closed gap rather than the open one.Review
Verified:
go test ./...green, and the fimap suite runs 15/15 against the live database —fi_paikannimi_casedexists and is populated there, so this went through a real import rather than a config-only edit.I checked the casing rule's claims against the register rather than taking the PR body's word, and all of them hold:
Zero all-caps names survive into
fi_paikannimi_cased. Two specific things I went looking for and did not find:regnamesdraws from the whole register, so a standaloneYLIOPISTOrow anywhere would capitalise the wrong half ofAALTO-YLIOPISTO. There are 0 such rows, so rule 3 does what the PR body says it does.Ala-aho/Ala-Aho,Övre kärret/Övre Kärret, …), which would makeDISTINCT ONa coin flip. None of them has a single all-caps consumer in the five label classes, so theORDER BYtiebreak never actually decides anything today. Worth knowing it's luck rather than design, and that the ordering is what will decide it the first time a collision does land.The lower-cased results read correctly for both languages —
Bottniska viken,Hangon itäinen selkä,Hausjärvi, tavara— and the four names the PR admits it cannot do better on (Koski tl,S:t karins,Pieksämäki temu,Eläinpuisto-zoo) are genuinely unreachable from the register.The places R94 test can't say which half broke
The stations twin was strengthened in
1b6b1bcto returnnames=...so a failure names what it found. The places test next to it still returns onlypassed:That is three independent failure modes — labels started shouting, the compound got flattened, or the name join broke entirely — collapsing into one bit. The run confirms it:
PASS (118ms, 1 row(s))with no detail at all. A count of all-caps labels plus the matched compound forms would cost nothing and make a red run self-explaining, the same way the stations version now does.Merge note: R105 must grow to 16
This branch adds a 16th Finland staging table. #124 (PR #137) ships an R105 test that names 15 and whose comment states the invariant "The list must be the
staging:block's list, and nothing else." After both merge,fi_paikannimi_casedis the one staging table R105 does not cover — which is the wrong table to miss, since a silently-empty shared casing pass is exactly the failure that would drift all five consumers at once.The two branches also conflict directly in
conf/fimap.yaml(both addacceptance_tests:towater_bodiesandstations). The conflict is additive on both sides, so resolving it is mechanical — just don't let the R105 list slip through while doing it.Rebased into a dependency chain — this PR is now the base of one, so it merges first and is unchanged (
676b753, no force-push).The
conf/fimap.yamlconflict with #137 is gone: #137 now sits downstream and carries both sides of the R94 blocks. #137's R105 test was extended to 16 staging tables there, sofi_paikannimi_casedis covered the moment both are in.Verified on the chain tip:
go test ./...green, and all five acceptance suites pass against the live DB (ismap 26/26, semap 26+1 not-run, plmap 24/24, fimap 29/29, world 9/9).