ferries: a layer of their own, not unpaved roads #34
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!34
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "night/issue-6-ferry-lines"
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 #6
Ferry lines now have their own layer instead of being roads.
Branch:
night/issue-6-ferry-lines(not pushed, not merged).What the data actually says
NVDB publishes a ferry route as an ordinary
bilnätrow inSverigepaketTPwith theroute's name in
Farjeled_Farjeledsnamn. There are 215 such rows, 1 846 km, 86 namedroutes, and nothing else in that file marks a ferry —
Vagtyp_typhas no ferry value,and the flattened TP package keeps only the name from NVDB's own Färjeled feature type.
So the road importer imported all 215 as roads.
It imported them as unpaved roads, which is the second half of the bug: a ferry row
has no
Slitlager_Slitlagertyp, and the surface CASE ended inELSE 'unpaved'. Bothreported features check out exactly — Ekeröleden is FunkVagklass 6 →
tertiary+unpaved, and the pair at Nynäshamn are Gotlands linje / Polenfärjan / Lettlandfärjan /Nynäshamn–Hanko, all FunkVagklass 3 →
secondary+unpaved. Only 306bilnätrows haveno Slitlager at all and 215 of them were the ferries.
What I changed
A new shared layer
ferries(conf/common.yaml), z5–14,geom + name. Not an eighthroad_class:road_classis a ladder of importance that the zoom filters read as one(
road_class <= 'tertiary'), and a ferry has no rung on it — NVDB's own functional classputs Stockholm–Helsingfors at 7 and a 100 m cable ferry at 5, because it describes the road
on the shore. Same argument the config already makes against a
trackclass, onlystronger. It is also drawn differently and generalizes differently, which is what a layer
is for.
No class or importance column, deliberately. A ferry route is a whole feature, not a
segment split at intersections, so unlike
roadsthis layer can usemin_length_pixels—set to 1, one screen pixel of route. That produces the whole ladder out of geometry with
nothing invented: 86 routes at z14 → 71 at z8 → 34 at z5, i.e. cable ferries at high zoom,
vägfärja crossings in the middle, only the long-haul Baltic lines at z5. NVDB does state
one real distinction (statlig vägfärja with a numbered länsväg, 38 routes, versus enskild
commercial line, 44) and I left it out on purpose: no other source here is known to draw
it, length separates them in practice, and inventing a shared vocabulary two of three
countries can't be checked against is what this project's config comments keep warning
against. It is written down in
conf/common.yamlso the option is not lost.conf/semap.yaml— theferrieslayer (the exact complement of the roads WHERE), andtwo changes to
roads: ferries excluded, andsurfaceis now NULL whenSlitlagerisabsent instead of asserting
unpaved. That second one is a separate small fix ridingalong; it affects the 91 remaining unknown-surface roads and is one line if you want it
gone.
conf/world.yaml—ferriesadded to themapsource.html/style.json— aferriesdashed mid-blue line drawn betweenwaterwaysand the road casings, andferry_labelsfrom z7 (63 layers now, was 61). CLAUDE.md / docs/country-{sweden,iceland,poland}.md updated.
One doc bug fixed on the way:
min_length_pixelsis documented as "default 2px" inboth CLAUDE.md and the
layerstruct, but the code has always treated 0 as "no filter"and every road/rail layer depends on that. The comments were wrong, not the code — I fixed
the comments rather than the behaviour, since implementing a default of 2 would silently
put a length filter on every road network.
How I verified it
make build,cd mapsrv && go test ./...,gl-style-validate html/style.json— allclean.
importer/importer -layer ferries conf/semap.yaml, 3.5 s. Rowcounts per zoom 215/118/118/116/114/109/95/79/54/39 (z14→z5), 86 distinct names down to
34, no NULL names, no invalid geometry, all SRID 3857 LINESTRING. Partition
map_ferries_14_seattached with its gist index adopted by the parent.make import-world(2 s) sozxy_mapcallszxy_map_ferries; decodedzxy_map_ferries(9,279,156)and foundGotlands linje/country=sein the tile.roadsquery against the GeoPackage without importing it: 3 397 786 rows(= 3 398 001 live − 215), 91 NULL surfaces, paved/unpaved split unchanged.
Ekeröleden renders as a dashed blue line with its label; z6 over the Baltic shows the
long-haul lines without noise. Screenshots were with the
roadslayers hidden, because:Left undone
Sweden's
roadslayer has not been reimported, so the 215 ferries are still inmap_roads_*and still render as unpaved roads underneath the new ferry line. That needsmake import-se(hours — a 3.4M-segment maxz read plus the full cascade), which the nightrun is not allowed to start. Nothing else is pending on the database side:
map_ferries_*and
zxy_map_ferriesare built andzxy_mapcalls them. The tree is back onmain, whosestyle.jsonhas no ferry layers yet, so the running server draws nothing new until thebranch is merged — the data is there waiting.
Iceland and Poland get no ferry partition and that is correct, not an omission — IS 50V has
the vocabulary (
einingvegakerfis= 7, Ferja) but zero rows in this delivery, and BDOT10kSKJZhas no ferry attribute or class at all. Both are written up in their country docs.Two judgement calls a reviewer might want to overrule, neither of which needs a reimport of
anything but this layer:
min_length_pixels: 1(2 would delay each route by about one zoomlevel) and the decision not to carry the statlig/enskild distinction.