NWB road network: is it worth wiring in? #180
Labels
No labels
agent
agent:ci
agent:done
agent:failed
agent:needs-input
agent:refined
agent:refining
agent:running
agent:shipped
agent:skip
autonomous
autopilot
driven
local
plan
proposal
qa
qa-gap
research
retro
ship
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
jeroen/cartopolis#180
Loading…
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?
Problem
docs/direction.md:55lists NWB road network as an unverified frontier candidate offering "measured carriageways, and bridge and tunnel geometry". The first half of this ticket is checking whether that is true and whether it is worth wiring in. It was checked, on 2026-08-29, against the live service. Both halves of the row's description are wrong, and the dataset is not worth wiring in.What NWB actually is
The service is
https://api.pdok.nl/rws/nationaal-wegenbestand-wegen/ogc/v1(OGC API Features). It has exactly two collections:wegvakken(road sections) andhectopunten(hectometre posts). Its landing page declaresrel="license"→ CC0 1.0, so the licence question is settled and is not a blocker.wegvakkengeometry ismultilinestring— the schema endpoint gives{"x-ogc-role": "primary-geometry", "format": "geometry-multilinestring"}. There is no polygon anywhere in the service. Its 60-odd properties are administrative: street name, road number, route number, road authority, house-number ranges, municipality,openlr,wvk_id/jte_id_beg/jte_id_end,bst_code,fow,frc,rel_hoogte.So:
crates/geo/src/road_texture.rs:164-201(motorway 22 m, residential 7 m, …), and NWB carries nothing that would replace it.rel_hoogte, an integer grade level.Why the gaps it could fill are already closed
docs/notes/bridge-heights.md— Shortbread'sbridgespolygon layer supplies the outline, AHN's DSM-minus-DTM supplies a measured clearance, andresolve_bridge_deckslifts the deck and the road span onto it. NWB has nothing to add to that path.crates/geo/src/paving.rs:7-35argues it at length for the BGT: replacing the OSM ribbons loses the road texture, the kerb casing and the depth ladder, and "the BGT cannot supply any of that". NWB's centrelines are strictly weaker than the BGT polygons that lost that argument.rel_hoogtewould supply is already recovered without it.docs/notes/grade-separation.md:99-114records that Shortbread ships nolayer, that this was expected to need an external source, and that the expectation was wrong: the dangle rule carries the fix (59 refusals to the grade rule's 4 on the Groningen fixture) andtwo_viaducts_crossing_are_not_a_junctioncovers the interchange case. The note says so explicitly: "This note previously said the interchange case needed a source carryinglayerand that nothing here could recover it. That was wrong."And
rel_hoogteis mostly absent anyway — measured over an unpaged sample, 37 of 400 features non-null at Knooppunt Oudenrijn (bbox=5.045,52.060,5.085,52.085), 31 of 1000 over Groningen centre.What it would cost, and what it would change
Paged with the
rel="next"link overbbox=6.555,53.207,6.580,53.222(~1.7 × 1.7 km of Groningen centre, comparable to the z14 cell the additive trees bin at —crates/cartopolis/src/systems/map/surveyed.rs:36): 1,392 features, 2.03 MB of raw GeoJSON, in two requests. The service caps a page at 1000 features whateverlimitasks for and returns nonumberMatched— the same truncation trap CLAUDE.md already records for the BAG WFS. That is the same order as the heaviest thing the client streams today (paving, 3.8 MB for the densest cell), spent on a second copy of centrelines the MVT already delivers for free.It changes only the data behind the picture, not the picture.
geobron_nmshows the geometry is largely BGT-derived and so more accurate than OSM's, but the client draws a constant-width ribbon around whatever centreline it is given; a decimetre-accurate centreline under an invented width is invisible.Two pointers worth recording while they are in hand
Neither is scope here, but both are the thing somebody will reach for NWB expecting:
https://api.pdok.nl/rws/weggegevens/ogc/v1, collectionswegvak_max_snelhedenandwegvak_rijstroken, also CC0, joined to NWB onwvk_id(omschr: "2 -> 2"). It covers Rijkswaterstaat roads only — the same Groningen city-centre box returns 2 lane features against NWB's 1,392. It is a motorway dataset, not a city one.overbruggingsdeelandkunstwerkdeel_vlak/_lijn/_punt. If surveyed bridge geometry is ever wanted, it belongs to the "BGT, the remaining layers" row atdocs/direction.md:54, not to this one. Interface confirmed; volume and usefulness are not checked.Approach
Documentation only. No crate is touched, no Rust changes, no build.
1.
docs/notes/nwb-road-network.md— a new note. This is the "directions abandoned without a diff" casedocs/notes/README.mdnames, which has no commit to attach to. Front-matter per that file:Carry the findings above as prose, with the date and the method on every measurement. Link
[[bridge-heights]]-style tobridge-heights.md,grade-separation.mdandpaving.rs's module doc, since each is where the corresponding gap was already closed.2.
docs/direction.md— record the result against the row. Remove| NWB road network | … |from the Candidates table (line 55) and add a new subsection under The frontier, after the candidates table:That table will be reused by the other seven rows, which is why it is a section rather than an annotation on one line.
docs/direction.md:4-5says a session "may not rewrite it". This edit is authorised by the frontier paragraph itself,docs/direction.md:47-49— "'this one is not worth it' is a valid result to record here" — and is confined to the frontier section. Do not touch the goal, the values, or the may/may-not sections.3. The commit body must name which reading of
docs/direction.mdwas applied. The ticket boilerplate refers to "the seven values at the top"; there is no numbered list of seven under that heading, so cite the sentences instead. The load-bearing one is the goal atdocs/direction.md:10-16— content comes from registries, and the world degrades to OSM where none covers it. NWB is a registry, and the check is whether it says anything OSM does not; on width, structures and grade it does not, and where it does the answer was already recovered.paving.rs:7-35is the precedent that a more accurate outline is not on its own an upgrade.Then close this ticket.
Acceptance criteria
docs/notes/nwb-road-network.mdexists, withtopic:/triggers:/updated:front-matter in the shapedocs/notes/README.mdspecifies.https://api.pdok.nl/rws/nationaal-wegenbestand-wegen/ogc/v1and its two collections,wegvakkenandhectopunten.rel="license"link rather than from a wiki.wegvakkengeometry ismultilinestringand that the service exposes no polygon, citing the/collections/wegvakken/schemaendpoint.bbox=6.555,53.207,6.580,53.222, and therel_hoogtenull counts (969/1000 Groningen centre, 363/400 Oudenrijn).numberMatched, and points at the matching BAG WFS trap already inCLAUDE.md.bridge-heights.md,grade-separation.mdandcrates/geo/src/paving.rs, and namescrates/geo/src/road_texture.rs:164as where the ribbon width actually comes from.wegvak_rijstroken, CC0, joined onwvk_id, RWS roads only, 2 features over the Groningen box) and the BGT'soverbruggingsdeel/kunstwerkdeel_*— each marked with exactly what was and was not verified.NWB road networkrow no longer appears in the Candidates table indocs/direction.md.docs/direction.mdhas a "Checked and not taken" table under The frontier containing the NWB row, its check date and a reason, linking to the new note.docs/direction.mdis modified.crates/is modified.docs/direction.mdthe decision was taken under and why, per the repo's rule that adocscommit explaining a direction carries its reasoning.Verification
No build. This branch changes no Rust, so the workspace gates (
cargo fmt --check, the crate checks,scene-smoke) are untouched and nothing needs--shotorcargo shots.Reproduce the numbers in the note (each is a read-only HTTP request; all were run from this container on 2026-08-29):
Check the edits:
Nothing here needs a workstation.
Out of scope
road_width_m. It is a real dataset with a real join key, it is CC0, and it would change the picture on motorways. It is also a different source, national-roads-only, and belongs to its own frontier row and its own ticket. Record the pointer; do not build it.overbruggingsdeel/kunstwerkdeel_*. That isdocs/direction.md:54, "BGT, the remaining layers". Its volume and usefulness are unmeasured.level_of, the noding pass, or the bridge deck path. All three already work, and this ticket found no reason to touch them.docs/direction.md.Open questions
None. The three questions the ticket poses were answered against the live service: the interface exists and is documented above, the licence is CC0 and permits caching and redistribution, and the dataset changes neither the picture nor any data the client is missing.
Sources: NWB Wegen (PDOK OGC API), Nationaal Wegen Bestand (NWB) — PDOK, Weggegevens (WEGGEG) OGC API, Wegkenmerk kunstwerken over de weg (RWS dataregister)
Branch:
docs/180-nwb-not-worth-wiringOriginal request
From the frontier in
docs/direction.md: NWB road network — measured carriageways, and bridge and tunnel geometry.The first half of this ticket is deciding whether it is worth doing at all:
Not worth it is a valid answer. Record it in
docs/direction.mdagainst this rowwith the reason, and close this ticket — that is the result, not a failure.
Decide it yourself. This ticket is not being watched, so a question asked
here is a ticket that stops. The seven values at the top of
docs/direction.mdexist to settle exactly this kind of ambiguity — pick the reading they support,
say in the commit body which one you applied and why, and build. Only a decision
that would need something nobody can derive from the repository — a credential, a
licence somebody must agree to, a choice about what the project is for — is a
reason to stop.
If it is worth doing, follow the shape the surveyed layers already use:
an extractor under
tools/, a coverage manifest, a streamer that adds to whatis drawn rather than replacing it, and no unbounded per-frame upload.
Filed by the autopilot.
🤖 Refined by the viberfox issue agent. Reply with @agent refine and what is wrong to have this rewritten.
🤖 Refining this before anything gets built — reading the code, no branch, no commits. If it turns out I'd have to guess at the requirements I'll stop and ask instead.
🤖 Refined. The description above is now the spec; I'll pick it up for implementation on the next poll.
If the direction is wrong, say so now — @agent refine with a correction rewrites it, and
agent:skipstops me.🤖 viberfox issue agent on the VPS — 39 turns · $3.16 · session
0a2ff303-5d3e-459b-b1b7-5906771b60f3. Reply with @agent to continue this session.🤖 Picked this up — working on branch
docs/180-nwb-not-worth-wiringin a fresh worktree on the VPS. I'll report back here when I'm done.Label an issue
agent:skipto keep me off it, ordrivento keep it in a session you are driving.I checked NWB against the live service and it is not worth wiring in. The change is documentation only.
What I changed
Two files, no code:
docs/notes/nwb-road-network.md— the check, with every measurement dated and its command written down so nobody repeats it.docs/direction.md— removed theNWB road networkrow from the Candidates table and added a new "Checked and not taken" table under The frontier holding it. The goal, the values and the may/may-not sections are untouched.Why not
The frontier row promised "measured carriageways, and bridge and tunnel geometry". Both halves are wrong:
wegvakkenis multilinestring,hectopuntenis multipoint, and there is no polygon anywhere in the service. The 60-odd properties are administrative — no width, no lane count. The road ribbon's width comes from a constant table incrates/geo/src/road_texture.rs:164, and NWB carries nothing to replace it.rel_hoogte, an integer grade level — and it is null in 969 of 1000 features over Groningen centre, 363 of 400 at Knooppunt Oudenrijn.grade-separation.mdrecords that the dangle rule handles the interchange case and that the earlier expectation of needing an external source was wrong.Cost, if it were wired: 1,392 features and 2.03 MB of raw GeoJSON over 1.7 × 1.7 km of Groningen centre — the order of the heaviest thing the client streams today, for a second copy of centrelines the map tiles already deliver. The licence is CC0 1.0, so terms were never the obstacle.
How I verified it
I re-ran every measurement in the ticket against the live service myself rather than transcribing them. All reproduced exactly. I also confirmed two things the ticket did not:
offsetis rejected with a 400, so paging must follow therel="next"link; andbst_codeis a carriageway subtype naming no structure, which is what makes "no bridge geometry" a statement about the whole schema rather than about one field.cargo fmt --checkpasses across the workspace. No crate is touched, so the crate checks andscene-smokeare unaffected —git diff origin/main -- crates/is empty. Nothing here needs a visual check.Two things for you
Pointers I recorded but did not build. Lane counts do exist, in WEGGEG (
wegvak_rijstroken, CC0, joins to NWB onwvk_id) — but it covers Rijkswaterstaat roads only: 2 lane features over the same Groningen box against NWB's 1,392. It is a motorway dataset and belongs to its own frontier row. Surveyed bridge polygons are in the BGT (overbruggingsdeel,kunstwerkdeel_*); I confirmed the collections exist and nothing else. Both are marked in the note with exactly what was and was not checked.The worktree I was handed was broken. Its
.gitfile pointed at an admin directory under/home/agent/viberfox/.git/worktrees/that does not exist, so every git command answeredfatal: not a git repository: (null).git worktree repaircannot fix that. I made a second worktree on the same branch at.claude/worktrees/docs-180-nwb-repair, copied the edits across and committed there. The branch is pushed and correct; the two leftover directories are worth a sweep when convenient.Branch
docs/180-nwb-not-worth-wiringis pushed at4fd5cb2. The commit body names the goal atdocs/direction.md:10-16as the reading applied — content comes from registries, so the test for a registry is whether it says anything OpenStreetMap does not, and on width, structures and grade it does not.No commits were made.
🤖 viberfox issue agent on the VPS — 55 turns · $4.27 · session
c4a0440c-220f-4a49-b101-d34632b51d2c. Reply with @agent to continue this session.🤖 Merged into
mainas pull request #184 (4fd5cb23).🤖 Could not ship this. No such file or directory
The branch is intact; nothing was merged.
docs/qa/targets.md— 14 of 14 passes re-verified a shipped ticket, 9 of them documentation-only verdicts #280