# Verkeersborden en bereikbaarheidskaart (NDW)

Het Nationaal Dataportaal Wegverkeer houdt een landelijk bestand bij van verkeersborden: per bord de RVV-code (A1 voor een snelheidslimiet, C22a voor een milieuzone …), onderborden, kant van de weg, het NWB-wegvak, gemeente, verkeersbesluit en sinds wanneer het bord gezien is. Alleen al in Amsterdam stonden er op 16 oktober 2026 97.175 borden in. De verkeersborden-API v4 geeft het actuele beeld (dagelijks bijgewerkt) en alle wijzigingen; het hele bestand is ook te downloaden. Daarnaast een bereikbaarheidskaart die per gemeente berekent welke wegen open zijn voor een voertuig met bepaalde afmetingen, nog in bèta.

- Uitgever: Nationaal Dataportaal Wegverkeer
- Gebied: Nederland · Laagste detail: verkeersbord
- Periode: actueel beeld, plus alle gepubliceerde wijzigingen (events) · Ververst: dagelijks
- Toegang: Open · Licentie: CC0 volgens de copyrightpagina van NDW ("tenzij anders vermeld"); de API noemt zelf geen licentie
- Koppelsleutels: rvvCode, countyCode (GM…), roadSectionId (NWB-wegvak), trafficOrderUrl (verkeersbesluit)
- Status: ok (2026-10-16)
- URL: https://docs.ndw.nu/data-uitwisseling/interface-beschrijvingen/verkeersborden-api/

## Wat kun je ermee?
- **Waar begint de milieuzone?.** Er staan 615 borden C22a (milieuzone) in 64 gemeenten; Amsterdam heeft er 91, Rotterdam en Arnhem elk 73. Zet ze op de kaart en je ziet de grens van elke zone.
- **Hoeveel borden staan er in jouw gemeente?.** Vraag het actuele beeld op met countyCode (bv. GM0599 voor Rotterdam) en tel per RVV-code.
- **Van bord naar verkeersbesluit.** Een deel van de borden heeft een trafficOrderUrl zoals gmb-2024-403036: het verkeersbesluit in het Gemeenteblad. Zo controleer je of er voor elk bord een besluit is.
- **Wat verandert er op straat?.** De events-dienst geeft elke gepubliceerde wijziging met een tijdstempel, ook borden die zijn weggehaald (status REMOVED). Volg zo een gemeente die naar 30 km per uur overstapt.

## Zo verwerk je het
1. **Altijd filteren.** current-state zonder filter geeft het hele land. Alleen rvvCode=A1 is al 97 MB, Amsterdam 56 MB. Filter op rvvCode, countyCode, roadAuthorityType (R, P, G, W, T), status of bbox. Een onbekende parameter wordt stil genegeerd.
   `https://wegkenmerken.ndw.nu/api/rest/static-road-data/traffic-signs/v4/current-state?rvvCode=C22a&countyCode=GM0363`
2. **Wijzigingen bijhouden.** events geeft maximaal 100 wijzigingen per keer, oudste eerst. offset is een tijdstempel: geef het tijdstip van de laatste ontvangen wijziging mee om verder te lezen.
   `https://wegkenmerken.ndw.nu/api/rest/static-road-data/traffic-signs/v4/events?limit=100&countyCode=GM0363`
3. **Het hele bestand.** Het actuele beeld als CSV (246 MB gezipt) of GeoJSON in RD en in graden, op opendata.ndw.nu.
   `https://opendata.ndw.nu/verkeersborden_actueel_beeld.csv.gz`
4. **Bereikbaarheidskaart (bèta).** GET municipalities geeft de 342 gemeenten met hun grenzen; POST accessibility.geojson met voertuigkenmerken en een gemeente geeft de wegvakken die wel en niet toegankelijk zijn. Volgens de beschrijving alleen bedoeld voor wegbeheerders.
   `https://data.ndw.nu/api/rest/static-road-data/accessibility-map/v2/municipalities`

## Interessante koppelingen
- Welke snelheid geldt op welk wegvak? → [rws-nwb](https://www.opendataindex.nl/bron/rws-nwb.md) via roadSectionId = wvk_id (let op nwbVersion). Koppel de A1-borden (snelheidslimiet) via roadSectionId aan de wegvakken van het NWB en kleur het wegennet op de limiet.
- Borden per inwoner → [cbs-kwb](https://www.opendataindex.nl/bron/cbs-kwb.md) via countyCode (gemeentecode). Tel per gemeente de borden en deel door het aantal inwoners uit de CBS-cijfers. Grote verschillen zeggen ook iets over hoe volledig een gemeente is ingewonnen.

## Vergelijkbare bronnen
- [openstreetmap](https://www.opendataindex.nl/bron/openstreetmap.md): OSM heeft maximumsnelheden en toegangsregels als kenmerk van de weg, ingevoerd door vrijwilligers; NDW heeft de borden zelf, met foto en verkeersbesluit.
- [rws-nwb](https://www.opendataindex.nl/bron/rws-nwb.md): Het wegennet zelf; WEGGEG heeft maximumsnelheden alleen voor rijkswegen. De verkeersborden gelden voor alle wegen.
- [ndw-verkeer](https://www.opendataindex.nl/bron/ndw-verkeer.md): Live snelheden en intensiteiten van hetzelfde portaal; dit is de statische kant van de weg.

## Waar je op moet letten
- **Bèta en zonder rechten.** De bereikbaarheidskaart is volgens de eigen beschrijving in bèta, alleen bedoeld voor wegbeheerders, en er kunnen geen rechten aan worden ontleend. De situatie op straat gaat altijd voor.
- **Niet gevalideerd.** Alle 615 milieuzoneborden hadden validated = n. De borden komen uit inwinning en meldingen; een bord kan ontbreken of al weg zijn.
- **Oude adressen werken niet meer.** De oude adressen data.ndw.nu/api/rest/static-road-data/traffic-signs/v1/… geven 404. Gebruik v4 op wegkenmerken.ndw.nu.
- **Grote antwoorden.** Er is geen paginering in current-state: een gemeente of een veelvoorkomende code levert tientallen MB's op. Voor heel Nederland is het downloadbestand beter.

## API (REST (GeoJSON, JSON, CSV))

- Basis: https://wegkenmerken.ndw.nu/api/rest/static-road-data/traffic-signs/v4
- Toegang: Geen sleutel of account; alle aanroepen werkten anoniem. (getest)
- Formaten: geojson, json, csv
- Omvang: 615 milieuzoneborden C22a in het actuele beeld, in 62 gemeenten (16 okt 2026); het hele bestand is 235 MB gezipt (getest)
- Filteren: Elke voorwaarde is een eigen queryparameter; combinaties gelden als EN. Exacte overeenkomst, geen jokertekens.; =, komma = OF binnen rvvCode en roadSectionId

### Endpoints
- `GET /current-state`: Het actuele beeld: elk bord als GeoJSON-feature (of CSV), dagelijks bijgewerkt. Met een filter wordt live gefilterd, inclusief wijzigingen van vandaag. Zonder status-filter alleen geplaatste borden (PLACED).
- `GET /events`: Alle gepubliceerde wijzigingen, oudste eerst, maximaal 100 per keer; verder lezen met offset (tijdstempel).
- `GET /collections`: De ondersteunde coördinatenstelsels (CRS84 en RD, EPSG 28992).
- `GET https://wegkenmerken.ndw.nu/api/images/{id}`: Foto van het bord (JPEG, ~14 kB); het adres staat in imageUrl.
- `GET https://opendata.ndw.nu/verkeersborden_actueel_beeld.csv.gz`: Het hele actuele beeld als bestand: CSV (235 MB gezipt) of GeoJSON in RD (_rd.geojson.gz, 228 MB) en in graden (_wgs84.geojson.gz, 236 MB). Eén keer per dag rond 12:05.

### Parameters
- `countyCode`: Gemeentecode, bv. GM0363 (Amsterdam). Ander formaat (GM363) geeft 400 met de regel ^GM\d{4}$. Ook op /events. (getest)
- `rvvCode`: RVV-code van het bord (A1, C22a …); meerdere met komma's (C22a,C22c). (getest)
- `roadSectionId`: NWB-wegvak-id's; geen limiet op het aantal. (uit de beschrijving)
- `status`: Status van het bord. Zonder deze parameter kreeg je alleen PLACED; status=REMOVED gaf 407 weggehaalde milieuzoneborden. (getest)
- `roadAuthorityType`: Soort wegbeheerder als letter uit de specificatie (die legt de letters niet uit). Met G bleven er in Rotterdam 72 van de 73 C22a-borden over. (getest)
- `roadAuthorityCode`: Code van één wegbeheerder. (uit de beschrijving)
- `bbox`: Begrenzingskader; 4.88,52.36,4.92,52.38 met rvvCode=C22a gaf 2 borden. (getest)
- `bbox-crs / crs`: Stelsel van de bbox en van de antwoorden: http://www.opengis.net/def/crs/OGC/1.3/CRS84 (standaard) of http://www.opengis.net/def/crs/EPSG/9.9.1/28992 (RD). (getest)
- `contentType`: contentType=csv (of de kop Accept text/csv) geeft een platte CSV met 36 kolommen. (getest)
- `offset`: Alleen /events: publicatietijdstip vanaf waar je leest (yyyy-MM-ddTHH:mm:ss.SSSZ); standaard 1970. (uit de beschrijving)
- `limit`: Alleen /events: blokgrootte, standaard en maximaal 100 (101 geeft 400). (getest)

### Velden per bord (current-state, GeoJSON-properties) (15)
`id` uuid, `rvvCode` tekst, `blackCode` tekst, `zoneCode` tekst, `status` tekst, `validated` j/n, `textSigns` lijst, `placement / side / bearing` tekst / graden, `fraction` getal, `drivingDirection` tekst, `roadName / roadNumber / roadSectionId / nwbVersion` tekst / getal / datum, `countyCode / countyName / townName` tekst, `imageUrl` url, `firstSeenOn / lastSeenOn / placedOn / removedOn` datum, `trafficOrderUrl` tekst

### Limieten en valkuilen
- current-state heeft geen paginering: zonder filter krijg je het hele land. Alleen rvvCode=A1 is al 97 MB, Amsterdam 56 MB. Filter altijd, of neem het downloadbestand. (ervaring)
- events: hoogstens 100 per aanroep (limit=101 geeft 400). (getest)
- Geen sleutel en geen gedocumenteerde snelheidslimiet; antwoorden kwamen binnen 0,1 seconde voor een gefilterde vraag. (getest)
- De documentatie noemt nog data.ndw.nu en de parameternamen rvv-code en road-section-ids. De OpenAPI-specificatie en de werkende API gebruiken wegkenmerken.ndw.nu/api met rvvCode en roadSectionId. De oude v1-adressen op data.ndw.nu geven 404. (getest)
- Een onbekende parameter wordt stil genegeerd (foo=bar gaf gewoon 73 borden). Een tikfout in een filternaam levert dus ongemerkt het ongefilterde, veel grotere antwoord op. (getest)
- events heeft geen publicatietijdstip in het antwoord, terwijl offset daarop werkt. Bewaar zelf het moment van je laatste aanroep en lees vanaf daar verder; een event kan dan dubbel binnenkomen. (getest)
- In events heet de structuur anders dan in current-state: location.wgs84.latitude, location.road.roadSectionId, location.county.code, details.imageUrl. current-state is plat. (getest)
- Koppel roadSectionId aan het NWB (wvk_id), maar let op nwbVersion: wegvakken veranderen tussen NWB-versies. (ervaring)
- wegkenmerken.ndw.nu heeft geen robots.txt (de webapp geeft voor elk pad de startpagina terug); data.ndw.nu stuurt robots.txt door naar een pagina met Disallow: /. Daarom hebben wij de bereikbaarheidskaart niet aangeroepen. (getest)

### Voorbeeld
```
https://wegkenmerken.ndw.nu/api/rest/static-road-data/traffic-signs/v4/current-state?rvvCode=C22a&countyCode=GM0363
```

## Zo haal je het op

### curl
```bash
curl "https://wegkenmerken.ndw.nu/api/rest/static-road-data/traffic-signs/v4/current-state?rvvCode=C22a"
```

### python
```python
import requests, collections

url = "https://wegkenmerken.ndw.nu/api/rest/static-road-data/traffic-signs/v4/current-state"
borden = requests.get(url, params={"rvvCode": "C22a"}).json()["features"]
print(collections.Counter(b["properties"]["countyName"] for b in borden).most_common(10))
```

## Wat je ermee kunt bouwen
- [Dashboard met files, snelheden en wegwerkzaamheden](https://www.opendataindex.nl/bouwen/files-en-wegwerkzaamheden.md): Een dashboard dat elke minuut toont hoe hard er op de snelwegen gereden wordt, waar het stilstaat en welke wegen dicht zijn, uit de open bestanden van NDW, met de maximumsnelheid van de borden ter plaatse.


## Voorbeelden met echte cijfers (1)

Per voorbeeld de bevinding, de peildatum en de aanroep die precies deze cijfers ophaalt.

- **Verkeersborden C22a (milieuzone) per gemeente: het meest Amsterdam (91 borden), dan Rotterdam en Arnhem** (oktober 2026). Tabel traffic-signs v4 current-state, rvvCode C22a. [Voorbeeld](https://www.opendataindex.nl/voorbeeld/ndw-milieuzoneborden-gemeenten)
  - `https://wegkenmerken.ndw.nu/api/rest/static-road-data/traffic-signs/v4/current-state?rvvCode=C22a`
