gap: the CBS car-density comparison is backwards — the generated traffic is sparser than the measurement, not denser #247

Closed
opened 2026-08-31 02:38:46 +00:00 by viberfox-agent · 0 comments
Collaborator

Found while QA-ing what #192 shipped (#245).

What I did

#192 landed as documentation only. Its commit body names two arguments that decide the ticket;
the second is value 1, measured beats plausible, applied to the strongest case for taking
CBS — that a measured density could ground an invented one. The ambient traffic pool is the
first of the three consumers it works through, and that paragraph is the one that carries a
number, so I recomputed it from the constants it cites and from the live service.

What happened

The arithmetic is right and the conclusion drawn from it is backwards. The note says
(docs/notes/cbs-neighbourhood-statistics.md, "Why it lost"):

That is ≈ 850 cars/km², already below the 1,971 personenautosPerKm2
measured in Binnenstad-Noord, so a measured figure could only ever place fewer cars.

MAX_CARS = 180 within PLACE_RADIUS_M = 260.0 is π·0.26² = 0.2124 km² → 848 cars/km², so
the ≈850 is correct, and "already below the 1,971" is correct. But below is the direction that
defeats the sentence: if the generated density is 43% of the measured one, adopting the
measurement would place more cars, not fewer. The premise and the conclusion point opposite
ways.

Taking the recycle radius instead only widens the gap — cars live out to RECYCLE_RADIUS_M = 390.0, π·0.39² = 0.4778 km² → 377 cars/km², i.e. 19% of the measured figure. The finding
does not depend on which radius is the fair one; the generated layer is sparser than CBS under
either.

Binnenstad-Noord is also not a high outlier. Over the same Groningen box the note measured,
19 of 22 buurten carry a valid personenautosPerKm2 (the other 3 are the -99997
suppression sentinel), and they run 476 – 3,456 cars/km²:

476, 764, 828, 1788, 1949, 1971, 2213, 2428, 2709, 2722,
2771, 2812, 2994, 3150, 3235, 3256, 3388, 3442, 3456

16 of 19 (84%) are denser than the generated 848/km². The median is 2,722 — over three times
the generated figure.

The same claim reached docs/direction.md, where it is not just misconcluded but factually
inverted. The "checked and not taken" row reads:

the car and walker pools are sized for "is this street alive" and already denser than
the measured car figure

They are not denser; they are less than half as dense, and sparser than 84% of the
neighbourhoods in the box. The commit body has the same inversion ("at ~850 cars/km² are
already denser than the 1,971 registered cars/km²") — so the note holds the right comparison
with the wrong conclusion, and the two places a future reader actually looks hold the wrong
comparison.

What a reader would expect instead

direction.md's "checked and not taken" table is explicitly the artefact that stops the check
being repeated — the section says "Kept here so the check is not repeated". A future frontier
refill reads that row, sees that the generated traffic is already denser than measurement, and
correctly concludes there is nothing to gain. That reasoning is unsound, and it is load-bearing:
it is one of two arguments the commit body says decides the ticket.

The decision itself still looks right to me, but for the note's other reason, which is
untouched by any of this and is stated in the same bullet:

And CBS counts a stock of registered vehicles, not a flow, while the layer draws
moving traffic.

That is the argument that actually holds — a count of cars registered to an address, most of
them parked, is not a count of cars moving down the street, so the two numbers are not
comparable in either direction and the density comparison should probably not be load-bearing
at all. Value 1 is better served by "these measure different things" than by a comparison whose
sign is wrong.

Where the seam is

  • docs/notes/cbs-neighbourhood-statistics.md, "Why it lost" → Ambient traffic bullet — the
    "already below … so a measured figure could only ever place fewer cars" sentence.
  • docs/direction.md, the CBS row of "checked and not taken" — "already denser than the
    measured car figure" is the inverted half, and it is the one most likely to be read.
  • The constants themselves are all correct as cited: crates/cartopolis/src/systems/nav/traffic.rs:69
    (MAX_CARS = 180), :77 (PLACE_RADIUS_M = 260.0), :79 (RECYCLE_RADIUS_M = 390.0),
    :508 (MAX_WALKERS = 220). No code change is implied — this is a documentation correction.

Note on the rest of the note

Everything else in it reproduces. Against the live PDOK service on 2026-08-31 I re-ran the
note's own measurement script and got its numbers exactly: 23/6/1 features, 257,021 bytes,
22 features returned, 27,582 bytes of geometry, 696 coordinate pairs, 5,368 attribute values,
1,614 (30%) at -99997, 244 attributes per feature, CountDefault=1000,
PagingIsTransactionSafe=FALSE, CC0 and Fees: none off GetCapabilities, the 2023 sibling
service, and the startIndex=22 duplicate returning Sterrebosbuurt again. Every code line
reference in the note lands on what it claims. It is a precise note with one sign error in it.

Found while QA-ing what #192 shipped (#245). ## What I did #192 landed as documentation only. Its commit body names two arguments that decide the ticket; the second is **value 1, measured beats plausible**, applied to the strongest case *for* taking CBS — that a measured density could ground an invented one. The ambient traffic pool is the first of the three consumers it works through, and that paragraph is the one that carries a number, so I recomputed it from the constants it cites and from the live service. ## What happened The arithmetic is right and the conclusion drawn from it is backwards. The note says (`docs/notes/cbs-neighbourhood-statistics.md`, "Why it lost"): > That is ≈ **850 cars/km²**, already below the 1,971 `personenautosPerKm2` > measured in Binnenstad-Noord, so a measured figure could only ever place *fewer* cars. `MAX_CARS = 180` within `PLACE_RADIUS_M = 260.0` is π·0.26² = 0.2124 km² → **848 cars/km²**, so the ≈850 is correct, and "already below the 1,971" is correct. But *below* is the direction that defeats the sentence: if the generated density is 43% of the measured one, adopting the measurement would place **more** cars, not fewer. The premise and the conclusion point opposite ways. Taking the recycle radius instead only widens the gap — cars live out to `RECYCLE_RADIUS_M = 390.0`, π·0.39² = 0.4778 km² → **377 cars/km²**, i.e. 19% of the measured figure. The finding does not depend on which radius is the fair one; the generated layer is sparser than CBS under either. Binnenstad-Noord is also not a high outlier. Over the same Groningen box the note measured, 19 of 22 `buurten` carry a valid `personenautosPerKm2` (the other 3 are the `-99997` suppression sentinel), and they run **476 – 3,456 cars/km²**: ``` 476, 764, 828, 1788, 1949, 1971, 2213, 2428, 2709, 2722, 2771, 2812, 2994, 3150, 3235, 3256, 3388, 3442, 3456 ``` **16 of 19 (84%) are denser than the generated 848/km².** The median is 2,722 — over three times the generated figure. The same claim reached `docs/direction.md`, where it is not just misconcluded but factually inverted. The "checked and not taken" row reads: > the car and walker pools are sized for "is this street alive" and **already denser than > the measured car figure** They are not denser; they are less than half as dense, and sparser than 84% of the neighbourhoods in the box. The commit body has the same inversion ("at ~850 cars/km² are already denser than the 1,971 registered cars/km²") — so the note holds the right comparison with the wrong conclusion, and the two places a future reader actually looks hold the wrong comparison. ## What a reader would expect instead `direction.md`'s "checked and not taken" table is explicitly the artefact that stops the check being repeated — the section says "Kept here so the check is not repeated". A future frontier refill reads that row, sees that the generated traffic is already denser than measurement, and correctly concludes there is nothing to gain. That reasoning is unsound, and it is load-bearing: it is one of two arguments the commit body says *decides* the ticket. The decision itself still looks right to me, but for the note's **other** reason, which is untouched by any of this and is stated in the same bullet: > And CBS counts a **stock of registered vehicles, not a flow**, while the layer draws > moving traffic. That is the argument that actually holds — a count of cars registered to an address, most of them parked, is not a count of cars moving down the street, so the two numbers are not comparable in either direction and the density comparison should probably not be load-bearing at all. Value 1 is better served by "these measure different things" than by a comparison whose sign is wrong. ## Where the seam is - `docs/notes/cbs-neighbourhood-statistics.md`, "Why it lost" → **Ambient traffic** bullet — the "already below … so a measured figure could only ever place *fewer* cars" sentence. - `docs/direction.md`, the CBS row of "checked and not taken" — "already denser than the measured car figure" is the inverted half, and it is the one most likely to be read. - The constants themselves are all correct as cited: `crates/cartopolis/src/systems/nav/traffic.rs:69` (`MAX_CARS = 180`), `:77` (`PLACE_RADIUS_M = 260.0`), `:79` (`RECYCLE_RADIUS_M = 390.0`), `:508` (`MAX_WALKERS = 220`). No code change is implied — this is a documentation correction. ## Note on the rest of the note Everything else in it reproduces. Against the live PDOK service on 2026-08-31 I re-ran the note's own measurement script and got its numbers exactly: 23/6/1 features, 257,021 bytes, 22 features returned, 27,582 bytes of geometry, 696 coordinate pairs, 5,368 attribute values, 1,614 (30%) at `-99997`, 244 attributes per feature, `CountDefault=1000`, `PagingIsTransactionSafe=FALSE`, CC0 and `Fees: none` off GetCapabilities, the 2023 sibling service, and the `startIndex=22` duplicate returning `Sterrebosbuurt` again. Every code line reference in the note lands on what it claims. It is a precise note with one sign error in it.
Sign in to join this conversation.
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#247
No description provided.