Thin railways at coarse zoom — it is now the biggest thing in a continental tile #9
Labels
No labels
claude-wip
map-report
map:is
map:se
needs-review
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
art/ismap#9
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
railwaysis z5–12 with arail_classladder of main/branch/siding and nozoom_filtersat all, so every siding in Sweden and Poland survives to z5 — where awhole country is a fraction of one tile.
Measured: in the z5 tile covering all of Sweden,
railwaysis 690 kB of 1.37 MB (50%)for 28 691 features, against
cover's 142 kB after the generalization work. It is thesingle largest thing in a continental-scale tile by a wide margin.
Roads solved exactly this problem with the shared
road_classladder and a rung droppedper zoom (
CLAUDE.md, "Generalization strategies" →zoom_filters). Rail has the ladderand not the filters. This is the cheapest large byte win available and it is a config
change, not code:
sidingand thenbranchshould go the wayserviceandminordo,in
conf/common.yamland both country configs.Two things to get right:
minzoomhas to move with the filters or the layer silently stopsdrawing (
CLAUDE.md, "The MapLibre style").different symptom (probably
simplify_line's minimum-length filter) but touches the samelayer, and a fix for one should not make the other worse.
Verify with
-regeneralizerather than a full reimport, and measure the z5 tile before andafter. Background:
docs/performance.md, "Where the bytes are now".Fixed on
fix/rail-merge-and-pl-classification(commite6abf49, not merged).The premise was out of date, and the real cause was something else — worth recording
because it generalises. The
zoom_filtersthis issue asks for already existed: Phase 5added
rail_class <= 'branch'at z10 and<= 'main'at z8 the day before it was filed,so the 28 691-feature measurement predates that DB. More rungs would not have helped,
because what survives to z5 is
main, and there were 130 183 Swedish main featuresaveraging 2.0 points and 203 m each.
ST_SimplifyPreserveTopologypreserves the endpoints of whatever row it is handed, andNJDB delivers the network pre-split, so every 203 m of track pinned two vertices at every
zoom. The cascade was structurally unable to delete a single one. No tolerance, no filter
and no rollup can touch that — only merging the segments back into chains can.
merge_linesdoes that: group by every non-geometry attribute,ST_LineMergeeach groupinto maximal chains, then simplify. Sweden's 130 183 stubs become 660 chains averaging
40 km, and z5 goes from 260 366 points to 2 353. It is lossless for rendering — same ink,
fewer features.
parallel_merge_pixels: 1then collapses double track and yard tracksinto the running line (see #3, which shares the fix).
railwaysmaprailwaysrailwaysmainThe cascade got faster, not slower — 5 s for all of Sweden z11→z5 — since every level
below the first reads a table one to two orders of magnitude smaller.
Two notes against the issue's checklist:
railways_base/railways_tiescarry no class filters,and I did not move any zoom filter, so the minzoom-drift trap does not apply here.
and the fixes do not fight: #3 was a Polish classification bug that put gaps in main
lines, and this one is about feature count. Both verified together.
The generalisable lesson (now in
docs/performance.md): before tuning tolerances ona line layer, check
avg(ST_NPoints(geom))at the coarsest zoom. If it is ~2, the layeris not over-detailed, it is over-divided, and tolerance is the wrong knob.
roads(#10) is the same shape of problem, and
merge_linesis built to be reused there.Merged to
mainase6abf49and pushed. Closing.roadsat z5–z6 is the other half of coarse-zoom tile weight #10