ProRail Spoorwegen, PDOK OGC API: is it worth wiring in? #227

Merged
viberfox-agent merged 1 commit from feat/216-prorail-level-crossings into main 2026-08-30 09:04:46 +00:00
Collaborator

Closes #216

Merged by the autopilot (docs/direction.md) after every Actions job passed on the branch head.

Closes #216 Merged by the autopilot (docs/direction.md) after every Actions job passed on the branch head.
feat(map): raise ProRail's registered level crossings into the world
All checks were successful
CI / test cartopolis (pull_request) Successful in 7m21s
CI / wasm & android targets (pull_request) Has been skipped
db60aea667
A railway has reached this client as a 3.2 m ballast ribbon with the rails
painted into the texture and nothing standing beside it — FURNITURE_TABLE
names no railway key at all, so a level crossing was a street ribbon
meeting a rail ribbon with no equipment on it. ProRail's `overweg` register
says where all 3,917 of them are and what installation is on each, so they
are drawn now: masts, lamp heads and red-and-white booms, merged into the
cell's existing furniture mesh, material, altitude fade and toggle.

One of the service's seven collections is taken and six are not, decided by
docs/direction.md's values:

- `spooras` (track axes) and `trace` (corridor centreline) — value 4, add
  don't replace. Drawing them lays a second set of rail ribbons over the
  OSM ones already there, which is the coplanar z-fight this codebase keeps
  paying for; substituting them is the argument paving.rs already lost for
  road surfaces (the ProRail axis carries no texture, no casing and no rung
  on the depth ladder), and it would delete every railway outside the
  Netherlands.
- `wissel` (switches) and `kruising` (diamond crossings) — value 6, ship
  the smallest thing a machine can judge. Real geometry and real attributes,
  and nothing to be drawn *on*: the rails are a painted texture rather than
  modelled steel, so a switch is invisible at every altitude and no
  --dump-state field would move for anything a person could see. Worth
  revisiting only if rails are ever modelled, which is a different ticket.
- `station` is already a POI through places.rs; `kilometrering` is a small
  unlabelled plate with `rotatie` null on all 6,000 sampled, so it has no
  orientation either — an unlabelled km post is a stick.

Orientation is the one genuinely new piece of logic. The register carries no
azimuth at all (`azimut` null on all 3,917) and its point sits *on the rail
centreline* by the collection's own description, so furniture::WayField —
which indexes every street, path and railway and reads no `kind` — answers
the track every single time, and every boom would be laid along the rails it
is meant to bar. It gained a WayFilter, with road_texture::is_rail_kind
beside road_class so the two cannot drift, and a `direction` that lays an
object along a way rather than across it. A crossing with no non-rail way in
range is dropped rather than drawn at a guessed angle, which keeps
`level_crossings` counting what is on screen rather than what came back.

Three fields the register fills in with something that is not the answer,
each pinned by the captured Peizerweg feature: `levenscyclus_status` is not
a built/not-built flag (1,304 of 3,917 read "Definitief ontwerp", including
crossings that have stood in the street for years, so filtering on it would
delete a third of the register — the surveyed-street-objects.md trap in the
opposite direction); `aantal_ahob` is not a boom count (15 on a single-track
crossing); and the published extent.spatial.bbox is the RD grid's, reaching
Rennes and Copenhagen, so the coverage gate uses an envelope measured over
the features instead.

Bounded like every other streamed layer: three gates before any request is
made (the envelope, a rail mention in the *undecoded* tile body, and the
Furniture toggle), MAX_CROSSINGS_PER_CELL with a warning on truncation, and
byte-bounded meshes built inside map_geometry's existing per-cell worker. No
collider, matching the navigation marks, and no animation — a boom that
lowers needs a train.

Value 1 decides what is left off: no St Andrew's cross, because the register
does not record one (`aantal_andreas` null on all 3,917) and every other
source for it would be a guess.

Refs #216
viberfox-agent deleted branch feat/216-prorail-level-crossings 2026-08-30 09:04:47 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
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
jeroen/cartopolis!227
No description provided.