303.489 datasets geïndexeerd1.419 uitgevers
Open Data IndexDe index van open data over Nederland
Open Data Index›Bouwen›Klimaatrisico-check voor een adres

Klimaatrisico-check voor een adres

Typ een postcode en huisnummer en zie in één rapport hoe het pand ervoor staat bij hitte, wateroverlast, overstroming, droogte en funderingsproblemen, met de kaarten van de Klimaateffectatlas, het AHN, de BAG en echte grondwatermetingen uit de BRO.

Je AI-assistentOpen Data Index MCP aan
De MCP-server van Open Data Index staat aan in je chat. Zo leest de assistent dit project en de bronnen zelf.
Jij plakt de prompt van dit project
De assistent haalt op bij Open Data Index
  • geef_project("klimaatrisico-adres")
  • geef_bron("klimaateffectatlas")
  • geef_bron("pdok-bag")
  • geef_bron("ahn")
De assistent

Ik heb het project, de geteste aanroepen en de valkuilen. Ik bouw een tool met Klimaateffectatlas, Basisregistratie Adressen en Gebouwen (BAG), Actueel Hoogtebestand Nederland (AHN) en Basisregistratie Ondergrond (BRO). Zo kan het eruitzien:

Dit bouw je zelf. Kopieer de prompt naar Claude, ChatGPT of Cursor, met de MCP-server aan, of volg de stappen hieronder.

Volg de stappen
Klimaatkeur

Klimaatrapport

Markt 1, 2801 JG Gouda
Bouwjaar
1459
Maaiveld
−0,17 m NAP
Peildatum
16-10-2026

Let op: modelkaarten en één meetput, geen keuring van het pand.

  • Hitteper buurt
    Gevoelstemperatuur; hitte-eiland +1,75 °C
    GevoelstemperatuurBuurt_2022
    45,3 °Cextreme hittestress
  • Overstroming> 20 cm water
    Kleine kans; dan 0,80 m water
    plaatsgebonden_overstromingskans_huidig_20_cm_20251120
    1/300tot 1/3.000 per jaar
  • Droogtegrondwater
    Gemeten 12-03-2026; model zegt 3,04 m
    BRO GMW000000005707 · 32 m
    0,92 monder maaiveld
  • Funderingper buurt
    Bodem daalt 2,2 mm per jaar
    nl_bodemdaling_totaal_v20260623
    laagpaalrot 1,73 · zetting 2,47
  • Wateroverlastrond het pand
    Na een hevige bui (99e percentiel)
    nl_fcab_omgevingsscore_wateroverlast_v20260806
    0 cmgeen hinder
Bronnen: BAG, AHN4, Klimaateffectatlas, BRO (482 putten binnen 1 km)blad 1 van 1
Mockup

Dit is een mockup, geen werkende versie, met de waarden uit onze proefdraai van 16 oktober 2026 voor het stadhuis van Gouda; de kleur van elk stoplicht is onze lezing van de klasse uit de legenda. De MCP-server zet je aan met het adres op Voor AI.

Voor wie

Huizenkopers en huiseigenaren die willen weten waar ze op moeten letten, makelaars en taxateurs, gemeenten en woningcorporaties die hun bezit willen doorlichten, en journalisten die een straat of wijk willen vergelijken.

Wat je krijgt

Een tool die bij een adres één rapport maakt met vijf risico's. Het adres gaat via de BAG naar een punt, het AHN geeft de hoogte van de grond, de Klimaateffectatlas geeft per kaart de waarde op dat punt met de klasse uit zijn eigen legenda, en de BRO geeft de echte grondwaterstand in de dichtstbijzijnde put.

Proefdraai op 16 oktober 2026 met het stadhuis van Gouda (Markt 1, bouwjaar 1459). De grond rond het stadhuis ligt op -0,17 m NAP (mediaan van 11 AHN-punten). Hitte: de buurt Nieuwe Markt e.o. heeft een gemiddelde gevoelstemperatuur van 45,3 °C op de hittekaart (extreme hittestress) en een hitte-eiland van 1,75 °C. Wateroverlast rond het pand: 0 cm. Overstroming: kleine kans (1/300 tot 1/3.000 per jaar) op meer dan 20 cm water, en bij zo'n overstroming 0,80 m water. Fundering: paalrot laag (score 1,73 per buurt), verschilzetting in 2050 laag (2,47), de bodem daalt 2,2 mm per jaar en volgens het hoge scenario 4 cm tussen 2020 en 2050. Grondwater: put GMW000000005707 op 32 m stond op 12 maart 2026 op -0,74 m NAP, 0,92 m onder het maaiveld bij de put; in het jaar ervoor tussen -1,02 en -0,26 m NAP (38.716 uurmetingen sinds 2021).

Ter vergelijking het Rijksmuseum in Amsterdam (Museumstraat 1, bouwjaar 1885): grond op +2,14 m NAP, gevoelstemperatuur in de buurt Museumplein 47,0 °C, hitte-eiland 1,86 °C, 16 cm water rond het pand na een hevige bui (klasse middel), geen overstromingskansklasse en geen waterdiepte op de overstromingskaart, paalrot en verschilzetting zeer laag, bodembeweging -1,0 mm per jaar.

Het rapport laat ook zien waar model en meting uit elkaar lopen: het landelijke grondwatermodel zegt dat de laagste grondwaterstand in Gouda 3,04 m onder het maaiveld ligt, maar de put naast het stadhuis mat in het jaar tot 12 maart 2026 nooit dieper dan 1,20 m onder het maaiveld. Voor een pand telt de meting.

Berekende gevoelstemperatuur (PET) uit de hittekaart: het hoogst in Schiermonnikoog (47,7 °C), het laagst in Zeist (38,8 °C)

Berekende gevoelstemperatuur (PET) uit de hittekaart per gemeente, 2022, in graden Celsius. Heel Nederland: 43,5. 342 gemeenten met een cijfer.

Bron: Klimaateffectatlas, WFS-laag GevoelstemperatuurBuurt_2022 (buurtgemiddelden, per gemeente samengenomen) · opgehaald 25 oktober 2026 · selectie: 14.574 buurten, per gemeente gewogen naar oppervlakOpen de tabel Los blok

Zo zou je kunnen starten7 stappen

  1. 1

    1. Van adres naar punt (BAG-WFS)

    Zoek het adres in de BAG-WFS van PDOK met een FES-filter op postcode en huisnummer. Je krijgt een punt in RD-coördinaten (EPSG:28992, in meters), het bouwjaar en de pandidentificatie. Met srsName=EPSG:4326 krijg je hetzelfde punt als lengte- en breedtegraad, nodig voor de BRO. Gebruik niet de PDOK Locatieserver: robots.txt van api.pdok.nl sluit /bzk/locatieserver/* uit; service.pdok.nl staat alles toe. Valkuil: bij nul treffers ontbreekt numberMatched in het antwoord, kijk dus naar de lijst features. En bij huisletters (12A, 12B) krijg je meer objecten.

    https://service.pdok.nl/lv/bag/wfs/v2_0?service=WFS&version=2.0.0&request=GetFeature&typeNames=bag:verblijfsobject&outputFormat=application/json&filter=<Filter xmlns%3D"http%3A%2F%2Fwww.opengis.net%2Ffes%2F2.0"><And><PropertyIsEqualTo><ValueReference>postcode<%2FValueReference><Literal>2801JG<%2FLiteral><%2FPropertyIsEqualTo><PropertyIsEqualTo><ValueReference>huisnummer<%2FValueReference><Literal>1<%2FLiteral><%2FPropertyIsEqualTo><%2FAnd><%2FFilter>
    "numberMatched": 1,
    "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::28992" } },
    "features": [
    { "type": "Feature", "properties": { "identificatie": "0513010013060645", "oppervlakte": 1311,
      "status": "Verbouwing verblijfsobject", "gebruiksdoel": "kantoorfunctie,bijeenkomstfunctie,overige gebruiksfunctie",
      "openbare_ruimte": "Markt", "huisnummer": 1, "postcode": "2801JG", "woonplaats": "Gouda", "bouwjaar": 1459,
      "pandidentificatie": "0513100011122752", "pandstatus": "Pand in gebruik" },
      "geometry": { "type": "Point", "coordinates": [ 108540.066, 447234.648 ] } }
  2. 2

    2. De hoogte van de grond (AHN)

    Vraag met WMS GetFeatureInfo op de laag dtm_05m van het AHN de hoogte ten opzichte van NAP. Gebruik een vak van 200 bij 200 meter met 200 pixels en klik met i en j. Valkuil: het BAG-punt ligt in het gebouw, en het maaiveldmodel heeft onder gebouwen geen waarde. Midden in het stadhuis (i=j=100) is de lijst leeg; 30 meter verderop (i=130) staat -0,24 m NAP. Neem daarom de mediaan van een ring punten rondom (het script gebruikt 16 punten op 30 en 60 meter). Dit is AHN4, ingewonnen in 2020 tot en met 2022.

    https://service.pdok.nl/rws/ahn/wms/v1_0?service=WMS&version=1.3.0&request=GetFeatureInfo&layers=dtm_05m&query_layers=dtm_05m&styles=&crs=EPSG:28992&bbox=108440,447135,108640,447335&width=200&height=200&i=130&j=100&info_format=application/json
    {"type":"FeatureCollection","features":[{"type":"Feature","bbox":[108568.75,447237.25,108568.75,447237.25],
     "geometry":{"type":"Point","coordinates":[108568.75,447237.25]},"properties":{"value_list":"-0.2389999926"}}], ...}
    
    met i=100&j=100 (midden in het stadhuis):
    {"type":"FeatureCollection","features":[],"crs":{"properties":{"name":"urn:ogc:def:crs:EPSG::28992"},"type":"name"}}
  3. 3

    3. Kies de juiste kaartversie (GetCapabilities)

    De WMS van de Klimaateffectatlas (GeoServer bij Sogelink, geen sleutel, 185 lagen) heeft laagnamen met een versiedatum, en oude versies blijven naast de nieuwe staan. Haal GetCapabilities op (538 kB), zoek de namen met hetzelfde begin en neem de hoogste datum op het eind (_20260128 boven _20251219; een naam zonder datum telt als oudste). Zet de gekozen laagnaam in je rapport, dan weet de lezer welke kaart het was. De lagen hebben geen omschrijving in de dienst; de uitleg staat op klimaateffectatlas.nl.

    https://cas.cloud.sogelink.com/public/data/org/gws/YWFMLMWERURF/kea_public/wms?service=WMS&request=GetCapabilities&version=1.3.0
    <Name>maximale_waterdiepte_nederland_kleine_kans_20251219</Name>
    <Name>maximale_waterdiepte_nederland_kleine_kans_20260128</Name>
    <Name>plaatsgebonden_overstromingskans_huidig_200_cm_20251120</Name>
    <Name>plaatsgebonden_overstromingskans_huidig_20_cm</Name>
    <Name>plaatsgebonden_overstromingskans_huidig_20_cm_20251120</Name>
  4. 4

    4. De waarde op je punt en de klasse uit de legenda

    GetFeatureInfo met info_format=application/json geeft bij een rasterlaag een getal (GRAY_INDEX), bij een vectorlaag de velden van het vlak. Wat dat getal betekent, staat in GetLegendGraphic met format=application/json: bij type values hoort elk getal bij één klasse (3 = kleine kans), bij type intervals krijgt een waarde de klasse van de eerste grens erboven. Vectorlagen hebben regels met een filter, zoals no_cc_risi > '0.8' AND no_cc_risi <= '3' (laag). Valkuil: nodata ziet er uit als een getal. -9999 bij de waterdiepte betekent droog of buiten het gebied, 2147483647 bij droogtestress betekent geen landbouwgrond, 55537 bij de gevoelstemperatuur betekent een gebouw, en 0 bij de overstromingskans staat niet in de legenda.

    https://cas.cloud.sogelink.com/public/data/org/gws/YWFMLMWERURF/kea_public/wms?service=WMS&version=1.3.0&request=GetFeatureInfo&layers=plaatsgebonden_overstromingskans_huidig_20_cm_20251120&query_layers=plaatsgebonden_overstromingskans_huidig_20_cm_20251120&styles=&crs=EPSG:28992&bbox=108440,447135,108640,447335&width=200&height=200&i=100&j=100&info_format=application/json
    {"type":"FeatureCollection","features":[{"type":"Feature","id":"","geometry":null,"properties":{"GRAY_INDEX":3}}],...}
    
    en de legenda (request=GetLegendGraphic&layer=…&format=application/json):
    "colormap": { "entries": [
      { "label": "Extreem kleine kans: <1/30.000 per jaar ", "quantity": "1", "color": "#619900" },
      { "label": "Zeer kleine kans: 1/3.000 tot 1/30.000 per jaar", "quantity": "2", "color": "#C5DB00" },
      { "label": "Kleine kans: 1/300 tot 1/3.000 per jaar", "quantity": "3", "color": "#FFD900" },
      { "label": "Middelgrote kans: 1/30 tot 1/300 per jaar", "quantity": "4", "color": "#FF8400" },
      { "label": "Grote kans: > 1/30 per jaar", "quantity": "5", "color": "#FF2600" } ],
      "type": "values" }
  5. 5

    5. Hitte per buurt (WFS met een punt)

    De rasterkaart van de gevoelstemperatuur heeft op een gebouw geen waarde (55537). Gebruik daarom de buurtlaag GevoelstemperatuurBuurt_2022 via de WFS met cql_filter=INTERSECTS(geometry,POINT(x y)) in RD. _mean is het gemiddelde over de rastercellen van de buurt, _count het aantal cellen. Met propertyName zonder geometrieveld laat GeoServer de geometrie weg en blijft het antwoord klein. Valkuil: de geometrie heet hier geometry, in andere lagen geom; een verkeerde naam geeft 'Illegal property name'. Welke hete dag de kaart doorrekent, staat niet in de dienst.

    https://cas.cloud.sogelink.com/public/data/org/gws/YWFMLMWERURF/kea_public/wfs?service=WFS&version=2.0.0&request=GetFeature&typeNames=kea_public:GevoelstemperatuurBuurt_2022&outputFormat=application/json&propertyName=buurtcode,buurtnaam,gemeentena,_count,_mean&cql_filter=INTERSECTS(geometry,POINT(108540.066 447234.648))
    {"type":"FeatureCollection","features":[{"type":"Feature","id":"GevoelstemperatuurBuurt_2022.fid--397ef6d2_1a14674f9af_-2df8",
     "geometry":null,"properties":{"buurtcode":"BU05130100","buurtnaam":"Nieuwe Markt e.o.","gemeentena":"Gouda",
     "_count":15648,"_mean":45.26546523517382}}],"totalFeatures":1,"numberMatched":1,"numberReturned":1,...}
  6. 6

    6. Wateroverlast per pand

    De laag nl_fcab_omgevingsscore_wateroverlast_v20260806 heeft per BAG-pand de waterdiepte rondom na een hevige bui (99e percentiel, in meters) en een klasse van 'geen hinderlijke waterdiepte' tot 'meer dan 30 cm'. GetFeatureInfo op het BAG-punt geeft het pand meteen. Valkuil: filteren op identificatie_bag via de WFS liep na 60 seconden vast op een serverfout (geen index op dat veld); zoeken met een punt kost ruim een seconde. Een ander valkuiltje: bij het Rijksmuseum vond de kaart pand 0363100012237298, terwijl de BAG bij het adres pand 0363100012157857 noemt. Beide panden bestaan; het museum bestaat uit meer panden.

    https://cas.cloud.sogelink.com/public/data/org/gws/YWFMLMWERURF/kea_public/wms?service=WMS&version=1.3.0&request=GetFeatureInfo&layers=nl_fcab_omgevingsscore_wateroverlast_v20260806&query_layers=nl_fcab_omgevingsscore_wateroverlast_v20260806&styles=&crs=EPSG:28992&bbox=120716,485801,120916,486001&width=200&height=200&i=100&j=100&info_format=application/json
    {"type":"FeatureCollection","features":[{"type":"Feature","id":"nl_fcab_omgevingsscore_wateroverlast_v20260806.2385481",
     "geometry":{"type":"Polygon","coordinates":[[[120867.5,485903.2],[120866.2,485902], ...]]},"geometry_name":"geom",
     "properties":{"identificatie_bag":"0363100012237298","bouwjaar":1885,"ahn_invliegjaar":2023,
     "waterdiepte_p99":0.156000003218651,"waterdiepte_klasse":"15 tot 20 cm"}}],"totalFeatures":"unknown",...}
  7. 7

    7. Grondwater gemeten in de buurt (BRO)

    Zoek grondwaterputten met een POST naar characteristics/searches: een cirkel om je punt (straal in kilometer, lat/lon in WGS84) en een registratieperiode. Het antwoord is XML met per put de ligging en de maaiveldhoogte (groundLevelPosition, m NAP). Meer dan 2.000 putten wordt geweigerd: binnen 1 km van het stadhuis van Gouda stonden er al 477. Daarna per put gmw-relations voor de buizen en hun grondwaterstandonderzoeken (GLD), en seriesAsCsv voor de reeks. Valkuilen: veel putten hebben geen reeks of een lege CSV (GLD000000094630 gaf 0 regels), de tijd staat in epoch-milliseconden, en er is een kolom per kwaliteitsregime. publiek.broservices.nl gaf op robots.txt een 503, er staan dus geen regels.

    curl -X POST "https://publiek.broservices.nl/gm/gmw/v1/characteristics/searches" \
      -H 'Content-Type: application/json' -d '{"registrationPeriod":{"beginDate":"1900-01-01","endDate":"2026-10-16"},"area":{"enclosingCircle":{"center":{"lat":52.0119,"lon":4.7106},"radius":1}}}'
    <numberOfDocuments>477</numberOfDocuments><dispatchDocument><GMW_C gml:id="BRO_0002">
    <brocom:broId>GMW000000005701</brocom:broId><brocom:deregistered>nee</brocom:deregistered>
    <brocom:qualityRegime>IMBRO/A</brocom:qualityRegime>
    <brocom:standardizedLocation srsName="urn:ogc:def:crs:EPSG::4258"><gml:pos>52.013343320 4.711304490</gml:pos>
    ...<groundLevelPosition uom="m">0.030</groundLevelPosition>...
    <screenPositionRange><shallowestScreenTopPosition uom="m">-1.130</shallowestScreenTopPosition>...
    
    en daarna https://publiek.broservices.nl/gm/gld/v1/seriesAsCsv/GLD000000013616:
    Tijdstip,Voorlopige Waarde [m],Voorlopige Opmerking,Beoordeelde Waarde [m],Beoordeelde Opmerking,Controle Waarde [m],...
    1615161616000,-0.789,,,,,,,
    ...
    1773302390000,-0.736,,,,,,,

Hoe de bronnen samenkomen

Laat AI het bouwen

Plak deze prompt in Claude, ChatGPT, Cursor of Lovable. Hij noemt de echte endpoints, de koppelsleutels en de valkuilen, zodat de assistent meteen werkende code schrijft. Controleer de uitkomst altijd met de bron zelf.

Bouw een webtool 'Klimaatrisico-check': de gebruiker typt een postcode en huisnummer en krijgt één rapport met vijf risico's (hitte, wateroverlast, overstroming, droogte, fundering), elk met de waarde, de klasse uit de legenda van de kaart, de naam van de kaartlaag en een korte uitleg. Plus een kaartje met het punt en een tabel met de grondwatermeting uit de dichtstbijzijnde put. Alle bronnen zijn open en zonder sleutel. Gebruik een eigen User-Agent (bijvoorbeeld 'mijn-project/1.0 (+jij@voorbeeld.nl)') in elke aanroep, en doe de aanroepen op de server (Klimaateffectatlas en BRO zijn niet als CORS-bron getest).

Stap 1, adres naar punt: BAG-WFS van PDOK, https://service.pdok.nl/lv/bag/wfs/v2_0 met service=WFS, version=2.0.0, request=GetFeature, typeNames=bag:verblijfsobject, outputFormat=application/json en een FES 2.0-filter (namespace http://www.opengis.net/fes/2.0) met PropertyIsEqualTo op postcode (zonder spatie, '2801JG') en huisnummer. Standaard in RD (EPSG:28992); met srsName=EPSG:4326 als [lon, lat]. Bij nul treffers ontbreekt numberMatched. Bij huisletters komen er meer objecten: laat de gebruiker kiezen. NIET de PDOK Locatieserver gebruiken: robots.txt van api.pdok.nl verbiedt /bzk/locatieserver/*.

Stap 2, maaiveld: AHN via https://service.pdok.nl/rws/ahn/wms/v1_0, request=GetFeatureInfo, layers=query_layers=dtm_05m, crs=EPSG:28992, bbox van 200 x 200 m rond het punt, width=height=200, i/j = pixel, info_format=application/json; de hoogte staat in properties.value_list (tekst, m NAP). Onder gebouwen is er geen waarde (lege features), dus neem de mediaan van 16 punten op 30 en 60 m rond het adres. WMS 1.3.0 met EPSG:28992: bbox is x,y (oost, noord).

Stap 3, Klimaateffectatlas: WMS https://cas.cloud.sogelink.com/public/data/org/gws/YWFMLMWERURF/kea_public/wms en WFS op .../kea_public/wfs (GeoServer). Laagnamen hebben een versiedatum (_20260128, _v20260806) en oude versies blijven staan: lees GetCapabilities en kies per kaart de hoogste datum. Gebruik deze kaarten:
- Hitte: WFS kea_public:GevoelstemperatuurBuurt_2022 met cql_filter=INTERSECTS(geometry,POINT(x y)) en propertyName=buurtnaam,_mean (gemiddelde gevoelstemperatuur per buurt in °C; klassen uit de legenda van de rasterlaag gevoelstemperatuur_2022). Plus rasterlaag hitteeiland (°C warmer dan het platteland). De rasterlaag gevoelstemperatuur_2022 zelf geeft 55537 op gebouwen: niet gebruiken op het adrespunt.
- Wateroverlast: nl_fcab_omgevingsscore_wateroverlast_v... (vector, per BAG-pand: waterdiepte_p99 in m en waterdiepte_klasse). Vraag via GetFeatureInfo of WFS INTERSECTS; een WFS-filter op identificatie_bag loopt vast (60 s, serverfout).
- Overstroming: plaatsgebonden_overstromingskans_huidig_20_cm_... (klasse 1 tot 5, type values; 0 staat niet in de legenda: toon 'geen kansklasse') en maximale_waterdiepte_nederland_kleine_kans_... (m; -9999 = droog of buiten het gebied).
- Droogte: GLG_Huidig en LG_extreemdroogjaar_Huidig (m onder maaiveld, landelijk model). droogtestress_huidig geeft 2147483647 buiten landbouwgrond: noem dat 'niet van toepassing'.
- Fundering: risicopaalrot_huidig (veld no_cc_risi) en risicoverschilzetting_2050laag (veld mild_cc_ri), per buurt; nl_bodemdaling_totaal_v... (veld snelheid, mm per jaar, negatief = daling) en bodemdaling_2020_2050hoog (m).
GetFeatureInfo: version=1.3.0, crs=EPSG:28992, bbox 200 x 200 m, width=height=200, i=j=100, info_format=application/json. Raster: properties.GRAY_INDEX. Vector: de velden van het vlak (met geometrie erbij). De betekenis haal je uit GetLegendGraphic&layer=<laag>&format=application/json: raster colormap type 'values' = exacte waarde, 'intervals' = klasse van de eerste quantity die groter of gelijk is; vector rules met een filter-tekst zoals "no_cc_risi > '3' AND no_cc_risi <= '6'". De eenheid van de paalrot- en verschilzettingsscores staat niet in de dienst: toon de score met de klasse, verzin geen eenheid.

Stap 4, BRO-grondwater: POST JSON naar https://publiek.broservices.nl/gm/gmw/v1/characteristics/searches met {"registrationPeriod":{"beginDate":"1900-01-01","endDate":"<vandaag>"},"area":{"enclosingCircle":{"center":{"lat":..,"lon":..},"radius":1}}} (straal in km). Antwoord is XML: per GMW_C broId, gml:pos (lat lon, EPSG:4258) en groundLevelPosition (m NAP). Meer dan 2.000 putten wordt geweigerd: maak de straal dan kleiner. Sorteer op afstand, vraag per put https://publiek.broservices.nl/gm/v1/gmw-relations/<GMW-id> (JSON met monitoringTubeReferences[].gldReferences[].broId) en dan https://publiek.broservices.nl/gm/gld/v1/seriesAsCsv/<GLD-id>. CSV-kolommen: Tijdstip (epoch-ms), Voorlopige Waarde [m], Beoordeelde Waarde [m], Controle Waarde [m], Onbekend Waarde [m], elk met een opmerkingskolom. Neem per regel de eerste gevulde waarde. Veel reeksen zijn leeg of oud: neem de dichtstbijzijnde put met een meting in de laatste twee jaar en toon datum, laatste stand, minimum en maximum van het jaar ervoor en de diepte onder het maaiveld van de put.

Rapport: per risico een kaartje met de klasse in kleur (de kleuren staan in de legenda-JSON), de waarde met eenheid, de laagnaam en een zin uitleg. Zet bovenaan: dit zijn modelkaarten en scenario's, per buurt of per rastercel, geen voorspelling voor dit huis. Zet onderaan de bronvermelding 'Klimaateffectatlas, 2026' (CC BY 4.0), BAG en AHN (PDOK), BRO (TNO, CC0). Laat zien als model en meting verschillen (grondwater).

Probeer het zelf

De kern van het project in een klein script. Nodig: Python 3.10+ en requests. Getest op 2026-10-16; hieronder de echte uitvoer van die proefdraai.

# Klimaatrisico-check voor een adres: hitte, wateroverlast, overstroming, droogte en fundering.
# Bronnen: BAG (PDOK WFS), AHN (PDOK WMS), Klimaateffectatlas (WMS/WFS), BRO (grondwaterputten). Geen sleutels.
import math, re, sys, statistics, requests
from datetime import datetime, timezone, timedelta

UA = {"User-Agent": "mijn-project/1.0 (+jij@voorbeeld.nl)"}
KEA = "https://cas.cloud.sogelink.com/public/data/org/gws/YWFMLMWERURF/kea_public"
POSTCODE, HUISNUMMER = (sys.argv[1], sys.argv[2]) if len(sys.argv) > 2 else ("2801JG", "1")

def get(url, **params):
    r = requests.get(url, params=params, headers=UA, timeout=90)
    r.raise_for_status()
    return r

# 1. Adres naar punt: BAG-WFS, één keer in RD (EPSG:28992) en één keer in WGS84 (lon, lat).
def bag(srs):
    f = ('<Filter xmlns="http://www.opengis.net/fes/2.0"><And>'
         f'<PropertyIsEqualTo><ValueReference>postcode</ValueReference><Literal>{POSTCODE}</Literal></PropertyIsEqualTo>'
         f'<PropertyIsEqualTo><ValueReference>huisnummer</ValueReference><Literal>{HUISNUMMER}</Literal></PropertyIsEqualTo>'
         '</And></Filter>')
    j = get("https://service.pdok.nl/lv/bag/wfs/v2_0", service="WFS", version="2.0.0", request="GetFeature",
            typeNames="bag:verblijfsobject", outputFormat="application/json", srsName=srs, filter=f).json()
    if not j["features"]:   # bij nul treffers ontbreekt numberMatched: kijk naar de lijst zelf
        sys.exit(f"Geen adres gevonden voor {POSTCODE} {HUISNUMMER}")
    return j["features"][0]   # met huisletter of toevoeging kunnen het er meer zijn

vbo = bag("EPSG:28992")
X, Y = vbo["geometry"]["coordinates"]
LON, LAT = bag("EPSG:4326")["geometry"]["coordinates"]
p = vbo["properties"]
print(f"{p['openbare_ruimte']} {p['huisnummer']}, {p['woonplaats']}: bouwjaar {p['bouwjaar']}, {p['gebruiksdoel']}")
print(f"  RD {X:.0f}, {Y:.0f}  WGS84 {LAT:.5f}, {LON:.5f}\n")

# 2. Waarde op het punt: WMS GetFeatureInfo met een vak van 200 x 200 m en de klik in het midden.
def punt(wms, laag, x=X, y=Y, i=100, j=100):
    f = get(wms, service="WMS", version="1.3.0", request="GetFeatureInfo", layers=laag, query_layers=laag, styles="",
            crs="EPSG:28992", bbox=f"{x-100},{y-100},{x+100},{y+100}", width=200, height=200, i=i, j=j,
            info_format="application/json").json()["features"]
    return f[0]["properties"] if f else None

# Maaiveld uit het AHN (DTM): onder een gebouw is er geen waarde, dus mediaan van een ring van 16 punten rondom.
ring = []
for straal in (30, 60):
    for k in range(8):
        a = k * math.pi / 4
        v = punt("https://service.pdok.nl/rws/ahn/wms/v1_0", "dtm_05m", i=100 + round(straal * math.cos(a)), j=100 - round(straal * math.sin(a)))
        if v:
            ring.append(float(v["value_list"]))
MAAIVELD = statistics.median(ring)
print(f"Maaiveld (AHN4, mediaan van {len(ring)} van 16 punten op 30 en 60 m): {MAAIVELD:+.2f} m NAP\n")

# 3. Klimaateffectatlas: kies per kaart de nieuwste versie uit GetCapabilities (laagnamen eindigen op een datum).
cap = get(f"{KEA}/wms", service="WMS", request="GetCapabilities", version="1.3.0").text
namen = set(re.findall(r"<Name>([^<]+)</Name>", cap))
def nieuwste(begin):
    kandidaten = [n for n in namen if n == begin or re.fullmatch(re.escape(begin) + r"_v?\d{8}", n)]
    return max(kandidaten, key=lambda n: re.search(r"(\d{8})$", n).group(1) if re.search(r"\d{8}$", n) else "0")

def klasse(laag, waarde, veld=None):
    """Zoek de klasse in de legenda (GetLegendGraphic als JSON)."""
    leg = get(f"{KEA}/wms", service="WMS", version="1.3.0", request="GetLegendGraphic", layer=laag, format="application/json").json()
    for rule in leg["Legend"][0]["rules"]:
        ras = rule["symbolizers"][0].get("Raster")
        if ras:   # rasterlaag: 'intervals' = eerste grens erboven, 'values' = precies gelijk
            cm = ras["colormap"]
            for e in cm["entries"]:
                q = float(e["quantity"])
                if (cm["type"] == "values" and waarde == q) or (cm["type"] != "values" and waarde <= q):
                    return e.get("label", "").strip()
            return "buiten de legenda"
        f = rule.get("filter", "")   # vectorlaag: filters als "no_cc_risi > '3' AND no_cc_risi <= '6'"
        voorwaarden = re.findall(r"(\w+) (>=|<=|>|<|=) '([^']*)'", f)
        def ok(v, op, d):
            if op == "=":
                return str(v) == d
            v, d = float(v), float(d)
            return {">=": v >= d, "<=": v <= d, ">": v > d, "<": v < d}[op]
        if voorwaarden and all(ok(waarde, op, d) for _, op, d in voorwaarden):
            return rule.get("title") or rule.get("name")
    return "?"

def kea(laag, veld="GRAY_INDEX"):
    v = punt(f"{KEA}/wms", laag)
    return None if v is None else v.get(veld)

print("HITTE")
buurt = get(f"{KEA}/wfs", service="WFS", version="2.0.0", request="GetFeature", typeNames="kea_public:GevoelstemperatuurBuurt_2022",
            outputFormat="application/json", propertyName="buurtnaam,gemeentena,_mean",
            cql_filter=f"INTERSECTS(geometry,POINT({X} {Y}))").json()["features"][0]["properties"]
print(f"  Gevoelstemperatuur (PET), gemiddeld over buurt {buurt['buurtnaam']}: {buurt['_mean']:.1f} °C ({klasse('gevoelstemperatuur_2022', buurt['_mean'])})")
hi = kea("hitteeiland")
print(f"  Stedelijk hitte-eiland: {hi:.2f} °C warmer dan het platteland ({klasse('hitteeiland', hi)})")

print("WATEROVERLAST")
l = nieuwste("nl_fcab_omgevingsscore_wateroverlast")
w = punt(f"{KEA}/wms", l)
if w:
    print(f"  Water rond pand {w['identificatie_bag']} na een hevige bui (99e percentiel): {w['waterdiepte_p99']*100:.0f} cm ({klasse(l, w['waterdiepte_klasse'])}) [{l}]")
else:
    print("  Geen pand van de wateroverlastkaart op dit punt")

print("OVERSTROMING")
l = nieuwste("plaatsgebonden_overstromingskans_huidig_20_cm")
k = kea(l)
print(f"  Kans op meer dan 20 cm water: {klasse(l, k) if k else 'waarde 0, geen kansklasse in de legenda'} [{l}]")
l = nieuwste("maximale_waterdiepte_nederland_kleine_kans")
d = kea(l)
print(f"  Waterdiepte bij een overstroming met kleine kans: {'droog of buiten het gebied' if d is None or d < 0 else f'{d:.2f} m'} [{l}]")

print("DROOGTE")
for l, wat in [("GLG_Huidig", "Grondwater in een gemiddeld droge periode (GLG)"), ("LG_extreemdroogjaar_Huidig", "Grondwater in een extreem droog jaar")]:
    v = kea(l)
    print(f"  {wat}: {v:.2f} m onder maaiveld ({klasse(l, v)})")

print("FUNDERING EN BODEMDALING")
for l, veld, wat in [("risicopaalrot_huidig", "no_cc_risi", "Risico op paalrot, huidig klimaat"),
                     ("risicoverschilzetting_2050laag", "mild_cc_ri", "Risico op verschilzetting, 2050 laag scenario")]:
    v = kea(l, veld)
    print(f"  {wat}: {v:.2f} ({klasse(l, v)}), per buurt")
l = nieuwste("nl_bodemdaling_totaal")
v = kea(l, "snelheid")
print(f"  Gemeten bodembeweging: {v:.1f} mm per jaar ({klasse(l, v)}) [{l}]")
v = kea("bodemdaling_2020_2050hoog")
print(f"  Verwachte daling 2020 tot 2050, hoog scenario: {v*100:.0f} cm ({klasse('bodemdaling_2020_2050hoog', v)})")

# 4. BRO: dichtstbijzijnde grondwaterput met een recente meetreeks.
print("GRONDWATER GEMETEN (BRO)")
xml = requests.post("https://publiek.broservices.nl/gm/gmw/v1/characteristics/searches", headers=UA, timeout=90, json={
    "registrationPeriod": {"beginDate": "1900-01-01", "endDate": datetime.now().strftime("%Y-%m-%d")},
    "area": {"enclosingCircle": {"center": {"lat": LAT, "lon": LON}, "radius": 1}}}).text   # straal in km; max 2.000 putten
putten = []
for doc in re.findall(r"<GMW_C.*?</GMW_C>", xml, re.S):
    la, lo = map(float, re.search(r"<gml:pos>([\d.]+) ([\d.]+)</gml:pos>", doc).groups())   # EPSG:4258: lat, lon
    mv = re.search(r'<groundLevelPosition uom="m">([-\d.]+)', doc)
    km = 6371 * math.hypot(math.radians(lo - LON) * math.cos(math.radians(LAT)), math.radians(la - LAT))
    putten.append((km, re.search(r"<brocom:broId>([^<]+)", doc).group(1), float(mv.group(1)) if mv else None))
print(f"  {len(putten)} putten binnen 1 km")
grens = datetime.now(timezone.utc) - timedelta(days=365)
for km, put, mv in sorted(putten)[:25]:
    rel = get(f"https://publiek.broservices.nl/gm/v1/gmw-relations/{put}").json()
    for buis in rel["monitoringTubeReferences"]:
        for gld in buis["gldReferences"]:
            csv = get(f"https://publiek.broservices.nl/gm/gld/v1/seriesAsCsv/{gld['broId']}").text.splitlines()[1:]
            reeks = []
            for regel in csv:
                c = regel.split(",")
                waarde = next((c[k] for k in (3, 1, 5, 7) if c[k]), None)   # beoordeeld, voorlopig, controle, onbekend
                if waarde:
                    reeks.append((datetime.fromtimestamp(int(c[0]) / 1000, timezone.utc), float(waarde)))
            recent = [w for t, w in reeks if t >= reeks[-1][0] - timedelta(days=365)] if reeks else []
            if reeks and reeks[-1][0] >= grens - timedelta(days=365):
                t, laatst = reeks[-1]
                print(f"  Put {put} ({km*1000:.0f} m), buis {buis['tubeNumber']}, reeks {gld['broId']}: {len(reeks)} metingen, {reeks[0][0]:%Y} tot {t:%d-%m-%Y}")
                print(f"  Laatste stand {laatst:+.2f} m NAP; laagste in het jaar ervoor {min(recent):+.2f}, hoogste {max(recent):+.2f} m NAP")
                if mv is not None:
                    print(f"  Dat is {mv - laatst:.2f} m onder het maaiveld bij de put ({mv:+.2f} m NAP volgens de BRO)")
                raise SystemExit
print("  Geen put met een meetreeks van de afgelopen twee jaar gevonden")
Uitvoer
Markt 1, Gouda: bouwjaar 1459, kantoorfunctie,bijeenkomstfunctie,overige gebruiksfunctie
  RD 108540, 447235  WGS84 52.01153, 4.71047

Maaiveld (AHN4, mediaan van 11 van 16 punten op 30 en 60 m): -0.17 m NAP

HITTE
  Gevoelstemperatuur (PET), gemiddeld over buurt Nieuwe Markt e.o.: 45.3 °C (Extreme Hittestress (niveau 1): 44°C – 45°C)
  Stedelijk hitte-eiland: 1.75 °C warmer dan het platteland (1.6-1.8 °C)
WATEROVERLAST
  Water rond pand 0513100011122752 na een hevige bui (99e percentiel): 0 cm (Geen hinderlijke waterdiepte) [nl_fcab_omgevingsscore_wateroverlast_v20260806]
OVERSTROMING
  Kans op meer dan 20 cm water: Kleine kans: 1/300 tot 1/3.000 per jaar [plaatsgebonden_overstromingskans_huidig_20_cm_20251120]
  Waterdiepte bij een overstroming met kleine kans: 0.80 m [maximale_waterdiepte_nederland_kleine_kans_20260128]
DROOGTE
  Grondwater in een gemiddeld droge periode (GLG): 3.04 m onder maaiveld (> 2,0m)
  Grondwater in een extreem droog jaar: 3.14 m onder maaiveld (> 2,0m)
FUNDERING EN BODEMDALING
  Risico op paalrot, huidig klimaat: 1.73 (Laag), per buurt
  Risico op verschilzetting, 2050 laag scenario: 2.47 (Laag), per buurt
  Gemeten bodembeweging: -2.2 mm per jaar (Beperkt (1.5 tot 5 mm/jaar daling)) [nl_bodemdaling_totaal_v20260623]
  Verwachte daling 2020 tot 2050, hoog scenario: 4 cm (Beperkt (3-10cm))
GRONDWATER GEMETEN (BRO)
  482 putten binnen 1 km
  Put GMW000000005707 (32 m), buis 1, reeks GLD000000013616: 38716 metingen, 2021 tot 12-03-2026
  Laatste stand -0.74 m NAP; laagste in het jaar ervoor -1.02, hoogste -0.26 m NAP
  Dat is 0.92 m onder het maaiveld bij de put (+0.18 m NAP volgens de BRO)

Waar het misgaat

  • Modelkaarten, geen voorspelling voor dit huis. De Klimaateffectatlas rekent scenario's door op een raster of per buurt. Paalrot en verschilzetting zijn scores per buurt; een eeuwenoud stadhuis in een buurt met 'laag' kan zelf wel op houten palen staan. Zeg dat bovenaan je rapport.
  • Nodata vermomd als getal: -9999 (waterdiepte: droog of buiten het gebied), 2147483647 (droogtestress: geen landbouwgrond), 55537 (gevoelstemperatuur: gebouw), 0 bij de overstromingskans (niet in de legenda). Behandel alles wat niet in de legenda past als 'geen waarde', niet als risico.
  • Laagnamen veranderen bij elke update (_20251219 werd _20260128) en oude versies blijven staan. Hardcode geen laagnaam: kies per kaart de nieuwste uit GetCapabilities en toon welke het werd.
  • Het adrespunt ligt in het gebouw. Daar is het AHN-maaiveld leeg en geeft de hitte-rasterkaart geen waarde. Kijk rond het pand (ring van punten) of gebruik de buurtlaag.
  • Model en meting lopen uiteen. Het landelijke grondwatermodel gaf in Gouda een laagste stand van 3,04 m onder maaiveld; de put 32 m verderop mat tussen maart 2025 en maart 2026 hooguit 1,2 m. Toon beide en zeg welke wat is.
  • BRO-putten zonder reeks of met een oude reeks zijn de regel, niet de uitzondering. De dichtstbijzijnde put bij het stadhuis (GMW000000092160, 24 m) had een lege CSV; in Amsterdam was de dichtstbijzijnde bruikbare reeks (25 metingen) van april 2025. Zoek door tot een put met recente metingen en zet de datum erbij.
  • Attribuutfilters op grote vectorlagen van de Klimaateffectatlas (zoals identificatie_bag op de wateroverlastkaart) lopen vast op een serverfout na 60 seconden. Zoek altijd ruimtelijk (GetFeatureInfo of INTERSECTS met een punt).

Verder bouwen

  • Scenario's naast elkaar: dezelfde kaarten bestaan vaak voor nu, 2050 en 2085 of 2100 (risicopaalrot_2050hoog, GLG_2085Hoog, plaatsgebonden_overstromingskans_norm_plus_klimaatverandering_2100_...). Laat per risico zien hoe het verschuift.
  • Een hele straat of wijk: haal alle verblijfsobjecten van een postcode op uit de BAG en zet de wateroverlastklasse per pand op een kaart. Let op het tempo: één aanroep per pand, wees zuinig.
  • De grondwaterreeks naast de neerslag: zet de reeks uit de BRO naast de dagneerslag van het dichtstbijzijnde KNMI-station (knmi-daggegevens) en laat zien hoe snel het grondwater na een droge zomer herstelt.
  • Wat zit er onder de grond: zoek sonderingen (CPT) in de BRO rond het adres (/sr/cpt/v1/characteristics/searches) en toon tot welke diepte de slappe lagen lopen. Dat zegt meer over funderingsrisico dan een buurtscore.

Meer met deze data

Grondwatermonitoringputten in de BRO naar bouwjaar: 2.786 putten in 2025, 2,2 keer zo veel als in 1990

Grondwatermonitoringputten in de BRO naar bouwjaar, 1990 – 2025, in putten. Het hoogste punt was 2022 (3.698).

Bron: TNO, Basisregistratie Ondergrond: grondwatermonitoring in samenhang via PDOK (OGC API) · opgehaald 25 oktober 2026 · selectie: 97.900 putten in de BRO; 2.186 zonder bouwjaar, 12.001 inmiddels verwijderd (tellen mee bij hun bouwjaar); alleen volle jarenOpen de tabel Los blok

De bronnen4

Klimaateffectatlas

Stichting Climate Adaptation Services (CAS), in opdracht van het ministerie van IenWNederland, buurt of rastercel

Landelijke kaarten van wat klimaatverandering in Nederland doet: gevoelstemperatuur, droogte, grondwater, bodemdaling, waterdiepte bij een overstroming en bij extreme regen. Vaak voor nu en voor 2050, 2085 of 2100. Er is ook een buurtdashboard met cijfers per buurt. Te gebruiken als kaartlaag (WMS), als vectordata (WFS) en als download.

OpenKaartlaagDownloadAPIKlimaat en milieuWonen en ruimte
Actueel
bijgewerkt in augustus 2026

Basisregistratie Adressen en Gebouwen (BAG)

Kadaster, via PDOKNederland, adres en gebouw

Alle adressen en gebouwen van Nederland met bouwjaar, oppervlakte en gebruiksdoel. De ruggengraat voor alles wat op adresniveau gekoppeld moet worden.

OpenKaartlaagAPIDownloadWonen en ruimte
Bereikbaar
dagelijks

Actueel Hoogtebestand Nederland (AHN)

Het Waterschapshuis namens waterschappen, provincies en Rijk; via PDOKNederland, 0,5 meter

De hoogtekaart van Nederland, gemeten met een laser vanuit een vliegtuig: minstens tien metingen per vierkante meter. Er zijn twee kaarten. Het maaiveldmodel (DTM) is de kale grond. Het oppervlaktemodel (DSM) is alles wat erop staat, met gebouwen en bomen. Via PDOK als kaartlaag (WMS), als API voor rasters (WCS) en als download.

OpenKaartlaagDownloadWonen en ruimteKlimaat en milieu
Actueel
bijgewerkt in april 2023

Basisregistratie Ondergrond (BRO)

TNO Geologische Dienst Nederland, namens het ministerie van BZK; kopie via PDOKNederland, meetpunt (sondering, boring, put)

De landelijke registratie van wat er onder de grond zit en gemeten wordt: sonderingen, geologische, bodemkundige en geotechnische boringen, grondwatermonitoringputten met hun meetreeksen (soms vanaf de jaren 1950), grondwatersamenstelling, onttrekkingen en mijnbouwvergunningen. Bestuursorganen moeten hun onderzoek hier laten registreren; TNO beheert de landelijke voorziening namens het ministerie van BZK. Veertien REST-diensten op publiek.broservices.nl, elk met een OpenAPI-beschrijving, plus een kopie op PDOK. Op 16 oktober 2026 stonden er 97.768 grondwatermonitoringputten in.

OpenAPIKaartlaagDownloadKlimaat en milieuWonen en ruimte
Actueel
bijgewerkt gisteren

Meer om te bouwen