cover: absorb in one direction, and add a too-thin test #42
No reviewers
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!42
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "issue-36-width-measure"
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 #36 and #13.
What the issue asked, and what the measurements said
4·area/perimeteris a sound width measure. Validated againstST_MaximumInscribedCircleover all 33 062 of Sweden's z9 water polygons: r = 0.971,median ratio 1.047, and 45× cheaper (0.06 s vs 2.7 s). The fractal-perimeter objection
does not bite, for a structural reason: both callers measure it on geometry already
simplified to that level's tolerance, so detail finer than half a pixel is gone before P is
taken.
But on
coverthe measure was never the constraint. A 1 px width test adds 2 072candidates to Poland's 612 643 at z11, and one in 18 158 at z12. Sweden already had
23 885 of 24 601 z5 polygons under a pixel wide. Whatever was wrong, it was not which
polygons the threshold picked.
What was wrong: absorption was not absorbing. Every candidate is evaluated against one
snapshot and takes its largest neighbour's class, with no rule about which of the two is
larger — so two adjacent candidates take each other's class. Both relabelled, neither
merges, count does not move. On Sweden's z6→z5 step, 17 560 of 24 797 absorptions (71%)
were one half of such a pair. At coarse zoom a threshold in pixels makes nearly the whole
table a candidate, so this is the normal case, not a corner.
Absorption is now directed: a candidate absorbs only from something strictly larger
(
(n._a, n._id) > (c._a, c._id), the firstORDER BYterm). A local maximum keeps itsclass and is what its neighbours absorb into — which is also why
foundstill means"touches anything at all", since the no-neighbour drop must not delete a local maximum
with neighbours. Same step, one extra sort term: 24 602 → 12 132 features, area
2 570 263 → 2 570 284 km² (8 ppm).
min_width_pixelsNew per-layer knob. On
coverit widens the candidate set (area <= minArea OR width < minWidth), so it recolours and can never open a hole; it also enables absorption on itsown. On
simplifyit is an outright drop ANDed with the area test, which is only safewhere something else still draws the feature. Measured at z9→z8 as orphaned area — dropped
polygon area with no waterway within a pixel:
So Poland's
water_bodiesgets it and Sweden's and Iceland's do not; the config commentsname the measurement to re-run before that changes, and #40 is what would change it.
Rejected before any DB work on
simplify_line/filter_only, where it would be silentlyignored.
Full cascades, all three countries
coverBcoverBIceland is the clearest reading, because it had no absorption at all before — nothing in
its cascade could remove a feature, so the table sat at a flat 6 700 from z9 to z5. Its z5
tile went 254 kB → 51 kB and renders essentially unchanged. Poland's
water_bodies: z95 675 → 4 281 features, 186 252 → 68 824 points.
Verification
marine_waterz12→z10 moves0.00% / +0.04% / +0.34%, so the coastline did not move (#26's property, re-checked
because a thinness test makes narrow inlets candidates and Sweden's archipelago is the
hard case).
ST_IsValidclean at z5/z8/z11 for all three; every partition present at every zoom; noleftover
_newtables.map.loaded()+areTilesLoaded(), never avirtual clock) at z5–z11 for all three countries.
go testgreen,gl-style-validateclean.width test does not change it.
Also in here
#13, folded in because it says to do it the next time
coveris rebuilt for anotherreason and that was now:
urban_vegetationrolls up toartificialat z9 (Iceland wascarrying a z12-granularity class to z5), and
glaciersurviving every rollup is writtendown as the deliberate decision it is.
Two spun out rather than folded in: #40 (bridge centrelines through water polygons that
have none — the answer to the "fake centrelines" question on #36, and what would let Sweden
and Iceland use the new knob) and #41 (absorption drifts every class into the dominant
one; pre-existing, and #36 improves it — Poland's
naturedrift over z9→z5 goes −46% →−7% — without fixing the cause).
#20, #26 and #27 are closed with their evidence.
🤖 Generated with Claude Code
Correction to what I wrote above. I said Poland's river polygons "go to zero at z6" and
that the river is "drawn as a centreline there instead". The first half is true only of the
river-classed polygons, and the sentence as a whole gives the wrong impression. Polandstill has 47 water polygons at z6, and the wide parts of the Vistula are among them.
BDOT10k classes an impoundment as woda stojąca — standing water — so a reservoir on a
river comes through as
lake, notriver. Two segments of Jezioro Włocławskie, theWłocławek reservoir on the Vistula, are 79 km² and 62 km² at 3 542 m and 4 004 m wide.
One pixel at z6 is 2 446 m, so they are 1.4 px wide and the rule keeps them. At z5 a pixel
is 4 892 m, they are 0.7 px, and the rule drops them — which is exactly the "loses some
segments at z5, but not all" behaviour, and it is the rule working, not failing.
What is left at z5 is the four things still over a pixel wide: Morze Bałtyckie (66 km),
Śniardwy (10.9 km), Łebsko (8.3 km), Dąbie (8.3 km).
Also worth correcting:
cover's water class is not what paints the Vistula at coarsezoom. Measured against the Wisła's 1 331 km of centreline,
coverwater lies on 67% of itat z9, 7.5% at z7 and 1.3% at z6 — so below z7 the river is carried by
waterwaysplusthe surviving impoundment polygons, not by the landcover coverage. That is the correct
behaviour but it is not what I implied.
Rendered before/after at z5/z6/z7 over the Włocławek reach: z6 is indistinguishable, z7
shows the reservoir as a slightly narrower band, and the river is continuous at every zoom
in both. The layer rebuild for the comparison was
-regeneralize 5-13, 2.5 min each way,and the config is back as committed.