#38: Poland's transit will not merge: the tram network is 73% junction nodes #57

Merged
art merged 3 commits from night/issue-38-transit-merge into main 2026-08-05 08:06:17 +00:00
Owner

Closes #38


Issue #38 — Poland's transit will not merge: the tram network is 73% junction nodes

Status: done — branch night/issue-38-transit-merge (3 commits), regeneralized
transit z9–z13 for SE, PL and FI against the live DB, verified per the repo chain.
Review round: Finland's partition had the same bug and now carries a measured
parallel_merge_pixels (0.5 px) of its own; the Sweden comment now describes the
widening corridor, not just z13.

The mechanism

ST_LineMerge chains only through degree-2 nodes. BDOT10k SKTR (PL) models each track
separately and splits it at every crossover and switch, so 73% of Poland's tram nodes
are junctions (degree 3+) against 30% in Sweden's Topo 10 — the merge had almost
nothing to chain. The fix is parallel_merge_pixels, the same knob that collapsed
double track for railways: most degree-3 nodes are crossovers between the two tracks
of one line, so dropping the second track of a parallel pair turns them into
degree-2 nodes and the next cascade level chains straight through.

The issue's expected obstacle does not exist. It asked whether parallel_priority
could be made optional defaulting to longest-wins — the code already does exactly
that: the rank falls back to (-ST_Length, ST_XMin, ST_YMin) when the column is
unset, and validateMerge never required it (it has been this way since the railways
commit e6abf49, 2026-08-01). The docs implied it was required; the change makes the
contract explicit in importer/generalize.go, importer/layer.go,
docs/generalization.md, and locks it with TestParallelPriorityOptional. No
generation-code change was needed — transit has only mode, and longest-wins is
exactly what it wants.

What changed

  • conf/plmap.yaml: transit gets parallel_merge_pixels: 1 (full railway-strength drop).
  • conf/semap.yaml: transit gets parallel_merge_pixels: 0.25 — deliberately small,
    see Sweden below.
  • conf/fimap.yaml: transit gets parallel_merge_pixels: 0.5 — measured mid-size, see
    Finland below.
  • importer/generalize.go + layer.go: comment the optional-parallel_priority
    contract (empty = longest-wins).
  • importer/layer_test.go: TestParallelPriorityOptional locks validation + the
    longest-wins rank tuple, and that a set priority still leads the rank.
  • docs/generalization.md: parallel_priority documented optional, default longest-wins.
  • docs/performance.md: the transit measurement replaces the stale "transit merged much
    less well in Poland" paragraph in place, and now carries the Finland row.

Measurements (regeneralized tables, live DB)

z14 (source) z13 (first merged) ratio z9 points/feat z9
Sweden (before) 1 764 862 2.0× 862 2.1
Sweden (after) 1 764 846 2.1× 321 2.9
Poland (before) 8 334 7 280 1.14× 7 280 2.1
Poland (after) 8 334 3 591 2.3× 531 3.5
Finland (before) 1 879 1 223 1.54× 1 223 2.3
Finland (after) 1 879 676 2.8× 75 5.9
  • Degree-2 share (the decisive number), PL z13 chain network: 3 of 5 244 nodes
    (~0%) → 976 of 3 690 (26%); junction nodes 4 383 → 1 214. The cascade now chains
    below z13 (z12 2 096, z11 1 162, z10 729, z9 531) where it previously froze at
    7 280. The z14 source histogram is unchanged (still 17% degree-2, exactly the
    issue's table) — the source import is untouched; the drop happens inside the cascade.
  • Finland's was the same pre-fix case the issue describes — MTK splits its network
    like BDOT10k, so its z13 chain network was 0 of 855 nodes degree-2 (712 junction
    nodes, 83% — junction-heavier than Poland's 73%)
    and the cascade froze at
    z13 = z9 = 1 223. Regeneralized with the 0.5 px drop it chains to z9 = 75, with z13
    degree-2 at 289 of 766 nodes (37.7%). The value is the measured middle: the full
    1 px would eat Helsinki's metro (parallel track pairs 10–19 m apart, the SE twin-tunnel
    geometry — a 1 px dry run dropped 18.6 km of its 202 km), while a 0.25 px regeneralize
    leaves z13 at 1 136 chains (10.4% degree-2). At 0.5 px the z13 metro keeps 200.0 of
    202.0 km (only the above-ground double track collapses).
  • z9 Warszawa tile zxy_map_transit(9,285,168): 29 203 B → 2 016 B (11% of the
    tile → under 1%). Stockholm z9: 8 081 → 3 707 B. Helsinki z9: 1 945 B.
  • Sweden's parallel metro tracks are safe at z13. Its z13 metro length is unchanged
    from source (313 km → 313 km) because Stockholm's twin tunnels sit 10–25 m apart,
    outside the 0.25 px corridor (4.8 m at z13) — Sweden only loses sub-pixel street tram
    double track (tram 328 → 327 km). The corridor widens as the cascade descends
    (~9.5 m at z12, ~19 m at z11, ~38 m at z10, ~76 m at z9), and from z11 down the
    tunnels are inside it and correctly collapsed — that is where most of Sweden's z9
    improvement comes from (z13 only moves 862 → 846; z9 moves 862 → 321). The first cut
    at 1 px changed SE's ratio to 2.6x and dropped 181 z13 chains; that is why SE uses
    0.25 px. Poland's drop removes the second track of each parallel pair (tram
    2 324 → 1 865 km by z13) — the merge, not lost lines.

Verification

  • make build clean; go test ./... fresh in importer/ and mapsrv/.
  • Tiles decoded at Warszawa, Stockholm and Helsinki z9/z13: both metro and tram
    modes present with correct mode/country attributes.
  • Real-browser CDP check (scripts/cdp-map-check.mjs, no virtual time) at z13 over
    Warszawa (344 transit features, 320 tram + 24 metro) and Stockholm (136, 87 metro +
    49 tram): lines continuous, no console errors; station layers render in Stockholm.
  • All three countries' z13 tables are fixed points (re-running the 1 px / 0.5 px /
    0.25 px DELETE drops 0).

Left undone

  • The z14 (source) tables were not re-imported — not needed: the drop runs only inside
    the cascade, and regeneralize 9–13 covers all merged levels.
Closes #38 --- # Issue #38 — Poland's `transit` will not merge: the tram network is 73% junction nodes **Status: done** — branch `night/issue-38-transit-merge` (3 commits), regeneralized `transit` z9–z13 for SE, PL and FI against the live DB, verified per the repo chain. Review round: Finland's partition had the same bug and now carries a measured `parallel_merge_pixels` (0.5 px) of its own; the Sweden comment now describes the widening corridor, not just z13. ## The mechanism `ST_LineMerge` chains only through degree-2 nodes. BDOT10k SKTR (PL) models each track separately and splits it at every crossover and switch, so 73% of Poland's tram nodes are junctions (degree 3+) against 30% in Sweden's Topo 10 — the merge had almost nothing to chain. The fix is `parallel_merge_pixels`, the same knob that collapsed double track for `railways`: most degree-3 nodes are crossovers between the two tracks of *one line*, so dropping the second track of a parallel pair turns them into degree-2 nodes and the next cascade level chains straight through. **The issue's expected obstacle does not exist.** It asked whether `parallel_priority` could be made optional defaulting to longest-wins — the code already does exactly that: the rank falls back to `(-ST_Length, ST_XMin, ST_YMin)` when the column is unset, and `validateMerge` never required it (it has been this way since the railways commit e6abf49, 2026-08-01). The docs implied it was required; the change makes the contract explicit in `importer/generalize.go`, `importer/layer.go`, `docs/generalization.md`, and locks it with `TestParallelPriorityOptional`. No generation-code change was needed — `transit` has only `mode`, and longest-wins is exactly what it wants. ## What changed - `conf/plmap.yaml`: transit gets `parallel_merge_pixels: 1` (full railway-strength drop). - `conf/semap.yaml`: transit gets `parallel_merge_pixels: 0.25` — deliberately small, see Sweden below. - `conf/fimap.yaml`: transit gets `parallel_merge_pixels: 0.5` — measured mid-size, see Finland below. - `importer/generalize.go` + `layer.go`: comment the optional-`parallel_priority` contract (empty = longest-wins). - `importer/layer_test.go`: `TestParallelPriorityOptional` locks validation + the longest-wins rank tuple, and that a set priority still leads the rank. - `docs/generalization.md`: `parallel_priority` documented optional, default longest-wins. - `docs/performance.md`: the transit measurement replaces the stale "transit merged much less well in Poland" paragraph in place, and now carries the Finland row. ## Measurements (regeneralized tables, live DB) | | z14 (source) | z13 (first merged) | ratio | z9 | points/feat z9 | |---|---:|---:|---:|---:|---:| | Sweden (before) | 1 764 | 862 | 2.0× | 862 | 2.1 | | Sweden (after) | 1 764 | 846 | **2.1×** | 321 | 2.9 | | Poland (before) | 8 334 | 7 280 | 1.14× | 7 280 | 2.1 | | Poland (after) | 8 334 | 3 591 | **2.3×** | 531 | 3.5 | | Finland (before)| 1 879 | 1 223 | 1.54× | 1 223 | 2.3 | | Finland (after) | 1 879 | 676 | **2.8×** | 75 | 5.9 | - **Degree-2 share (the decisive number), PL z13 chain network:** 3 of 5 244 nodes (~0%) → **976 of 3 690 (26%)**; junction nodes 4 383 → 1 214. The cascade now chains below z13 (z12 2 096, z11 1 162, z10 729, z9 531) where it previously froze at 7 280. The z14 *source* histogram is unchanged (still 17% degree-2, exactly the issue's table) — the source import is untouched; the drop happens inside the cascade. - **Finland's was the same pre-fix case the issue describes** — MTK splits its network like BDOT10k, so its z13 chain network was **0 of 855 nodes degree-2 (712 junction nodes, 83% — junction-heavier than Poland's 73%)** and the cascade froze at z13 = z9 = 1 223. Regeneralized with the 0.5 px drop it chains to z9 = 75, with z13 degree-2 at **289 of 766 nodes (37.7%)**. The value is the measured middle: the full 1 px would eat Helsinki's metro (parallel track pairs 10–19 m apart, the SE twin-tunnel geometry — a 1 px dry run dropped 18.6 km of its 202 km), while a 0.25 px regeneralize leaves z13 at 1 136 chains (10.4% degree-2). At 0.5 px the z13 metro keeps 200.0 of 202.0 km (only the above-ground double track collapses). - **z9 Warszawa tile** `zxy_map_transit(9,285,168)`: **29 203 B → 2 016 B** (11% of the tile → under 1%). Stockholm z9: 8 081 → 3 707 B. Helsinki z9: 1 945 B. - **Sweden's parallel metro tracks are safe at z13.** Its z13 metro length is unchanged from source (313 km → 313 km) because Stockholm's twin tunnels sit 10–25 m apart, outside the 0.25 px corridor (4.8 m at z13) — Sweden only loses sub-pixel street tram double track (tram 328 → 327 km). The corridor widens as the cascade descends (~9.5 m at z12, ~19 m at z11, ~38 m at z10, ~76 m at z9), and from z11 down the tunnels are inside it and correctly collapsed — that is where most of Sweden's z9 improvement comes from (z13 only moves 862 → 846; z9 moves 862 → 321). The first cut at 1 px changed SE's ratio to 2.6x and dropped 181 z13 chains; that is why SE uses 0.25 px. Poland's drop removes the second track of each parallel pair (tram 2 324 → 1 865 km by z13) — the merge, not lost lines. ## Verification - `make build` clean; `go test ./...` fresh in importer/ and mapsrv/. - Tiles decoded at Warszawa, Stockholm and Helsinki z9/z13: both `metro` and `tram` modes present with correct `mode`/`country` attributes. - Real-browser CDP check (`scripts/cdp-map-check.mjs`, no virtual time) at z13 over Warszawa (344 transit features, 320 tram + 24 metro) and Stockholm (136, 87 metro + 49 tram): lines continuous, no console errors; station layers render in Stockholm. - All three countries' z13 tables are fixed points (re-running the 1 px / 0.5 px / 0.25 px DELETE drops 0). ## Left undone - The z14 (source) tables were not re-imported — not needed: the drop runs only inside the cascade, and regeneralize 9–13 covers all merged levels.
Poland's `transit` merged 1.14x (8 334 -> 7 280) where Sweden merged 2.0x,
because BDOT10k SKTR models each track separately and splits it at every
crossover and switch: 73% of Poland's tram nodes are junctions (degree 3+)
against 30% in Sweden, and ST_LineMerge chains only through degree-2 nodes.
Most of those degree-3 nodes are crossovers between the two tracks of one
line, so `parallel_merge_pixels` — what collapsed double track for railways —
turns them into degree-2 nodes and lets the cascade chain through.

The obstacle the issue expected — that the knob requires `parallel_priority` —
does not exist: the rank falls back to longest-wins (-ST_Length, then a stable
envelope key) when the column is unset, exactly as transit wants (its only
attribute is `mode`, and no class ladder). That was already the code's
behaviour since the railways commit; this change documents it as the contract
(generalize.go, layer.go, docs/generalization.md), locks it in with a test,
and applies `parallel_merge_pixels: 1` to transit in semap.yaml and
plmap.yaml.

Co-Authored-By: Hermes Agent <noreply@nousresearch.com>
The first cut applied the same 1 px parallel drop to both countries, but that
changed Sweden's z14→z13 ratio from 2.0x to 2.6x and dropped 181 z13 chains —
too aggressive for a network that was already chainable. The issue called
Stockholm's parallel metro tracks "a different case from Warsaw's trams", and
the measurements agree: the tunnelbana's twin tunnels sit 10–25 m apart
(visible at z13 where 1 px = 19 m), while Warsaw's tram double track is a few
metres apart with crossovers every block. So:

- Poland keeps the full 1 px drop: z13 8 334 → 3 591 (2.3x, was 1.14x), z9
  7 280 → 531, and the z13 chain network's degree-2 share goes from 3 of
  5 244 nodes (~0%) to 976 of 3 690 (26%) — the cascade now chains below z13
  (z12 2 096, z11 1 162, z9 531) where it previously froze at 7 280.
- Sweden uses a 0.25 px drop: z13 1 764 → 846 (2.1x, effectively unchanged),
  metro length identical to source (313 km), tram 328 → 327 km. The 0.25 px
  corridor (4.8 m at z13) catches street tram double track but is far narrower
  than the 10–25 m between Stockholm's parallel metro tunnels.

Measured on the regeneralized tables; the z9 Warszawa tile goes 29 203 → 2 016 B,
Stockholm 8 081 → 3 707 B. Both modes render in both cities (CDP check, no
console errors). Recorded in docs/performance.md; mechanism in
docs/generalization.md.

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

Review — #57 (transit merge, issue #38)

Builds clean, go vet and go test pass in both modules (the only failure is
TestDumpGlyphPNG, which cannot write /tmp/glyph_g.png in this sandbox and fails
identically on every branch, main included).

This is the right response to the issue. The central claim checks out against main:
rank() at generalize.go:519–529 already omits the column when ParallelPriority is
empty and falls back to (-ST_Length, ST_XMin, ST_YMin), and validateMerge at :401
only validates it when non-empty. So "the issue's expected obstacle does not exist" and
"no generation-code change was needed" are both accurate — the correct outcome was to
document the contract, lock it with a test, and set two config values, which is exactly
what the diff does. A 30-line code change for a problem the issue expected to need a
schema extension is the good kind of result.

The mechanism measurement is the decisive one and it is the right one: 73% junction nodes
against Sweden's 30%, and the degree-2 share of Poland's z13 chain network moving from
3 of 5 244 to 976 of 3 690. Sweden's 0.25 px against Poland's 1 px is properly justified
by the tunnel-separation measurement rather than picked, and recording that the first cut
at 1 px moved SE to 2.6× and dropped 181 z13 chains is exactly the rejected-alternative
number that makes the choice reviewable.

Also worth noting, since the other two open generalization PRs are entangled: this branch
is based on main, carries no cherry-picks, and merges cleanly with both #55 and #56
(verified by trial merge — docs/performance.md, importer/generalize.go and
importer/layer_test.go all auto-merge).

Finland does have a transit layer, and it has exactly this bug

"Left undone" says:

Finland's transit partition (map_transit_*_fi) was not regeneralized — its config
(conf/fimap.yaml) has no transit layer of its own, so it is unaffected

That premise is wrong. conf/fimap.yaml:638 defines one:

  - name: transit
    stop_z: 9
    maxz: 14
    generalization_strategy: simplify_line
    merge_lines: true

simplify_line + merge_lines: true, no parallel_merge_pixels, sourced from
fi_muut.rautatie — i.e. precisely the pre-fix configuration Poland had. And the live
tables show Helsinki in the same frozen state the issue describes:

z14 fi | 1879      z13 fi | 1223      z9 fi | 1223
z14 pl | 8334      z13 pl | 3591      z9 pl |  531
z14 se | 1764      z13 se |  846      z9 se |  321

1 879 → 1 223 is a 1.54× merge, and then z13 and z9 are the same number — the cascade
does not chain at all below z13, which is the exact signature of PL freezing at 7 280.
It is not an empty partition either: 1 105 tram + 118 metro chains, so this is Helsinki's
real network.

So the third country with a tram network is being left in the pre-fix state on a false
premise. Either measure Finland's junction share and give it a parallel_merge_pixels
alongside the other two (the layer is already merge_lines: true, so it is a one-line
config change plus a regeneralize), or correct the claim and file the follow-up
explicitly. Given that the PR closes #38 and #38 is about transit not merging, quietly
leaving a third of the affected countries unmerged seems worth resolving before merge
rather than after.

The Sweden comment describes z13 only

conf/semap.yaml:

0.25 px at z13 is a 4.8 m corridor: it collapses true double track but leaves the twin
tunnels alone

True at z13, but the corridor is px * 0.25 and px doubles every level down: ~9.5 m at
z12, ~19 m at z11, ~38 m at z10, ~76 m at z9. Tunnels 10–25 m apart are inside the
corridor from z11 down and do get collapsed.

That is correct behaviour — at z11 the two tunnels are half a pixel apart and drawing them
separately would be wrong — and it is where most of Sweden's improvement actually comes
from: z13 only moves 862 → 846, while z9 moves 862 → 321. But the comment reads as a
property of the setting rather than of one zoom level, and someone tuning this later will
believe the tunnels are preserved throughout. One clause ("at z13; the corridor widens with
the cascade, and by z11 the tunnels are correctly collapsed") covers it, and it makes the
0.25 choice easier to understand rather than harder.

Smaller notes

  • The parallel DELETE's rank tuple is a strict total order in both forms, so no mutual
    deletion is possible, and exact ties simply both survive. The fixed-point check
    (re-running drops 0) confirms it empirically — good check to have run.
  • The PR body lists the cascade as "z12 2 096, z11 1 162, z10 729, z9 531";
    docs/performance.md gives the same series without the z10 729. Harmless, but they
    should agree.
  • The body says the measurement was "recorded in the 'Water at coarse zoom' section". It
    actually replaces the stale transit paragraph in place, which is the better thing to have
    done — the description just undersells it.
  • TestParallelPriorityOptional pins both the longest-wins tuple and the priority-led one,
    which is the right pair to lock given the whole point is that the two paths coexist.
## Review — #57 (transit merge, issue #38) Builds clean, `go vet` and `go test` pass in both modules (the only failure is `TestDumpGlyphPNG`, which cannot write `/tmp/glyph_g.png` in this sandbox and fails identically on every branch, `main` included). This is the right response to the issue. The central claim checks out against `main`: `rank()` at `generalize.go:519–529` already omits the column when `ParallelPriority` is empty and falls back to `(-ST_Length, ST_XMin, ST_YMin)`, and `validateMerge` at `:401` only validates it when non-empty. So "the issue's expected obstacle does not exist" and "no generation-code change was needed" are both accurate — the correct outcome was to document the contract, lock it with a test, and set two config values, which is exactly what the diff does. A 30-line code change for a problem the issue expected to need a schema extension is the good kind of result. The mechanism measurement is the decisive one and it is the right one: 73% junction nodes against Sweden's 30%, and the degree-2 share of Poland's z13 chain network moving from 3 of 5 244 to 976 of 3 690. Sweden's 0.25 px against Poland's 1 px is properly justified by the tunnel-separation measurement rather than picked, and recording that the first cut at 1 px moved SE to 2.6× and dropped 181 z13 chains is exactly the rejected-alternative number that makes the choice reviewable. Also worth noting, since the other two open generalization PRs are entangled: this branch is based on `main`, carries no cherry-picks, and merges cleanly with both #55 and #56 (verified by trial merge — `docs/performance.md`, `importer/generalize.go` and `importer/layer_test.go` all auto-merge). ### Finland does have a transit layer, and it has exactly this bug "Left undone" says: > Finland's transit partition (`map_transit_*_fi`) was not regeneralized — its config > (`conf/fimap.yaml`) has no transit layer of its own, so it is unaffected That premise is wrong. `conf/fimap.yaml:638` defines one: ```yaml - name: transit stop_z: 9 maxz: 14 generalization_strategy: simplify_line merge_lines: true ``` `simplify_line` + `merge_lines: true`, no `parallel_merge_pixels`, sourced from `fi_muut.rautatie` — i.e. precisely the pre-fix configuration Poland had. And the live tables show Helsinki in the same frozen state the issue describes: ``` z14 fi | 1879 z13 fi | 1223 z9 fi | 1223 z14 pl | 8334 z13 pl | 3591 z9 pl | 531 z14 se | 1764 z13 se | 846 z9 se | 321 ``` 1 879 → 1 223 is a 1.54× merge, and then **z13 and z9 are the same number** — the cascade does not chain at all below z13, which is the exact signature of PL freezing at 7 280. It is not an empty partition either: 1 105 tram + 118 metro chains, so this is Helsinki's real network. So the third country with a tram network is being left in the pre-fix state on a false premise. Either measure Finland's junction share and give it a `parallel_merge_pixels` alongside the other two (the layer is already `merge_lines: true`, so it is a one-line config change plus a regeneralize), or correct the claim and file the follow-up explicitly. Given that the PR closes #38 and #38 is about transit not merging, quietly leaving a third of the affected countries unmerged seems worth resolving before merge rather than after. ### The Sweden comment describes z13 only `conf/semap.yaml`: > 0.25 px at z13 is a 4.8 m corridor: it collapses true double track but leaves the twin > tunnels alone True at z13, but the corridor is `px * 0.25` and `px` doubles every level down: ~9.5 m at z12, ~19 m at z11, ~38 m at z10, ~76 m at z9. Tunnels 10–25 m apart are inside the corridor from z11 down and do get collapsed. That is correct behaviour — at z11 the two tunnels are half a pixel apart and drawing them separately would be wrong — and it is where most of Sweden's improvement actually comes from: z13 only moves 862 → 846, while z9 moves 862 → 321. But the comment reads as a property of the setting rather than of one zoom level, and someone tuning this later will believe the tunnels are preserved throughout. One clause ("at z13; the corridor widens with the cascade, and by z11 the tunnels are correctly collapsed") covers it, and it makes the 0.25 choice easier to understand rather than harder. ### Smaller notes - The parallel `DELETE`'s rank tuple is a strict total order in both forms, so no mutual deletion is possible, and exact ties simply both survive. The fixed-point check (re-running drops 0) confirms it empirically — good check to have run. - The PR body lists the cascade as "z12 2 096, z11 1 162, z10 729, z9 531"; `docs/performance.md` gives the same series without the z10 729. Harmless, but they should agree. - The body says the measurement was "recorded in the 'Water at coarse zoom' section". It actually replaces the stale transit paragraph in place, which is the better thing to have done — the description just undersells it. - `TestParallelPriorityOptional` pins both the longest-wins tuple and the priority-led one, which is the right pair to lock given the whole point is that the two paths coexist.
art force-pushed night/issue-38-transit-merge from 873c9b818f to 7322d2958b 2026-08-05 02:10:57 +00:00 Compare
Author
Owner

Both asks from the review are addressed on the branch (head now 7322d29, 3 commits).

Finland — measured, and given a value of its own (0.5 px, not borrowed).

The premise error is acknowledged: FI has had a transit layer all along (conf/fimap.yaml), and the live tables did show Helsinki frozen at z13 = z9 = 1 223. Measured on the first merged level (z13), Finland's chain network is 0 of 855 nodes degree-2 — 712 junction nodes, 83%, junction-heavier than Poland's pre-fix 73%. And the tunnel-separation measurement did apply to Helsinki after all: the metro's parallel track pairs sit 10–19 m apart, and a 1 px dry run dropped 18.6 km of its 202 km — so Poland's full 1 px was not an option. Sweden's 0.25 px regeneralizes the cascade but weakly (z13 stays at 1 136 chains, only 10.4% degree-2). The measured middle is 0.5 px: z13 metro keeps 200.0 of 202.0 km (only the above-ground double track collapses), degree-2 reaches 289 of 766 nodes (37.7% — past Poland's post-fix 26%), and the FI cascade now chains z13 676 → z12 280 → z11 163 → z10 107 → z9 75 (was frozen at 1 223). The z13 table is a fixed point (re-running the 0.5 px DELETE drops 0), and tiles decode at Helsinki z9/z13 with both modes and correct country/mode attributes.

Sweden comment. Added the clause: the corridor is px * 0.25 and px doubles every level down (~9.5 m at z12, ~19 m at z11, ~38 m at z10, ~76 m at z9), so from z11 down the 10–25 m tunnels are inside it and correctly collapsed — a property of z13, not of the setting, and the source of most of the z9 improvement.

Smaller notes.

  • The rank tuple's strict total order: agreed — both forms are total orders, so no mutual deletion is possible and exact ties both survive; the fixed-point check confirms it empirically.
  • Cascade series: the PR body already had z10 729; docs/performance.md was the one missing it — corrected there. PL/SE were not regeneralized, so the series is unchanged; Finland's own series is recorded alongside it in the table.
  • Measurement description: the body now says the docs change "replaces the stale transit paragraph in place" rather than "recorded in the 'Water at coarse zoom' section".

Verification per the repo chain: make build clean, go test ./... fresh in importer/ and mapsrv/, confs parse, decoded tiles at Helsinki z9/z13 (64 features at z9, both modes with correct attrs at z13).

Both asks from the review are addressed on the branch (head now 7322d29, 3 commits). **Finland — measured, and given a value of its own (0.5 px, not borrowed).** The premise error is acknowledged: FI has had a transit layer all along (conf/fimap.yaml), and the live tables did show Helsinki frozen at z13 = z9 = 1 223. Measured on the first merged level (z13), Finland's chain network is **0 of 855 nodes degree-2 — 712 junction nodes, 83%**, junction-heavier than Poland's pre-fix 73%. And the tunnel-separation measurement did apply to Helsinki after all: the metro's parallel track pairs sit 10–19 m apart, and a 1 px dry run dropped 18.6 km of its 202 km — so Poland's full 1 px was not an option. Sweden's 0.25 px regeneralizes the cascade but weakly (z13 stays at 1 136 chains, only 10.4% degree-2). The measured middle is 0.5 px: z13 metro keeps 200.0 of 202.0 km (only the above-ground double track collapses), degree-2 reaches 289 of 766 nodes (37.7% — past Poland's post-fix 26%), and the FI cascade now chains **z13 676 → z12 280 → z11 163 → z10 107 → z9 75** (was frozen at 1 223). The z13 table is a fixed point (re-running the 0.5 px DELETE drops 0), and tiles decode at Helsinki z9/z13 with both modes and correct country/mode attributes. **Sweden comment.** Added the clause: the corridor is px * 0.25 and px doubles every level down (~9.5 m at z12, ~19 m at z11, ~38 m at z10, ~76 m at z9), so from z11 down the 10–25 m tunnels are inside it and correctly collapsed — a property of z13, not of the setting, and the source of most of the z9 improvement. **Smaller notes.** - The rank tuple's strict total order: agreed — both forms are total orders, so no mutual deletion is possible and exact ties both survive; the fixed-point check confirms it empirically. - Cascade series: the PR body already had z10 729; docs/performance.md was the one missing it — corrected there. PL/SE were not regeneralized, so the series is unchanged; Finland's own series is recorded alongside it in the table. - Measurement description: the body now says the docs change "replaces the stale transit paragraph in place" rather than "recorded in the 'Water at coarse zoom' section". Verification per the repo chain: `make build` clean, `go test ./...` fresh in importer/ and mapsrv/, confs parse, decoded tiles at Helsinki z9/z13 (64 features at z9, both modes with correct attrs at z13).
art force-pushed night/issue-38-transit-merge from 7322d2958b to 0bb3ee5b92 2026-08-05 08:04:31 +00:00 Compare
art merged commit 0bb3ee5b92 into main 2026-08-05 08:06:17 +00:00
art deleted branch night/issue-38-transit-merge 2026-08-05 08:06:17 +00:00
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!57
No description provided.