#149: shared airports + airport_points layer — one MVT source for is/se/pl/fi #154
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!154
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "issue-149-shared-airports"
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?
#149: shared airports + airport_points layer — one MVT source for is/se/pl/fi
Closes #149
The shared layer
airportsand the derivedairport_pointsare now shared layers in theunification sense: contracts in
conf/common.yamlshared_layers:, onecountry-partitioned table
map_<layer>_<z>_<cc>per country, one MVT function(
zxy_map_airports/zxy_map_airport_points) on themapsource. All fourcountries build a partition; the style draws every country's airports from the one
maptile route.The contract (
airports: stop_z 10, maxz 13, filter_only;airport_points:stop_z 8, maxz 13, filter_only) is one attribute set all four countries already
fill:
geom,name,airport_class. The class ladders collapse to the same 1/2(Áætlunarvöllur / iata presence / TYPLOTNISKA 'port lotniczy' / register
LENTOASEMA → 1, everything else → 2) and the zoom floors matched before this PR,
so no country changed its data — only the table it lands in. Iceland renamed its
nafnfitjucolumn tonameto meet the contract.The derivation reads the country's own partition: each
airport_pointsquery sources
map_airports_13_<cc>(partition-pruned), with the existinglayers: [airports]DAG edge keeping airports first (R140).This carries the three per-country imports: the se (#146/#103), fi (#147/#110)
and pl (#153/#106) airports data now renders through the shared source. Those
issues stay open for their data review; this PR is only the unification fold.
Style and sources
airports+airport_labelsnow read the sharedmapsource (airport_labelsswitched from
nafnfitjuto the contract'snamefield).airports_se/fi/pl,airport_labels_se/fi/pl) andthe per-country tile sources (
se,fi,pl) that #103/#106/#110 added aredeleted.
conf/mapsrv.yamlsources are back to[map, is];iskeepscontours/buildings/peaks.
se/pl/ficonfigs now declare no source; theirsources:blocks are empty(documented in-place).
docs/style.md(66 layers: 58 map + 7 is + background),docs/schema.md(shared/per-country lists),docs/country-requirements.md(R13 + layer inventory),
docs/unification.md,docs/workstream-a.md.Orphans — deliberate (issue #12 shape)
Nothing was DROPped. The old per-country tables (
ismap_/se_/plmap_/fi_airports +airport_points) and their
zxy_<cc>_airports[_points]functions remain in the DB asinert #12 orphans — the project's established practice from past unifications. They
collide with nothing (different prefixes; mapsrv no longer declares those sources)
and are tracked by #12.
Verification (live DB)
Re-imported only the two layers per country (
--layer airports,airport_points),no fetches, no full imports:
make acceptance):map_airports_*_is)R119: no airports zoom table is empty (z10–z13) — PASS,R120: airports carry no NULL airport_class ... — PASS(per country), theFinland
R94: no all-caps Finland airport labels ... — PASS, the PolandR6: the airport partition is populated (OT_KUKO_A) — PASS (airports=301).layers' keys are exactly
[name airport_class country](contract attrs minusnothing, plus the partition key).
zxy_mapat z13: Keflavík →airports1 +airport_points1 (name Keflavík, class 1); Arlanda → 1 (Arlanda flygplats, 1);Chopin → 1 + 1 (Lotnisko Chopina w Warszawie, 1); Helsinki-Vantaa → 32
(Helsinki-vantaan lentoasema, class 1 among class-2 grounds).
scripts/cdp-map-check.mjs, no virtual time) at z13per country: Keflavík 8 airport polygons + label "Keflavík"; Arlanda 5 +
"Arlanda flygplats"; Chopin 4 + "Lotnisko Chopina w Warszawie"; Helsinki-Vantaa
72 + "Helsinki-vantaan lentoasema". Screenshots verified (local Qwen2.5-VL).
make testpasses;config-checkpasses for all four configs + world.Sweden's first unshared layer since unification Phase 5: `airports` (runway polygons) + the derived `airport_points` label layer, mirroring Iceland's implementation (R140), from the already-negotiated topo10 Geotorget order (new files: entry only — 11.4 MB zipped / 25.7 MB unzipped, recorded on first fetch, R5). Source: start_landningsbana (objekttypnr 2853, 206 runway polygons with flygplatsstatus I drift/Nedlagd) joined to flygplatsomrade (objekttypnr 2854, 183 areas with iata/icao). Design, each decision measured against the live data: - Nedlagd runways are dropped at import (190 of 206 kept) — the same closed-track decision the railways layer made; a decommissioned runway is not an airport. - airport_class comes from the codes, not flygplatsstatus: Iceland's scheduled-vs-strip ladder has no Swedish vocabulary, so class 1 = iata present ("regular traffic only" per the source docs), class 2 = absent. 57/133 runways. The coarse-zoom label filter (z9, class 1, like Iceland) keeps the 42 scheduled airports on z8-z9. - Names come from the Topo 10 text theme's ANLTX "X flygplats" labels (48 of 183 areas carry one, always inside its area): neither anläggningsomrade table has a name, only codes, and a code is not a label. The join is the label inside the runway's own area — the uncapped nearest-label join this replaced labelled runways from another airport up to 300 km away, and the R120 acceptance test pins the structural guarantee. Serving: semap.yaml regains a sources: block (se), mapsrv.yaml serves /tiles/se, html/style.json declares the se source with airports_se + airport_labels_se copied from Iceland's (nafnfitju -> name). Docs updated: country-sweden.md catalogue line (issue #84), R13 in country-requirements.md, style.md layer count, unification.md. Verified against the live DB: se_airports_* 190 rows at z10-z13; se_airport_points_* 42 at z8-z9 / 48 at z10-z13; new R119/R120 acceptance tests PASS; importer tiles --check PASS for both layers at coarsest + finest zoom; decoded the z13 Arlanda tile by hand (2 runways, name=Arlanda flygplats, class 1); real-browser CDP render at z11-13 shows Arlanda/Landvetter/Sturup labels + runways; make acceptance-all: ismap 31/31, semap 36/36, plmap 29/29, fimap 34/34, world 14/14; make build and make test pass.The fold made airports shared but left four copies of its checks and four copies of its derivation. Both are now one, and unifying the second is what found the defect. THE TESTS. R119 and the range half of R120 were pasted four times, each naming its own partitions ('map_airports_10_is', …_se, …_pl, …_fi). Four copies drift, and a fifth country gets them only if it remembers to paste them. They are now two catalogue queries on each contract in conf/common.yaml — the pg_inherits idiom country_borders already uses, covering whatever countries exist — plus a per-country aggregate for the attribute checks. This is the split docs/importer-cli.md already documents: "an invariant of the shared table, across every country" belongs on the contract, "that country's own data" stays with the country. Each country keeps exactly the claim that is its own: is every runway is named (true of no other country's source) se every name is the ANLTX label inside its own area pl no invalid polygon; every 'port lotniczy' is class 1 in airport_points fi no invalid polygon; class 1 is exactly the lentoasema-named areas; R94 THE DERIVATION. All four countries now run the identical airport_points query, and writing it once exposed that max() over the class ladder was wrong: the ladder is 1 = scheduled, 2 = everything else, so max() demotes an airport to the tier of its weakest polygon. Poland's BDOT10k splits Wrocław-Strachowice and Lublin across a 'port lotniczy' and an 'inne lotnisko' area each, so both were class 2 and the z9 filter dropped them — 15 scheduled airports drawn at coarse zoom where Poland has 17. Iceland, Sweden and Finland agreed by luck, not by construction, and nothing compared the four queries until they had to become one. The grouping gains a spatial cluster for the same reason (a name is a label, not an identity key; 'Aeroklub Koszaliński' is two airfields 46 km apart). The reasoning and the measurements live on the contract. Verified on the live database: all four countries reimported, 165 acceptance tests pass across the five configs, and the shared tiles still render for every country at z8 with no null tiles. pl 139 → 140 points and 15 → 17 class 1; is/se/fi unchanged at 67/13, 48/42, 88/26.