303.489 datasets geïndexeerd1.419 uitgevers
Open Data IndexDe index van open data over Nederland
Open Data Index›Bouwen›Natuur in je buurt: welke soorten zijn er gezien en hoe groen is het?

Natuur in je buurt: welke soorten zijn er gezien en hoe groen is het?

Een app die voor elk punt in Nederland laat zien welke planten en dieren er in een straal van 1 km zijn waargenomen, hoeveel van de grond groen is en hoe ver het dichtstbijzijnde Natura 2000-gebied ligt.

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("biodiversiteit-buurt")
  • geef_bron("gbif")
  • geef_bron("esa-worldcover")
  • geef_bron("natura2000")
De assistent

Ik heb het project, de geteste aanroepen en de valkuilen. Ik bouw een app met GBIF biodiversiteit, ESA WorldCover en Natura 2000-gebieden. 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
10:24
Vondelpark, Amsterdam1 km
2021–2025
Om je heen gezien21.279waarnemingen van 486 soorten
95% vogelsNatura 2000 · 7,6 km
31%groen
  • bebouwd65,7%
  • bomen28,5%
  • gras2,7%
  • water2,6%

Meest gezien alle 486 →

1MeerkoetFulica atra1.168×
2HalsbandparkietPsittacula krameri1.161×
3NijlgansAlopochen aegyptiaca1.068×
4WaterhoenGallinula chloropus1.061×
Ede, rand Veluwe399 waarnemingen · 85% groenvergelijk
Mockup

Dit is een mockup, geen werkende versie, met de cijfers uit onze proefdraai van 16 oktober 2026 voor het Vondelpark (GBIF 2021–2025, ESA WorldCover 2021, Natura 2000 van PDOK). De MCP-server zet je aan met het adres op Voor AI.

Voor wie

Buurtbewoners en wijkraden die willen weten wat er rond hun huis leeft, scholen (een buurtonderzoek met echte data), groenvrijwilligers, gemeenten die groen en biodiversiteit per wijk willen vergelijken, en makers van een 'natuur-om-de-hoek'-widget.

Wat je krijgt

Een script (en daarna een kaartje met zoekveld) dat voor een punt de waarnemingen uit GBIF telt, de soorten en groepen met Nederlandse namen toont, het vak van waarneming.nl erbij zoekt, Natura 2000-gebieden binnen 10 km noemt en het grondgebruik binnen 1 km uitrekent.

Proefdraai op 16 oktober 2026 voor het Vondelpark in Amsterdam (52,358 N, 4,8686 O): binnen 1 km in 2021 tot en met 2025 21.279 waarnemingen van 486 soorten. 95% waren vogels (20.138), vooral uit eBird (83%). Meest gezien: meerkoet (1.168), halsbandparkiet (1.161), nijlgans (1.068) en waterhoen (1.061). Waarneming.nl staat in GBIF alleen op vakken van 0,05 graad: in het vak rond het Vondelpark 64.595 waarnemingen van 2.444 soorten. Het grondgebruik binnen 1 km (ESA WorldCover 2021): 65,7% bebouwd, 28,5% bomen, 2,7% gras, 2,6% water, samen 31% groen. Het dichtstbijzijnde Natura 2000-gebied is Markermeer & IJmeer op 7,6 km.

Ter vergelijking een punt in Ede aan de rand van de Veluwe (52,040 N, 5,690 O, Burgemeestersbuurt): maar 399 waarnemingen van 236 soorten binnen 1 km, maar 85% groen (75,0% bomen) en de Veluwe op 0,3 km. Minder waarnemingen betekent hier niet minder natuur, maar minder mensen die iets doorgeven.

Waarnemingen uit Nederland in GBIF per klasse: het meest vogels (5.567.722 waarnemingen), dan insecten en tweezaadlobbigen

Waarnemingen uit Nederland in GBIF per klasse, 2025, in waarnemingen. Totaal: 12.496.874; de grootste 12 van 123 categorieën staan in de grafiek. Vogels is 45% van het totaal. Ingedeeld naar klasse; het totaal telt ook records zonder klasse. Eén record is één waarneming van een soort, soms van meerdere exemplaren tegelijk.

Bron: GBIF, occurrence search (facet classKey, land NL) · opgehaald 25 oktober 2026Open de tabel Los blok

Zo zou je kunnen starten7 stappen

  1. 1

    Tel de waarnemingen rond je punt

    De GBIF-zoek-API (api.gbif.org/v1, geen sleutel, robots.txt staat het toe) heeft een parameter geoDistance=breedte,lengte,afstand. Met limit=0 krijg je geen records maar wel het aantal, en met facet= de verdeling over soorten (speciesKey), groepen (classKey) of datasets. Zet facetLimit hoog genoeg om alle soorten te tellen (5.000 is ruim voor 1 km). Filter op een periode (year=2021,2025) en op occurrenceStatus=PRESENT, anders tellen 'niet gevonden'-records van tellingen mee. De groepen zijn sleutels: 212 is vogels (Aves), 220 tweezaadlobbigen (Magnoliopsida), 216 insecten.

    https://api.gbif.org/v1/occurrence/search?geoDistance=52.358,4.8686,1km&limit=0&facet=classKey&facetLimit=10&occurrenceStatus=PRESENT&year=2021,2025
    {"offset":0,"limit":0,"endOfRecords":false,"count":21279,"results":[],"facets":[{"field":"CLASS_KEY","counts":[
     {"name":"212","count":20138},{"name":"220","count":735},{"name":"216","count":208},{"name":"196","count":99},
     {"name":"186","count":37},{"name":"367","count":8},{"name":"179","count":6},{"name":"180","count":6},...]}]}
  2. 2

    Kijk uit welke datasets het komt

    Met facet=datasetKey zie je wie de waarnemingen leverde. Rond het Vondelpark kwam 83% uit eBird (vogelaars), 11% uit iNaturalist en 2% uit Birda; samen 14 datasets. Dat verklaart waarom vogels domineren. Licenties verschillen per dataset: eBird is CC BY 4.0, iNaturalist, Birda en Observation.org zijn CC BY-NC 4.0 (niet commercieel). Wil je records doorgeven of publiceren, vermeld dan de datasets, of maak een download met DOI via gbif.org.

    https://api.gbif.org/v1/dataset/50c9509d-22c7-4a22-a47d-8c48425ef4a7
    facet=datasetKey: [('4fa7b334', 17736), ('50c9509d', 2446), ('6ff8b3b0', 498), ('14d5676a', 343), ('7a3679ef', 106), ...]  14 datasets
    EOD – eBird Observation Dataset | http://creativecommons.org/licenses/by/4.0/legalcode
    iNaturalist Research-grade Observations | http://creativecommons.org/licenses/by-nc/4.0/legalcode
    Birda - Global Observation Dataset | http://creativecommons.org/licenses/by-nc/4.0/legalcode
    Pl@ntNet automatically identified occurrences | http://creativecommons.org/licenses/by/4.0/legalcode
  3. 3

    Geef soorten een Nederlandse naam

    Een facet geeft alleen sleutels. /species/<sleutel> geeft de wetenschappelijke naam, /species/<sleutel>/vernacularNames alle volksnamen met taalcode; neem de eerste met language nld. Die lijst is gepagineerd (de meerkoet heeft er meer dan 200), dus vraag limit=500. Voor grote groepen als Magnoliopsida, Liliopsida en Agaricomycetes is er geen Nederlandse naam: toon dan de wetenschappelijke, of zet zelf een vertaaltabel neer. Cache de namen, want ze veranderen zelden.

    https://api.gbif.org/v1/species/2479226/vernacularNames?limit=200
    2474377 Fulica atra Eurasian Coot Aves         endOfRecords False, 200 namen  [('Meerkoet', 'EUNIS Biodiversity Database'), ...]
    2479226 Psittacula krameri Rose-ringed Parakeet Aves   True, 152  [('Halsbandparkiet', 'EUNIS Biodiversity Database'), ('Halsbandparkiet', 'Catalogue of Life'), ...]
    2498252 Alopochen aegyptiaca Egyptian Goose Aves       True, 106  [('Nijlgans', 'Catalogue of Life'), ...]
    5228199 Gallinula chloropus Eurasian Moorhen Aves      True, 197  [('Waterhoen', 'EUNIS Biodiversity Database'), ...]
  4. 4

    Zoek waarneming.nl op zijn eigen raster

    Waarneming.nl (Observation.org) is de grootste Nederlandse bron in GBIF: 107.932.072 records in Nederland. Maar de coördinaten zijn afgerond met floor(coord * 20) / 20, op vakken van 0,05 graad (ongeveer 5,6 km noord-zuid en 3,4 km oost-west), met coordinateUncertaintyInMeters 5000. Binnen 1 km van het Vondelpark kwam daardoor geen enkel record van waarneming.nl terug. Zoek het vak waar je punt in valt met decimalLatitude en decimalLongitude precies op de afgeronde waarden (52,35 en 4,85 voor het Vondelpark): 64.595 waarnemingen van 2.444 soorten in 2021 tot en met 2025. Een polygoon om het vak werkt niet: dan tellen de hoekpunten van de buurvakken mee (258.334).

    https://api.gbif.org/v1/occurrence/search?datasetKey=8a863029-f435-446a-821e-275f4f641165&decimalLatitude=52.35&decimalLongitude=4.85&year=2021,2025&occurrenceStatus=PRESENT&limit=1
    {"count": 64595}
    {"species": "Anas platyrhynchos", "vernacularName": "Domestic Duck", "decimalLatitude": 52.35, "decimalLongitude": 4.85,
     "coordinateUncertaintyInMeters": 5000.0,
     "dataGeneralizations": "WGS84 coordinates generalized with formula: `coord = floor(coord * 20) / 20`",
     "eventDate": "2025-01-02", "license": "http://creativecommons.org/licenses/by-nc/4.0/legalcode"}
  5. 5

    Natura 2000 in de buurt

    De PDOK-WFS van Natura 2000 (CC0) filtert op een bbox; met srsName=EPSG:4326 en de bbox in breedte,lengte-volgorde plus urn:ogc:def:crs:EPSG::4326. Deze MapServer-WFS geeft altijd de volledige omtrek mee, ook als je weinig velden vraagt: een vak van 20 bij 20 km rond Ede was 7,0 MB, omdat de hele Veluwe en de hele Rijntakken meekomen. Houd de bbox dus klein. Eén gebied kan uit meerdere objecten bestaan (Vogelrichtlijn, Habitatrichtlijn of beide, beschermin VR, HR of VR+HR): voeg samen op nr. Afstand en 'erin of niet' reken je zelf uit met de omtrek.

    https://service.pdok.nl/rvo/natura2000/wfs/v1_0?service=WFS&version=2.0.0&request=GetFeature&typeNames=natura2000:natura2000&outputFormat=application/json&srsName=EPSG:4326&bbox=51.950,5.544,52.130,5.836,urn:ogc:def:crs:EPSG::4326
    HTTP 200, 7.024.945 bytes, 2,3 s, 4 features
    {"naamN2K": "Binnenveld", "vhnNew": 2, "nr": 65, "beschermin": "HR", "sitecodeH": "NL2003006", "status": "Natura 2000-besluit 30 april 2014", ...} MultiPolygon
    {"naamN2K": "Veluwe", "vhnNew": 3, "nr": 57, "beschermin": "VR+HR", "sitecodeV": "NL3009017", "sitecodeH": "NL9801023", ...} MultiPolygon
    {"naamN2K": "Rijntakken", "vhnNew": 1, "nr": 38, "beschermin": "VR", ...} MultiPolygon
    {"naamN2K": "Rijntakken", "vhnNew": 3, "nr": 38, "beschermin": "VR+HR", ...} MultiPolygon
  6. 6

    Vind de WorldCover-tegel

    ESA WorldCover (10 m, CC BY 4.0) is via Microsoft Planetary Computer te gebruiken zonder account. De VITO-kaartdienst gaf in oktober 2026 alleen fouten. Zoek met STAC welke tegel je punt bevat: je krijgt er twee, 2020 (v100) en 2021 (v200). Neem 2021; nieuwere jaargangen komen er niet. De klassen met hun naam staan in het asset map onder classification:classes, dus je hoeft ze niet zelf in te tikken.

    curl -X POST "https://planetarycomputer.microsoft.com/api/stac/v1/search" \
      -H 'Content-Type: application/json' -d '{"collections":["esa-worldcover"],"intersects":{"type":"Point","coordinates":[4.8686,52.358]},"limit":5}'
    2 items: ESA_WorldCover_10m_2021_v200_N51E003 (2.0.0, 2021-01-01T00:00:00Z) en ESA_WorldCover_10m_2020_v100_N51E003 (1.0.0)
    "classification:classes": [{"value": 10, "color-hint": "006400", "description": "Tree cover"},
     {"value": 20, ... "Shrubland"}, {"value": 30, ... "Grassland"}, {"value": 40, ... "Cropland"},
     {"value": 50, ... "Built-up"}, {"value": 60, ... "Bare / sparse vegetation"}, {"value": 70, ... "Snow and ice"},
     {"value": 80, ... "Permanent water bodies"}, {"value": 90, ... "Herbaceous wetland"}, {"value": 95, ... "Mangroves"},
     {"value": 100, ... "Moss and lichen"}]
  7. 7

    Reken het grondgebruik binnen 1 km uit

    POST een GeoJSON-Feature (een cirkel van 64 punten) naar het statistics-eindpunt met categorical=true: je krijgt een histogram met het aantal pixels per klasse. Zet max_size=1024 erbij; voor een cirkel van 1 km ging het ook zonder, maar bij grotere vlakken gaf de dienst zonder max_size een 502. Reken met percentages: de pixels zijn in graden, niet in vierkante meters (60.242 geldige pixels voor 3,1 km²). WorldCover is de stand van 2021 en een model: in het Vondelpark staat 0,4% 'akker'.

    curl -X POST "https://planetarycomputer.microsoft.com/api/data/v1/item/statistics?collection=esa-worldcover&item=ESA_WorldCover_10m_2021_v200_N51E003&assets=map&categorical=true&max_size=1024" \
      -H 'Content-Type: application/json' -d '{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[4.8686,52.366983],[4.870042,52.36694],"... 64 punten op 1 km rond het Vondelpark ...",[4.8686,52.366983]]]}}'
    {"type":"Feature","geometry":{...},"properties":{"statistics":{"map_b1":{"min":10.0,"max":90.0,"mean":38.79170678264334,
     "count":60242.0, ... "majority":50.0,"minority":90.0,"unique":6.0,"valid_percent":78.78,"masked_pixels":16222.0,
     "valid_pixels":60242.0, ...
     "histogram":[[17185.0,1656.0,233.0,39592.0,1540.0,36.0],[10.0,30.0,40.0,50.0,80.0,90.0]]}}}}

Hoe de bronnen samenkomen

  • GBIF biodiversiteitESA WorldCovervia punt en straal (dezelfde cirkel van 1 km)

    Zet het aantal soorten naast het aandeel groen. Pas op met conclusies: het aantal waarnemingen hangt vooral af van hoeveel mensen er kijken. Het Vondelpark (31% groen) had 486 soorten in GBIF, het punt in Ede (85% groen) 236.

  • GBIF biodiversiteitNatura 2000-gebiedenvia afstand van het punt tot de omtrek

    Zoek in GBIF ook de waarnemingen binnen het Natura 2000-gebied zelf (geometry= met een vereenvoudigde omtrek, tegen de klok in) en toon welke soorten je even verderop kunt zien.

  • ESA WorldCoverWijk- en buurtkaartvia buurtgrens als vlak

    Gebruik in plaats van een cirkel de buurtgrens van CBS/PDOK als vlak in het statistics-eindpunt. Dan kun je groen per buurt vergelijken met de cijfers van de buurt (inwoners, woningen).

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 webapp 'Natuur in je buurt'. De gebruiker klikt op een kaart (of zoekt een adres) en ziet binnen 1 km: hoeveel waarnemingen en soorten er zijn, de verdeling over groepen, de meest geziene soorten met Nederlandse naam, hoeveel van de grond groen is, en het dichtstbijzijnde Natura 2000-gebied. Geen sleutels nodig. Stuur in elke aanroep een eerlijke User-Agent mee.

1. Waarnemingen (GBIF): GET https://api.gbif.org/v1/occurrence/search?geoDistance=LAT,LON,1km&year=2021,2025&occurrenceStatus=PRESENT&limit=0&facet=speciesKey&facet=classKey&facet=datasetKey&facetLimit=5000. Het antwoord heeft count en facets[].counts[] met {name: sleutel, count}. Aantal soorten = lengte van de speciesKey-lijst.
2. Namen: GET https://api.gbif.org/v1/species/KEY (canonicalName) en https://api.gbif.org/v1/species/KEY/vernacularNames?limit=500, eerste met language 'nld'. Grote groepen als Magnoliopsida hebben geen Nederlandse naam: toon de wetenschappelijke of gebruik een eigen tabel. Cache alle namen.
3. Waarneming.nl: dataset 8a863029-f435-446a-821e-275f4f641165 heeft coördinaten afgerond met floor(coord*20)/20 (vakken van 0,05 graad, onzekerheid 5 km). Binnen 1 km vind je ze meestal niet. Vraag apart het vak op met decimalLatitude=floor(LAT*20)/20 en decimalLongitude=floor(LON*20)/20 (exacte waarden, geen polygoon) en toon dat als 'in de wijde omgeving (vak van ongeveer 5,6 bij 3,4 km)'.
4. Natura 2000: GET https://service.pdok.nl/rvo/natura2000/wfs/v1_0?service=WFS&version=2.0.0&request=GetFeature&typeNames=natura2000:natura2000&outputFormat=application/json&srsName=EPSG:4326&bbox=LAT1,LON1,LAT2,LON2,urn:ogc:def:crs:EPSG::4326 (let op: breedte eerst). De omtrek komt altijd mee (megabytes bij de Veluwe): bbox hooguit 10 km en het antwoord cachen. Voeg objecten samen op nr; beschermin is VR, HR of VR+HR. Reken afstand en punt-in-vlak zelf (of met turf.js).
5. Groen: POST https://planetarycomputer.microsoft.com/api/stac/v1/search met {"collections":["esa-worldcover"],"intersects":{"type":"Point","coordinates":[LON,LAT]}}; neem het item met de hoogste esa_worldcover:product_version (2021, v200). Klassen staan in assets.map['classification:classes']. Daarna POST https://planetarycomputer.microsoft.com/api/data/v1/item/statistics?collection=esa-worldcover&item=ITEM_ID&assets=map&categorical=true&max_size=1024 met een GeoJSON-Feature (cirkel van 64 punten, [lon, lat]). properties.statistics.map_b1.histogram = [[aantallen],[klassewaarden]]. Groen = 10 bomen, 20 struiken, 30 gras, 90 moeras, 100 mos. Reken in procenten.

Valkuilen die de app moet uitleggen: meer waarnemingen betekent vooral meer kijkers (stadsparken en vogelaars), niet meer natuur; vogels domineren (rond het Vondelpark 95%) omdat eBird de grootste bron is; licenties verschillen per dataset (iNaturalist en waarneming.nl CC BY-NC); WorldCover is de stand van 2021 en een model met fouten (akker in een stadspark); de Natura 2000-afstand is een benadering.

Uitkomst: kaart met de cirkel, een donut met grondgebruik, een staafje per groep, een lijst van de 10 meest geziene soorten (Nederlandse naam, wetenschappelijke naam, aantal, link naar gbif.org/species/KEY), de regel 'Natura 2000: Veluwe op 0,3 km', en onderaan de bronnen met licentie.

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.

# Biodiversiteit in je buurt: welke soorten zijn er gezien (GBIF), hoe groen is het (ESA WorldCover) en ligt er
# Natura 2000 in de buurt (PDOK)? Geen sleutels nodig. Vereist: Python 3.10+ en requests.
import math, sys
import requests

LAT, LON, STRAAL = 52.358, 4.8686, 1.0          # Vondelpark, Amsterdam; straal in km
if len(sys.argv) == 3:
    LAT, LON = float(sys.argv[1]), float(sys.argv[2])
JAREN = "2021,2025"
UA = {"User-Agent": "mijn-project/1.0 (+jij@voorbeeld.nl)"}
GBIF = "https://api.gbif.org/v1"
get = lambda url, **p: requests.get(url, params=p, headers=UA, timeout=120).json()

def naam(key):   # Nederlandse naam als die er is, anders de wetenschappelijke
    s = get(f"{GBIF}/species/{key}")
    nl = [v["vernacularName"] for v in get(f"{GBIF}/species/{key}/vernacularNames", limit=500)["results"] if v.get("language") == "nld"]
    return (nl[0].lower() if nl else s.get("canonicalName", key)), s.get("canonicalName", "")

# 1. Waarnemingen binnen de straal, alle datasets (geoDistance = breedte,lengte,afstand).
basis = {"geoDistance": f"{LAT},{LON},{STRAAL}km", "year": JAREN, "occurrenceStatus": "PRESENT", "limit": 0}
r = get(f"{GBIF}/occurrence/search", **basis, facet=["speciesKey", "classKey", "datasetKey"], facetLimit=5000)
f = {x["field"]: x["counts"] for x in r["facets"]}
print(f"GBIF, {STRAAL:g} km rond {LAT}, {LON}, jaren {JAREN.replace(',', '-')}: {r['count']} waarnemingen, {len(f['SPECIES_KEY'])} soorten")
print("  per groep:", ", ".join(f"{naam(c['name'])[0]} {c['count']}" for c in f["CLASS_KEY"][:5]))
print("  uit:", ", ".join(f"{get(f'{GBIF}/dataset/{d['name']}')['title'][:40]} ({d['count'] / r['count']:.0%})" for d in f["DATASET_KEY"][:3]))
print("  meest gezien:")
for s in f["SPECIES_KEY"][:8]:
    nl, wet = naam(s["name"])
    print(f"    {s['count']:6}  {nl} ({wet})")

# 2. Waarneming.nl (Observation.org) staat in GBIF met coördinaten afgerond op 0,05 graad: zoek je eigen cel.
cel = (math.floor(LAT * 20) / 20, math.floor(LON * 20) / 20)
o = get(f"{GBIF}/occurrence/search", datasetKey="8a863029-f435-446a-821e-275f4f641165", decimalLatitude=cel[0],
        decimalLongitude=cel[1], year=JAREN, occurrenceStatus="PRESENT", limit=0, facet="speciesKey", facetLimit=10000)
print(f"\nWaarneming.nl in het vak {cel[0]:.2f}-{cel[0] + .05:.2f} N, {cel[1]:.2f}-{cel[1] + .05:.2f} O (ongeveer 5,6 bij 3,4 km): "
      f"{o['count']} waarnemingen, {len(o['facets'][0]['counts']) if o['facets'] else 0} soorten")

# 3. Natura 2000 binnen 10 km (PDOK WFS; deze MapServer geeft altijd de hele omtrek mee, dus bbox klein houden).
dy, dx = 10 / 111.32, 10 / (111.32 * math.cos(math.radians(LAT)))
n2k = get("https://service.pdok.nl/rvo/natura2000/wfs/v1_0", service="WFS", version="2.0.0", request="GetFeature",
          typeNames="natura2000:natura2000", outputFormat="application/json", srsName="EPSG:4326",
          bbox=f"{LAT - dy},{LON - dx},{LAT + dy},{LON + dx},urn:ogc:def:crs:EPSG::4326")["features"]
def km(p, q):
    return 111.32 * math.hypot((p[0] - q[0]) * math.cos(math.radians(LAT)), p[1] - q[1])
def afstand(geom):   # 0 als het punt erin ligt, anders de afstand tot de dichtstbijzijnde rand (benadering)
    vlakken = geom["coordinates"] if geom["type"] == "MultiPolygon" else [geom["coordinates"]]
    binnen, d = False, float("inf")
    for vlak in vlakken:
        for ring in vlak:
            for (x1, y1), (x2, y2) in zip(ring, ring[1:]):
                if (y1 > LAT) != (y2 > LAT) and LON < x1 + (LAT - y1) * (x2 - x1) / (y2 - y1):
                    binnen = not binnen
                d = min(d, km((LON, LAT), (x1, y1)))
    return 0.0 if binnen else d
gebieden = {}   # één gebied (nr) kan uit meerdere objecten bestaan: Vogelrichtlijn, Habitatrichtlijn of beide
for g in n2k:
    p, a = g["properties"], afstand(g["geometry"])
    oud = gebieden.get(p["nr"], (p["naamN2K"], float("inf"), set()))
    gebieden[p["nr"]] = (p["naamN2K"], min(oud[1], a), oud[2] | set(p["beschermin"].split("+")))
print(f"\nNatura 2000 binnen 10 km: {len(gebieden) or 'geen'}")
for nm, a, r in sorted(gebieden.values(), key=lambda x: x[1]):
    print(f"  {nm} ({'+'.join(sorted(r))}): {'je staat erin' if a == 0 else f'{a:.1f} km'}")

# 4. Hoe groen: ESA WorldCover 2021 (10 m) via Microsoft Planetary Computer, histogram binnen een cirkel.
item = requests.post("https://planetarycomputer.microsoft.com/api/stac/v1/search", headers=UA, timeout=120, json={
    "collections": ["esa-worldcover"], "intersects": {"type": "Point", "coordinates": [LON, LAT]}}).json()["features"]
item = max(item, key=lambda i: i["properties"]["esa_worldcover:product_version"])   # 2021 (v200) boven 2020 (v100)
klassen = {c["value"]: c["description"] for c in item["assets"]["map"]["classification:classes"]}
ring = [[LON + STRAAL / (111.32 * math.cos(math.radians(LAT))) * math.sin(2 * math.pi * i / 64),
         LAT + STRAAL / 111.32 * math.cos(2 * math.pi * i / 64)] for i in range(65)]
st = requests.post("https://planetarycomputer.microsoft.com/api/data/v1/item/statistics", headers=UA, timeout=120,
                   params={"collection": "esa-worldcover", "item": item["id"], "assets": "map", "categorical": "true", "max_size": 1024},
                   json={"type": "Feature", "properties": {}, "geometry": {"type": "Polygon", "coordinates": [ring]}}).json()
aantallen, waarden = st["properties"]["statistics"]["map_b1"]["histogram"]
totaal = sum(aantallen)
print(f"\nGrondgebruik binnen {STRAAL:g} km ({item['id']}):")
for n, w in sorted(zip(aantallen, waarden), reverse=True):
    print(f"  {n / totaal:6.1%}  {klassen[int(w)]}")
groen = sum(n for n, w in zip(aantallen, waarden) if int(w) in (10, 20, 30, 90, 95, 100))
print(f"  groen (bomen, struiken, gras, moeras, mos): {groen / totaal:.0%}")
Uitvoer
$ python buurt.py
GBIF, 1 km rond 52.358, 4.8686, jaren 2021-2025: 21279 waarnemingen, 486 soorten
  per groep: vogels 20138, Magnoliopsida 735, insecten 208, Liliopsida 99, Agaricomycetes 37
  uit: EOD – eBird Observation Dataset (83%), iNaturalist Research-grade Observations (11%), Birda - Global Observation Dataset (2%)
  meest gezien:
      1168  meerkoet (Fulica atra)
      1161  halsbandparkiet (Psittacula krameri)
      1068  nijlgans (Alopochen aegyptiaca)
      1061  waterhoen (Gallinula chloropus)
       950  ekster (Pica pica)
       949  wilde eend (Anas platyrhynchos)
       903  blauwe reiger (Ardea cinerea)
       885  kraai (Corvus corone)

Waarneming.nl in het vak 52.35-52.40 N, 4.85-4.90 O (ongeveer 5,6 bij 3,4 km): 64595 waarnemingen, 2444 soorten

Natura 2000 binnen 10 km: 3
  Markermeer & IJmeer (VR): 7.6 km
  Ilperveld, Varkensland, Oostzanerveld & Twiske (HR+VR): 8.7 km
  Polder Westzaan (HR): 10.0 km

Grondgebruik binnen 1 km (ESA_WorldCover_10m_2021_v200_N51E003):
   65.7%  Built-up
   28.5%  Tree cover
    2.7%  Grassland
    2.6%  Permanent water bodies
    0.4%  Cropland
    0.1%  Herbaceous wetland
  groen (bomen, struiken, gras, moeras, mos): 31%

$ python buurt.py 52.040 5.690
GBIF, 1 km rond 52.04, 5.69, jaren 2021-2025: 399 waarnemingen, 236 soorten
  per groep: Magnoliopsida 117, insecten 116, vogels 105, Agaricomycetes 20, spinachtigen 13
  uit: iNaturalist Research-grade Observations (58%), Pl@ntNet automatically identified occurr (19%), EOD – eBird Observation Dataset (15%)
  meest gezien:
        10  merel (Turdus merula)
        10  beuk (Fagus sylvatica)
         8  vink (Fringilla coelebs)
         6  roodborst (Erithacus rubecula)
         6  blauwe bosbes (Vaccinium myrtillus)
         6  roodborsttapuit (Saxicola rubicola)
         6  look-zonder-look (Alliaria petiolata)
         5  pimpelmees (Cyanistes caeruleus)

Waarneming.nl in het vak 52.00-52.05 N, 5.65-5.70 O (ongeveer 5,5 bij 3,4 km): 128692 waarnemingen, 3302 soorten

Natura 2000 binnen 10 km: 3
  Veluwe (HR+VR): 0.3 km
  Binnenveld (HR): 6.9 km
  Rijntakken (HR+VR): 8.2 km

Grondgebruik binnen 1 km (ESA_WorldCover_10m_2021_v200_N51E003):
   75.0%  Tree cover
   14.3%  Built-up
   10.3%  Grassland
    0.3%  Cropland
    0.1%  Bare / sparse vegetation
    0.0%  Herbaceous wetland
    0.0%  Shrubland
  groen (bomen, struiken, gras, moeras, mos): 85%

Waar het misgaat

  • Waarnemingen meten mensen, niet natuur. Het Vondelpark (31% groen) had binnen 1 km 21.279 waarnemingen van 486 soorten, een punt in Ede aan de Veluwe (85% groen) 399 van 236. Toon het aantal soorten nooit als 'biodiversiteitsscore' zonder te zeggen hoeveel waarnemingen erachter zitten.
  • Waarneming.nl lijkt te ontbreken, maar staat er wel: Observation.org rondt coördinaten in GBIF af op vakken van 0,05 graad (floor(coord * 20) / 20, onzekerheid 5.000 m). Binnen 1 km vind je ze daardoor bijna nooit. Vraag het vak apart op met exacte decimalLatitude en decimalLongitude en zeg erbij dat het om een gebied van ongeveer 5,6 bij 3,4 km gaat.
  • Vogels domineren door eBird: rond het Vondelpark was 95% van de waarnemingen een vogel en kwam 83% uit eBird, met vaak dezelfde soort op elke lijst. Toon daarom ook het aantal soorten per groep, niet alleen het aantal waarnemingen, en overweeg vogels apart te tonen.
  • Licenties verschillen per dataset. eBird en Pl@ntNet zijn CC BY 4.0, maar iNaturalist, Birda en Observation.org zijn CC BY-NC 4.0. Tellingen tonen is meestal geen probleem; records doorgeven of in een commerciële app zetten wel. Vermeld de datasets en maak voor publicaties een GBIF-download met DOI.
  • De Natura 2000-WFS van PDOK geeft altijd de hele omtrek mee: 7,0 MB voor een vak van 20 bij 20 km rond Ede. Vraag een kleine bbox, cache het antwoord en voeg objecten met hetzelfde nr samen (Rijntakken kwam twee keer terug, als VR en als VR+HR). Let ook op de volgorde: in EPSG:4326 is de bbox breedte,lengte.
  • GeoJSON en GBIF gebruiken een andere volgorde: geoDistance is breedte,lengte, GeoJSON-coördinaten zijn [lengte, breedte]. Een omgedraaid punt in Nederland belandt in de Indische Oceaan en geeft gewoon 0 resultaten, zonder foutmelding.
  • WorldCover is de stand van 2021, uit een model: kleine fouten zoals 0,4% 'akker' rond het Vondelpark horen erbij, en nieuwe bouw of nieuw groen na 2021 zie je niet. Gebruik het voor verhoudingen, niet voor losse pixels.

Verder bouwen

  • Seizoenskalender: haal met facet=month per groep op wanneer er in jouw buurt vlinders, vogels of paddenstoelen worden gezien, en toon een kalender 'wat kun je nu zien'.
  • Groen per buurt: gebruik de buurtgrenzen van CBS/PDOK in plaats van een cirkel en maak een kaart van alle buurten van je gemeente met het aandeel bomen, gras en bebouwd. Zet dat naast het aantal inwoners per buurt.
  • Exoten volgen: tel per jaar (facet=year) de halsbandparkiet, nijlgans of bruingemarmerde schildwants in je buurt en laat zien hoe snel ze opkomen, met de kanttekening dat er ook steeds meer mensen waarnemingen doorgeven.
  • Ontbrekende soorten: vergelijk de soortenlijst van je buurt met die van het dichtstbijzijnde Natura 2000-gebied en toon welke soorten daar wel en bij jou niet zijn gezien, als tip voor een wandeling.

Meer met deze data

Waarnemingen van planten en dieren uit Nederland in GBIF: 12,5 miljoen waarnemingen in 2025, 24 keer zo veel als in 1990

Waarnemingen van planten en dieren uit Nederland in GBIF, 1990 – 2025, in miljoen waarnemingen. Dat is het hoogste punt in de reeks.

Bron: GBIF, occurrence search (facet year, land NL, alleen volle jaren) · opgehaald 25 oktober 2026Open de tabel Los blok

Landbedekking van de Randstad (vak tussen Amsterdam, Den Haag, Rotterdam en Utrecht): grasland is het grootste deel, 41% in 2021

Verdeling in 2021: grasland 41%, bebouwing 19%, bomen 17%, water 15%, akkers 6,9%, overig (moeras met kruiden, kaal of schaars begroeid) 0,9%. Totaal: 572.416 beeldpunten.

Bron: ESA WorldCover 2021 v200 (CC BY 4.0), via Microsoft Planetary Computer · opgehaald 25 oktober 2026 · selectie: Vak: 4,25–5,35 graden oost en 51,8–52,4 graden noord, hetzelfde als de kaart; water telt een strook Noordzee mee; Geschat uit een verkleinde versie van de kaart (572.416 beeldpunten)Open de tabel Los blok

Natura 2000-gebieden naar Europese richtlijn: alleen Habitatrichtlijn is het grootste deel, 52% in januari 2026

Verdeling in januari 2026: alleen Habitatrichtlijn 52%, beide richtlijnen 35%, alleen Vogelrichtlijn 14%. Totaal: 162 gebieden.

Bron: RVO, Natura 2000-gebieden via PDOK (WFS) · opgehaald 25 oktober 2026 · selectie: 162 gebieden uit 209 kaartobjectenOpen de tabel Los blok

De bronnen3

GBIF biodiversiteit

Global Biodiversity Information FacilityWereld, waarneming

Meer dan 150 miljoen waarnemingen van soorten in Nederland, onder meer uit waarneming.nl en museumcollecties.

OpenAPIDownloadKlimaat en milieu
Bereikbaar
dagelijks

ESA WorldCover

ESAWereld, 10 meter

Een kaart van de hele aarde in elf klassen grondgebruik (bos, akker, bebouwing, water …), op basis van Sentinel-1 en -2. Twee jaargangen, er komen geen nieuwe.

OpenKaartlaagDownloadAardobservatieWonen en ruimte
Bereikbaar
afgerond

Natura 2000-gebieden

Ministerie van Landbouw, Visserij, Voedselzekerheid en Natuur, via PDOKNederland, gebied (grens)

De officiële grenzen van alle Natura 2000-gebieden in Nederland: de natuur die onder de Europese Vogelrichtlijn en Habitatrichtlijn valt. Het gaat om 162 gebieden, waarvan drie op de Noordzee. Per gebied staan het nummer, de Europese sitecode, de soort bescherming en het aanwijzingsbesluit erbij. Via PDOK als WFS, OGC API en download.

OpenKaartlaagDownloadAPIKlimaat en milieu
Actueel
bijgewerkt in januari 2026

Meer om te bouwen