Minder data ophalen via vector-tiles (points_public) #15

Closed
opened 2026-07-20 14:46:12 +02:00 by jelmer · 0 comments
Owner

Gemigreerd uit backlog/ naar issues op 2026-07-20 — oorspronkelijk TASK-12.
Labels in het oude bord: performance.

Nu halen we voor elke datum alle ~3300 Nederlandse situaties op en filteren
we pas daarna op afstand tot de route.

Onderzocht (2026-07-18): de Melvin-API kent geen bbox-parameter.
Onbekende parameters (bbox, minLat/maxLat, …) worden stil genegeerd en
geven gewoon alle 3318 situaties terug. maps.ndw.nu/api/v1/ is een statische
tile-server (NWB/OSM/wegkenmerken) en bevat geen situatiedata; er is ook geen
publieke situatie-laag onder /api/maps-public/.

Wat wél werkt: de filterparameter roadAuthorities. Geverifieerd:
?roadAuthorities=409 (Leiden) geeft 136 in plaats van 3318 situaties.
Ook areaIds en areaBuffer staan in de frontend-filters, maar er is geen
publiek endpoint om de beschikbare areas op te vragen.

Gevonden: vector-tiles met situaties (2026-07-18)

GET /api/maps-public/points_public/{z}/{x}/{y} levert Mapbox-vector-tiles met
één punt per situatie — en tiles zijn per definitie op bbox opgevraagd. Ook
lines_public/{z}/{x}/{y} bestaat (beperkings-geometrie). Standaard XYZ-schema
(TMS-variant geeft leeg). TileJSON op /api/maps-public/points_public.

Attributen per feature: id, object_id, object_type, style.
id is het situatie-id dat /situations/by-ids verwacht — geverifieerd:
id=326497 → M390745 Reitdiepstraat, exact op de tegellocatie. object_id is
iets anders (resolveerde naar een melding 48 km verderop) — niet gebruiken.

Gemeten op de Biesbosch-route (133 km): z12 met één ring buffer = 46 tegels,
0,6 s → 238 situaties in plaats van 3318.

Belangrijke beperking

points_public bevat alleen situaties met bron MELVIN (prefix M/P). Van de
59 hits op de testroute werden er 26 gedekt; de 33 gemiste waren allemaal
extern: LTC (15, prefix E) en SPIN (18, prefix F) — waaronder de
Prinses Beatrixsluis en Molenstraat pál op de route. Blind op tiles vertrouwen
geeft dus ernstige false negatives.

Robuust algoritme (bestand tegen nieuwe bronnen)

  1. allIds voor de datum ophalen (~0,2 s, 3318).
  2. allIds&source=MELVIN ophalen (~0,2 s, 2604).
  3. nietMelvin = allIds − melvinIds (~714) → details volledig ophalen.
    Zo valt een nieuwe bron automatisch in deze groep in plaats van stil weg.
  4. Tegels langs de route ophalen → melvinBijRoute (238), snijden met
    melvinIds van stap 2.
  5. Details ophalen voor nietMelvin ∪ melvinBijRoute ≈ 950 i.p.v. 3318 (−71%).

Benodigd: een minimale MVT/protobuf-decoder in stdlib (varint + velden; is al
werkend geprototypeerd, ~40 regels) en tegelwiskunde langs de route.

Al gedaan als tussenoplossing: batchgrootte van 150 → 500 en 3 → 4 workers,
gemeten 18,1 s → 9,7 s voor een verse datum.

Definition of Done

  • #1 Merkbaar snellere check zonder gemiste meldingen op de Biesbosch-route
  • #2 Documentatie bijgewerkt

Hoe het is opgelost

Afgerond (2026-07-20). Het in de taak beschreven algoritme is gebouwd en
gemeten.

Implementatie in server.py: minimale MVT/protobuf-decoder (varint + velden,
stdlib), tegelwiskunde langs de route (z12, één ring eromheen), en
fetch_situations(datum, route) die details opvraagt voor
niet-Melvin ∪ Melvin-langs-de-route.

Metingen op de Biesbosch-route (2026-07-20): 3899 situaties totaal, 3065 met
bron MELVIN, 834 daarbuiten. 46 tegels in 0,6 s → 408 ids. Op te halen 1039
i.p.v. 3899 (−73%). Koude cache: 3,1 s i.p.v. 11,8 s.

Correctheid getoetst, dat was het punt: dezelfde route via beide paden
gedraaid en de treffers vergeleken op (displayId, km, afstand, categorie) —
identiek, nul gemist, nul extra. Herhaald met een tweede route dwars door
Amsterdam: ook identiek. Live nagemeten op productie: 57 hits, gelijk aan
lokaal.

Twee dingen anders dan in de oorspronkelijke analyse stond:

  • De tegels bevatten inmiddels óók niet-Melvin-ids (er zaten E-prefixen in).
    Dat breekt niets — niet-Melvin halen we sowieso volledig op — maar de
    aanname "alleen MELVIN" klopt niet meer.
  • Er is nu een detail-cache per situatie-id in plaats van één lijst per datum,
    zodat opeenvolgende routes op dezelfde dag elkaars opgehaalde details
    hergebruiken.

Vangnetten: mislukt een tegel, dan gaat hij terug naar alles ophalen (liever
traag dan een gemiste afsluiting). Nieuwe bronnen vallen automatisch in
alle − melvin en worden dus altijd volledig opgehaald.

> Gemigreerd uit `backlog/` naar issues op 2026-07-20 — oorspronkelijk **TASK-12**. > Labels in het oude bord: `performance`. Nu halen we voor elke datum **alle** ~3300 Nederlandse situaties op en filteren we pas daarna op afstand tot de route. **Onderzocht (2026-07-18):** de Melvin-API kent **geen bbox-parameter**. Onbekende parameters (`bbox`, `minLat/maxLat`, …) worden stil genegeerd en geven gewoon alle 3318 situaties terug. `maps.ndw.nu/api/v1/` is een statische tile-server (NWB/OSM/wegkenmerken) en bevat geen situatiedata; er is ook geen publieke situatie-laag onder `/api/maps-public/`. **Wat wél werkt:** de filterparameter **`roadAuthorities`**. Geverifieerd: `?roadAuthorities=409` (Leiden) geeft 136 in plaats van 3318 situaties. Ook `areaIds` en `areaBuffer` staan in de frontend-filters, maar er is geen publiek endpoint om de beschikbare areas op te vragen. ### Gevonden: vector-tiles met situaties (2026-07-18) `GET /api/maps-public/points_public/{z}/{x}/{y}` levert Mapbox-vector-tiles met één punt per situatie — en tiles zijn per definitie op bbox opgevraagd. Ook `lines_public/{z}/{x}/{y}` bestaat (beperkings-geometrie). Standaard XYZ-schema (TMS-variant geeft leeg). TileJSON op `/api/maps-public/points_public`. Attributen per feature: `id`, `object_id`, `object_type`, `style`. **`id` is het situatie-id** dat `/situations/by-ids` verwacht — geverifieerd: `id=326497` → M390745 Reitdiepstraat, exact op de tegellocatie. `object_id` is iets anders (resolveerde naar een melding 48 km verderop) — niet gebruiken. Gemeten op de Biesbosch-route (133 km): z12 met één ring buffer = 46 tegels, **0,6 s → 238 situaties** in plaats van 3318. ### Belangrijke beperking `points_public` bevat **alleen situaties met bron MELVIN** (prefix M/P). Van de 59 hits op de testroute werden er 26 gedekt; de 33 gemiste waren allemaal extern: **LTC** (15, prefix E) en **SPIN** (18, prefix F) — waaronder de Prinses Beatrixsluis en Molenstraat pál op de route. Blind op tiles vertrouwen geeft dus ernstige false negatives. ### Robuust algoritme (bestand tegen nieuwe bronnen) 1. `allIds` voor de datum ophalen (~0,2 s, 3318). 2. `allIds&source=MELVIN` ophalen (~0,2 s, 2604). 3. `nietMelvin = allIds − melvinIds` (~714) → details volledig ophalen. Zo valt een *nieuwe* bron automatisch in deze groep in plaats van stil weg. 4. Tegels langs de route ophalen → `melvinBijRoute` (238), snijden met `melvinIds` van stap 2. 5. Details ophalen voor `nietMelvin ∪ melvinBijRoute` ≈ 950 i.p.v. 3318 (−71%). Benodigd: een minimale MVT/protobuf-decoder in stdlib (varint + velden; is al werkend geprototypeerd, ~40 regels) en tegelwiskunde langs de route. **Al gedaan als tussenoplossing:** batchgrootte van 150 → 500 en 3 → 4 workers, gemeten 18,1 s → 9,7 s voor een verse datum. ## Definition of Done - [x] #1 Merkbaar snellere check zonder gemiste meldingen op de Biesbosch-route - [x] #2 Documentatie bijgewerkt ## Hoe het is opgelost Afgerond (2026-07-20). Het in de taak beschreven algoritme is gebouwd en gemeten. Implementatie in server.py: minimale MVT/protobuf-decoder (varint + velden, stdlib), tegelwiskunde langs de route (z12, één ring eromheen), en fetch_situations(datum, route) die details opvraagt voor niet-Melvin ∪ Melvin-langs-de-route. Metingen op de Biesbosch-route (2026-07-20): 3899 situaties totaal, 3065 met bron MELVIN, 834 daarbuiten. 46 tegels in 0,6 s → 408 ids. Op te halen 1039 i.p.v. 3899 (−73%). Koude cache: 3,1 s i.p.v. 11,8 s. **Correctheid getoetst, dat was het punt:** dezelfde route via beide paden gedraaid en de treffers vergeleken op (displayId, km, afstand, categorie) — identiek, nul gemist, nul extra. Herhaald met een tweede route dwars door Amsterdam: ook identiek. Live nagemeten op productie: 57 hits, gelijk aan lokaal. Twee dingen anders dan in de oorspronkelijke analyse stond: - De tegels bevatten inmiddels óók niet-Melvin-ids (er zaten E-prefixen in). Dat breekt niets — niet-Melvin halen we sowieso volledig op — maar de aanname "alleen MELVIN" klopt niet meer. - Er is nu een detail-cache per situatie-id in plaats van één lijst per datum, zodat opeenvolgende routes op dezelfde dag elkaars opgehaalde details hergebruiken. Vangnetten: mislukt een tegel, dan gaat hij terug naar alles ophalen (liever traag dan een gemiste afsluiting). Nieuwe bronnen vallen automatisch in alle − melvin en worden dus altijd volledig opgehaald.
Sign in to join this conversation.
No labels
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
jelmer/gpx-afsluitingen#15
No description provided.