#80: Finland's top place names no longer shout, and same-place duplicates collapse #90

Merged
art-bot merged 2 commits from issue-80-place-casing into main 2026-08-09 15:56:36 +00:00
Owner

Closes #80


#80 — Finland's place names: casing + spatial dedupe

Finland's top-tier place names were all-caps on the map (FORSSA, HANKO,
HEINOLA, HELSINKI at z5), and the same place could appear twice at
near-but-not-identical anchor points — HELSINKI at importance 3 beside a cased
Helsinki at importance 2.

What changed

Both in conf/fimap.yaml's places query:

  1. Casing normalized on the way in (R94). The 48111/48112 tier ships in
    capitals; all-caps rows are initcap-ed (HELSINKI → Helsinki,
    MÄNTTÄ-VILPPULA → Mänttä-Vilppula, S:T MICHEL → S:t Michel). Cased rows
    pass through untouched so an already-cased register row is never re-cased.
  2. Dedupe is now spatial (R90), not coordinate-exact. ST_ClusterDBSCAN at
    eps 600 partitioned by the normalized name, one row per (name, cluster).
    eps 600 was measured against the live register (R79): same-place duplicate
    anchors sit at 13–600 units, and at 60°N a 3857 unit is ~0.5 m on the
    ground, so 600 units ≈ 300 m — the "few hundred metres" of the acceptance.
    Distinct same-name settlements (two places called Helsinki 230 km apart,
    hundreds of Koivula hamlets) stay split.
  3. The R92 language fix is untouched. The outer DISTINCT ON the point
    with Finnish preferred still collapses VAASA/VASA and
    HELSINKI/HELSINGFORS at identical coordinates — the casing fix does not
    undo the language fix.

Rows: 394 636 register rows → 269 826 points coordinate-exactly → 267 812
after the spatial dedupe. The z5 top-4 is the same order, just cased; the
per-zoom rank <= N budgets are unchanged (R83).

Verification (live DB, importer/importer -layer places conf/fimap.yaml)

  • R94 acceptance: count(*) WHERE country='fi' AND name=upper(name) AND length(name)>3 → 0 (was 308).
  • R90 acceptance: no same-name pair within 600 units in map_places_14 for fi
    → 0 pairs.
  • Per-zoom fi counts match the caps: 1/4/17/70/282/1129/4519/18076/72305 at
    z4–z12, full register at z13+.
  • Partitions present at every zoom (z4–z14); other countries' partitions
    untouched (se 203830, pl 101334, is 44533).
  • No NULLs in name/importance/rank/geom.
  • Decoded z8 tile over Helsinki: cased Helsinki/Espoo/Inkoo/Kauniainen/…,
    no caps, rank absent (mvt_exclude intact).
  • Real-browser CDP (no virtual-time-budget): z5 over Finland renders
    Forssa/Hanko/Heinola/Helsinki; Vaasa renders without a Vasa twin; the
    archipelago "Helsinki" hamlet still renders its own label (positive control
    for R90).
  • make build and go test ./... pass in importer/ and mapsrv/.

Notes

  • docs/country-finland.md updated; the eps rationale is in the config
    comment next to the query (the review surface).
  • Iceland's 4 name=upper(name) rows are codes (M-804, 1930, G. G., M. A.),
    not the caps problem; untouched.
  • The ranking itself (R85) was not touched — the z5 order is #71/#77's
    accepted design; this issue was the casing and the duplicate.
Closes #80 --- ## #80 — Finland's place names: casing + spatial dedupe Finland's top-tier place names were all-caps on the map (FORSSA, HANKO, HEINOLA, HELSINKI at z5), and the same place could appear twice at near-but-not-identical anchor points — HELSINKI at importance 3 beside a cased Helsinki at importance 2. ### What changed Both in `conf/fimap.yaml`'s `places` query: 1. **Casing normalized on the way in (R94).** The 48111/48112 tier ships in capitals; all-caps rows are `initcap`-ed (`HELSINKI → Helsinki`, `MÄNTTÄ-VILPPULA → Mänttä-Vilppula`, `S:T MICHEL → S:t Michel`). Cased rows pass through untouched so an already-cased register row is never re-cased. 2. **Dedupe is now spatial (R90), not coordinate-exact.** `ST_ClusterDBSCAN` at eps 600 partitioned by the normalized name, one row per `(name, cluster)`. eps 600 was measured against the live register (R79): same-place duplicate anchors sit at 13–600 units, and at 60°N a 3857 unit is ~0.5 m on the ground, so 600 units ≈ 300 m — the "few hundred metres" of the acceptance. Distinct same-name settlements (two places called Helsinki 230 km apart, hundreds of Koivula hamlets) stay split. 3. **The R92 language fix is untouched.** The outer `DISTINCT ON` the point with Finnish preferred still collapses VAASA/VASA and HELSINKI/HELSINGFORS at identical coordinates — the casing fix does not undo the language fix. Rows: 394 636 register rows → 269 826 points coordinate-exactly → 267 812 after the spatial dedupe. The z5 top-4 is the same order, just cased; the per-zoom `rank <= N` budgets are unchanged (R83). ### Verification (live DB, `importer/importer -layer places conf/fimap.yaml`) - R94 acceptance: `count(*) WHERE country='fi' AND name=upper(name) AND length(name)>3` → **0** (was 308). - R90 acceptance: no same-name pair within 600 units in `map_places_14` for fi → **0 pairs**. - Per-zoom fi counts match the caps: 1/4/17/70/282/1129/4519/18076/72305 at z4–z12, full register at z13+. - Partitions present at every zoom (z4–z14); other countries' partitions untouched (se 203830, pl 101334, is 44533). - No NULLs in name/importance/rank/geom. - Decoded z8 tile over Helsinki: cased Helsinki/Espoo/Inkoo/Kauniainen/…, no caps, `rank` absent (mvt_exclude intact). - Real-browser CDP (no virtual-time-budget): z5 over Finland renders Forssa/Hanko/Heinola/Helsinki; Vaasa renders without a Vasa twin; the archipelago "Helsinki" hamlet still renders its own label (positive control for R90). - `make build` and `go test ./...` pass in importer/ and mapsrv/. ### Notes - `docs/country-finland.md` updated; the eps rationale is in the config comment next to the query (the review surface). - Iceland's 4 `name=upper(name)` rows are codes (M-804, 1930, G. G., M. A.), not the caps problem; untouched. - The ranking itself (R85) was not touched — the z5 order is #71/#77's accepted design; this issue was the casing and the duplicate.
The 48111/48112 tier of the paikannimi register ships in capitals (HELSINKI),
and the same place can appear in two series at near-but-not-identical anchor
points, so the map rendered its biggest cities in caps and whispered a cased
twin beside them (HELSINKI at importance 3 next to a cased Helsinki at
importance 2).

Fix in conf/fimap.yaml's places query, per R94 and R90:

- All-caps rows are initcap-ed on the way in (HELSINKI → Helsinki,
  MÄNTTÄ-VILPPULA → Mänttä-Vilppula, S:T MICHEL → S:t Michel); cased rows pass
  through untouched so an already-cased register row is never re-cased. R94's
  acceptance — no name = upper(name) with length > 3 — is 0 for fi.
- Deduplication is now spatial instead of coordinate-exact: ST_ClusterDBSCAN
  at eps 600 partitioned by the normalized name, one row per (name, cluster).
  The eps is measured against the live register (R79): same-place duplicate
  anchors sit at 13–600 units, and 600 units is 300 m on the ground at 60°N
  (a 3857 unit is ~0.5 m there) — the "few hundred metres" of R90's
  acceptance. The genuinely distinct same-name settlements (two places called
  Helsinki 230 km apart, hundreds of Koivula hamlets) stay split.
- The outer DISTINCT ON the point with Finnish preferred is kept, so the R92
  bilingual collapse (VAASA/VASA, HELSINKI/HELSINGFORS) still works — the
  casing fix does not undo the language fix.

394 636 register rows now collapse to 267 812 points (was 269 826). The z5
top-4 is unchanged in order, just cased: Forssa, Hanko, Heinola, Helsinki;
per-zoom rank budgets are unchanged (R83).

Verified against the live DB after reimporting the single layer
(importer/importer -layer places conf/fimap.yaml):
- R94 acceptance: count(*) WHERE name=upper(name) AND length(name)>3 is 0.
- R90 acceptance: no same-name pair within 600 units (300 m ground) in
  map_places_14 for fi.
- Per-zoom fi counts match the caps exactly: 1/4/17/70/282/1129/4519/18076/
  72305 at z4–z12, full register at z13+.
- Partitions present at every zoom; the other countries' partitions are
  untouched (se 203830, pl 101334, is 44533).
- No NULLs in name/importance/rank/geom.
- Decoded z8 tile over Helsinki: cased Helsinki/Espoo/Inkoo/... features, no
  caps, no rank key (mvt_exclude intact).
- Real-browser CDP check: z5 over Finland renders Forssa/Hanko/Heinola/Helsinki
  (was FORSSA/HANKO/HEINOLA/HELSINKI); Vaasa renders without a Vasa twin; the
  archipelago "Helsinki" hamlet still renders its own label (R90).
- make build and go test ./... pass in importer/ and mapsrv/.
initcap breaks a word at every non-alphanumeric character, so S:T MICHEL comes
back as S:T Michel, not S:t Michel as the comment claimed. Record the actual
behaviour and the two names it affects.

The eps rationale quoted the measured duplicate gaps as metres while deriving
the eps itself in 3857 units, which read as an eps of 300 ground metres against
duplicates 600 ground metres apart. The gaps are units: the duplicate mass is
below 300 units (~150 m ground) and the tail beyond is background.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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!90
No description provided.