Wildfire map: today's risk, hotspots and burnt land
One map of the Netherlands per safety region with the fire service's phase, the fire danger for today and the coming days (EFFIS), the hotspots satellites saw this week (without factories) and the land that burnt this year, with KNMI drought data alongside.
geef_project("natuurbrand-kaart")geef_bron("natuurbrandrisico")geef_bron("effis")geef_bron("nasa-firms")
I have the project, the tested calls and the pitfalls. I'll build a map with Wildfire risk (fire service), EFFIS wildfires (Copernicus), NASA FIRMS (fires) and KNMI daily weather data. This is how it could look:
You build this yourself. Copy the prompt into Claude, ChatGPT or Cursor, with the MCP server on, or follow the steps below.
- Elburg421 ha29-04
- Cranendonck126 ha30-04
- Venray89 ha04-08
- Oirschot27 ha30-04
- Oldebroek25 ha25-08
- Wassenaar5 ha05-08
Fire danger
lowtoday and Mon 19 Oct (FWI)
Hotspots 7 d
54in NL, 53 at a fixed heat source
Rain deficit
245 mmDeelen, since 1 Apr · 2018: 288
This is a mockup, not a working version, with the phase per region from brandweer.nl, the EFFIS fire danger, the VIIRS hotspots and the KNMI Deelen rain deficit from our test run on 16 October 2026, and the EFFIS burnt areas (as of 17 October 2026). Turn the MCP server on with the address on For AI.
Who it's for
Rangers and land managers, safety regions and municipalities that want their own overview, journalists who want to see quickly how large a heath fire was, and anyone who wants to know on a dry day whether the Veluwe or the Peel is turning red.
What you get
A map (Leaflet or MapLibre) with the 25 safety regions from PDOK, coloured by the phase on brandweer.nl, overlaid with the EFFIS fire danger layer for the chosen day, the VIIRS hotspots of the last seven days and the outlines of the burnt areas. Plus a table per region and a drought gauge.
Test run on 16 October 2026: all regions were in phase 1, except Zaanstreek-Waterland ("Onbekend", unknown). The fire danger (Fire Weather Index) was "low" everywhere (below 11.2), for today and also for 19 October; from 20 October the service returned no map yet. For comparison: on 12 August 2026 most of the Netherlands was "high" or "very high", with a patch of "extreme" in Limburg. VIIRS saw 4,404 hotspots in Europe in seven days, 54 of them in the Netherlands; 53 of those lay within 1 km of a fixed heat source from 2025 (mainly the steelworks at IJmuiden). EFFIS mapped nine burnt areas in 2026, together 693 hectares, the largest near Elburg (29 April, 421 ha, entirely in Natura 2000). That fire came at the end of the longest dry spell of 2026 at Deelen: 20 days in a row with less than 1 mm, up to and including 1 May. The precipitation deficit at Deelen from 1 April to 14 October was 245 mm (2018: 288 mm, 2022: 224 mm on the same date).
Burnt natural land in the Netherlands mapped by EFFIS: 330 hectares in 2025, 80% more than in 2018
Burnt natural land in the Netherlands mapped by EFFIS, 2018 – 2025, in hectares. The highest point was 2020 (822).
How you could start7 steps
- 1
Read the phase per safety region
The fire service has no API. On brandweer.nl/natuurbrandrisico, under 'Alle locaties & huidige fase', each region has a block with name and phase (Fase 1, Fase 2 or Onbekend). robots.txt allows reading, with Crawl-delay 10: reading once a day is enough, and store it yourself, because there is no history. The map on the site also fetches a JSON with a colour per region code (VR01 to VR25); those codes are the same as at CBS and PDOK, but you get colours (#dd9933 for phase 1, #B0C4DE for unknown), not phase numbers. Names sometimes differ from CBS ('Hollands Midden' versus 'Hollands-Midden', 'Zuid-Limburg' versus 'Limburg-Zuid'): compare on letters only.
https://www.brandweer.nl/natuurbrandrisico/
<legend class="strong red">Alle locaties & huidige fase</legend> <div class="facetwp-template risk-list" data-name="risks"> <div class="risk"> Fryslân <div class="risk-phase"> Fase 1 </div> ... 25 regio's: ('Fryslân', 'Fase 1'), ('Utrecht', 'Fase 1'), ... ('Zaanstreek-Waterland', 'Onbekend'), ... ('Twente', 'Fase 1') - 2
Fetch the safety region polygons
PDOK publishes the CBS area divisions as a WFS. The layer veiligheidsregio_gegeneraliseerd gives the 25 regions with statcode (VR01 to VR25) and name, 750 kB as GeoJSON in longitude and latitude. With these polygons you colour the map, and with a point-in-polygon test you link hotspots and burnt areas to a region. Choose the year of the division (here 2025) and state it.
https://service.pdok.nl/cbs/gebiedsindelingen/2025/wfs/v1_0?service=WFS&version=2.0.0&request=GetFeature&typeNames=gebiedsindelingen:veiligheidsregio_gegeneraliseerd&outputFormat=application/json&srsName=EPSG:4326
HTTP 200, 748.151 bytes, 25 features (MultiPolygon) {'statcode': 'VR01', 'jrstatcode': '2025VR01', 'statnaam': 'Groningen', 'rubriek': 'veiligheidsregio', 'id': 1} ('VR11', 'Zaanstreek-Waterland'), ('VR14', 'Gooi en Vechtstreek'), ('VR16', 'Hollands-Midden'), ('VR24', 'Limburg-Zuid') - 3
Fire danger for today and the coming days (EFFIS)
The EFFIS map service (WMS 1.1.1, no key, no robots.txt) has the layer mf010.fwi: the Canadian Fire Weather Index, computed from the weather forecast. Always pass time=: without it the layer falls back to 1 January 2021. On 16 October the forecast ran up to and including 19 October; for 20 October an empty, transparent image came back, also with HTTP 200. The layer is not queryable (queryable=0), so you read the value from the colour. The classes are in the legend (GetLegendGraphic): Low < 11.2, Moderate 11.2 to 21.3, High 21.3 to 38, Very High 38 to 50, Extreme 50 to 70, Very Extreme > 70. Note: this is fire danger according to the weather, not the fire service's phase.
https://maps.effis.emergency.copernicus.eu/effis?service=WMS&version=1.1.1&request=GetMap&layers=mf010.fwi&styles=&srs=EPSG:4326&bbox=3.2,50.7,7.3,53.6&width=410&height=290&format=image/png&transparent=true&time=2026-08-12
2026-10-14 [((156, 255, 192), 89300)] alles Low 2026-10-16 [((156, 255, 192), 89300)] alles Low 2026-10-20 [] leeg plaatje, nog geen verwachting 2026-08-12 [((217, 112, 16), 46900), ((230, 172, 0), 32400), ((205, 226, 78), 6400), ((173, 6, 14), 3600)] = Very High, High, Moderate, Extreme <Layer queryable="0" opaque="0" cascaded="0"><Name>mf010.fwi</Name> ... <Extent name="time" default="2021-01-01" nearestValue="0">2018-01-01/2099-12-31</Extent> - 4
Burnt land with outline (EFFIS)
The EFFIS REST API returns all mapped burnt areas in the Netherlands since 2003 in one response (53 areas, 194 kB, next is null). Per area: firedate (with +02:00), area_ha, commune and province (names, not codes), centroid, bbox, the outline as a MultiPolygon in shape, land cover in percent and percna2k (share in Natura 2000). Draw shape on the map and link centroid to a safety region. These are mostly the larger fires: per year 2003 1, 2011 1, 2014 1, 2015 1, 2018 3, 2019 1, 2020 2, 2022 15, 2023 2, 2024 2, 2025 15 and 2026 9.
https://api.effis.emergency.copernicus.eu/rest/2/burntareas/current/?country=NL
{"count": 53, "next": null, "results": [ ... {"id": 438857, "centroid": {"type": "Point", "coordinates": [5.866599251185119, 52.37698879575639]}, "bbox": [5.845090845339057, 52.36675178251562, 5.887158589036566, 52.386277550008856], "shape": {"type": "MultiPolygon", "coordinates": [[[[5.863966188551401, 52.38581500645767, ...]]]]}, "country": "NL", "countryful": "Nederland", "province": "Veluwe", "commune": "Elburg", "firedate": "2026-04-29T09:42:00+02:00", "area_ha": 421, "conifer": "1.19047619", "othernatlc": "98.80952381", "percna2k": "100.00000000", "lastupdate": "2026-04-30T12:40:32.993585+02:00", "lastfiredate": null, "noneu": false} - 5
Hotspots of the last days (NASA FIRMS)
FIRMS publishes open CSV files per continent, without a key: the VIIRS detections (375 m) of the last 24 hours and 7 days. The 7-day Europe file was 356 kB with 4,404 detections. There is no country column: filter yourself with the polygons from step 2 (a rectangle around the Netherlands also catches Duisburg and Ghent). These files have no type column, so you cannot see whether a hotspot is a factory. Times (acq_date, acq_time) are UTC. confidence is low, nominal or high here. If you want your own area, another satellite or a past date, use the Area API with a free MAP_KEY (request it with your email address at firms.modaps.eosdis.nasa.gov/api/map_key; 5,000 transactions per 10 minutes, at most 5 days per call). Without a valid key you get HTTP 400 'Invalid MAP_KEY.'
https://firms.modaps.eosdis.nasa.gov/data/active_fire/suomi-npp-viirs-c2/csv/SUOMI_VIIRS_C2_Europe_7d.csv
latitude,longitude,bright_ti4,scan,track,acq_date,acq_time,satellite,confidence,version,bright_ti5,frp,daynight 52.49662,4.61254,308.18,0.45,0.47,2026-10-10,0245,N,nominal,2.0NRT,280.99,2.02,N 52.49261,4.60978,331.44,0.45,0.47,2026-10-10,0245,N,nominal,2.0NRT,285.02,2.02,N 52.49102,4.61598,305.58,0.45,0.47,2026-10-10,0245,N,nominal,2.0NRT,283.52,2.02,N ... eu7d.csv 4404 detecties, 2026-10-09 tot 2026-10-16
- 6
Remove factories and flares with the annual file
The annual file per country (open, about 250 kB for the Netherlands) does have a type column: 0 = presumed vegetation fire, 2 = other static land source (factories, flares), 3 = offshore. In 2025, 2,511 of the 3,260 detections in the Netherlands were type 2 (77%), 708 type 0 and 41 type 3. Use last year's type-2 points as a mask: a new hotspot within 1 km of one is probably a factory. That left one of the 54 Dutch detections in the week to 16 October 2026. The file for the current year does not exist yet (HTTP 404). Respect Crawl-delay 1 from robots.txt.
https://firms.modaps.eosdis.nasa.gov/data/country/viirs-snpp/2025/viirs-snpp_2025_Netherlands.csv
latitude,longitude,bright_ti4,scan,track,acq_date,acq_time,satellite,instrument,confidence,version,bright_ti5,frp,daynight,type 52.48415,4.59752,311.68,0.61,0.53,2025-01-02,0246,N,VIIRS,n,2,275.77,3.98,N,2 52.49296,4.61101,329.99,0.58,0.7,2025-01-02,1055,N,VIIRS,n,2,277.1,3.55,D,2 ... 3260 Counter({'2': 2511, '0': 708, '3': 41}) type 0 per maand: juni 180, mei 167, april 86, juli 71, augustus 69, maart 38, september 35 ... - 7
Drought: precipitation deficit and dry days (KNMI)
Fire danger follows drought. KNMI daily data gives rainfall (RH) and Makkink evaporation (EV24) per station, both in tenths of a mm; RH -1 means less than 0.05 mm (count as 0). The precipitation deficit is the sum of evaporation minus rainfall since 1 April. For the Veluwe station 275 Deelen is a good choice, for the Peel 375 Volkel or 370 Eindhoven. Also count the longest run of days with less than 1 mm: at Deelen 20 days up to and including 1 May 2026, just after the Elburg fire. The newest day is usually the day before yesterday.
curl -X POST "https://www.daggegevens.knmi.nl/klimatologie/daggegevens" \ -d 'stns=275&vars=RH:EV24&start=20260401&end=20261016&fmt=json'
[{"station_code": 275, "date": "2026-04-01T00:00:00.000Z", "RH": 0, "EV24": 24}, {"station_code": 275, "date": "2026-04-02T00:00:00.000Z", "RH": 6, "EV24": 6}, ... {"station_code": 275, "date": "2026-10-13T00:00:00.000Z", "RH": 45, "EV24": 5}, {"station_code": 275, "date": "2026-10-14T00:00:00.000Z", "RH": 0, "EV24": 16}] 197 dagen; neerslagtekort 245.2 mm; langst droog (<1mm) 20 dagen, eindigend 2026-05-01
How the sources fit together
- Wildfire risk (fire service)EFFIS wildfires (Copernicus)via
veiligheidsregio (VR01 tot VR25) en datum; EFFIS-gebieden via hun centroid in het regiovlakThe fire service's phase is a human decision, the Fire Weather Index a calculation from the weather. Put them side by side per region and per day, then add the burnt areas: did a large fire come after phase 2, and was the FWI already red? Store the phase daily yourself, because brandweer.nl has no archive.
- NASA FIRMS (fires)EFFIS wildfires (Copernicus)via
datum en plaats (hittepunt binnen de omtrek van een verbrand gebied)FIRMS sees the fire while it burns, EFFIS measures the burnt area afterwards. Hotspots inside an EFFIS outline show how the fire moved.
- KNMI daily weather dataWildfire risk (fire service)via
datum; KNMI-station in of bij de veiligheidsregio (Deelen 275 voor Gelderland-Midden en Noord- en Oost-Gelderland)The precipitation deficit and the number of dry days in a row explain why a region moves to phase 2. Show them next to the phase.
- EFFIS wildfires (Copernicus)Natura 2000 sitesvia
omtrek (shape) tegen de Natura 2000-vlakken van PDOKEFFIS already gives the share in Natura 2000 (percna2k); with the PDOK polygons you see which area it was, for example the Veluwe near Elburg.
Let AI build it
Paste this prompt into Claude, ChatGPT, Cursor or Lovable. It names the real endpoints, the join keys and the pitfalls, so the assistant writes working code straight away. Always check the result against the source itself.
Build a wildfire map of the Netherlands as a web page (MapLibre or Leaflet) with a small backend that fetches and stores data once a day. No keys needed. Layers and sources: 1. Safety regions as polygons: PDOK WFS https://service.pdok.nl/cbs/gebiedsindelingen/2025/wfs/v1_0?service=WFS&version=2.0.0&request=GetFeature&typeNames=gebiedsindelingen:veiligheidsregio_gegeneraliseerd&outputFormat=application/json&srsName=EPSG:4326 (25 features, statcode VR01 to VR25, statnaam). 2. Phase per region: brandweer.nl has no API. Read https://www.brandweer.nl/natuurbrandrisico/ and take name and phase per region from <div class="risk">NAME<div class="risk-phase">PHASE</div>. Values: 'Fase 1', 'Fase 2', 'Onbekend' (unknown is NOT phase 1). Link to PDOK by name, compared on letters only (Hollands Midden = Hollands-Midden, Zuid-Limburg = Limburg-Zuid). Read at most once a day (robots.txt: Crawl-delay 10) and store it yourself: there is no history. 3. Fire danger: EFFIS WMS https://maps.effis.emergency.copernicus.eu/effis, version 1.1.1, layer mf010.fwi, srs EPSG:4326 (bbox lon,lat) or EPSG:3857 for web maps, format image/png, transparent=true, and ALWAYS time=YYYY-MM-DD (without time you get 2021-01-01). The forecast runs about three days ahead; after that an empty image comes back with HTTP 200. Legend via request=GetLegendGraphic&layer=mf010.fwi: Low <11.2, Moderate 11.2-21.3, High 21.3-38, Very High 38-50, Extreme 50-70, Very Extreme >70. Add a day slider (today to +3). 4. Burnt areas: https://api.effis.emergency.copernicus.eu/rest/2/burntareas/current/?country=NL returns JSON with count, next and results (firedate with time zone, area_ha, commune, province, centroid, shape as MultiPolygon, percna2k). Follow next until null. Draw shape, popup with date, hectares, municipality and % Natura 2000. 5. Hotspots: open CSV https://firms.modaps.eosdis.nasa.gov/data/active_fire/suomi-npp-viirs-c2/csv/SUOMI_VIIRS_C2_Europe_7d.csv (also _24h). Columns latitude, longitude, acq_date, acq_time (UTC), confidence (low/nominal/high), frp (MW), daynight. No country column: filter with point-in-polygon on the safety regions. No type column: remove factories with last year's annual file https://firms.modaps.eosdis.nasa.gov/data/country/viirs-snpp/2025/viirs-snpp_2025_Netherlands.csv (column type: 0 vegetation fire, 2 static heat source, 3 offshore); mark a hotspot within 1 km of a type-2 point as 'probably industry' (grey) rather than dropping it. Crawl-delay 1 between calls. 6. Drought: KNMI daily data POST https://www.daggegevens.knmi.nl/klimatologie/daggegevens with stns=275&vars=RH:EV24&start=YYYY0401&end=YYYYMMDD&fmt=json. RH and EV24 in tenths of mm; RH -1 = less than 0.05 mm. Precipitation deficit = sum(EV24 - RH) since 1 April. Also show the number of days since the last day with 1 mm or more. Pitfalls: the phase (a human decision) and the FWI (a weather calculation) are different things, show them separately. A hotspot is one 375 m pixel on one overpass, not a fire and not an area; never count 'number of fires' from hotspots. EFFIS misses many small heath fires and had only four Dutch areas before 2018: not a complete fire statistic. Times: FIRMS in UTC, EFFIS with +02:00 or +01:00, KNMI date at 00:00 UTC. Honest User-Agent in every call. Output: a map with regions in the colour of their phase (phase 2 orange, unknown grey), FWI layer with slider, burnt areas with outline, hotspots (red) and industry (grey), a panel per region with phase, most common FWI class, hotspots this week and hectares burnt this year, and a drought gauge with the precipitation deficit against 2018 and 2022 on the same date.
Try it yourself
The core of the project in a small script. Needs: Python 3.10+, requests en Pillow. Tested on 2026-10-16; below is the real output of that run.
# Natuurbrand-kaart, de data erachter: per veiligheidsregio de fase van de brandweer, het brandgevaar (EFFIS Fire
# Weather Index), hittepunten van de laatste 7 dagen (NASA FIRMS, zonder fabrieken), verbrande natuur dit jaar (EFFIS)
# en de droogte (KNMI). Geen sleutels nodig. Vereist: Python 3.10+, requests en Pillow.
import csv, io, math, re, time
from datetime import date, timedelta
import requests
from PIL import Image
UA = {"User-Agent": "mijn-project/1.0 (+jij@voorbeeld.nl)"}
get = lambda url, **kw: requests.get(url, headers=UA, timeout=120, **kw)
# 1. Veiligheidsregio's als vlakken (PDOK, CBS-indeling 2025), in lengte- en breedtegraad.
vr = get("https://service.pdok.nl/cbs/gebiedsindelingen/2025/wfs/v1_0", params={
"service": "WFS", "version": "2.0.0", "request": "GetFeature", "outputFormat": "application/json",
"typeNames": "gebiedsindelingen:veiligheidsregio_gegeneraliseerd", "srsName": "EPSG:4326"}).json()["features"]
def binnen(lon, lat, ringen): # punt-in-veelhoek (ray casting), alleen buitenringen
ok = False
for ring in ringen:
for (x1, y1), (x2, y2) in zip(ring, ring[1:]):
if (y1 > lat) != (y2 > lat) and lon < x1 + (lat - y1) * (x2 - x1) / (y2 - y1):
ok = not ok
return ok
regios = {}
for f in vr:
ringen = [p[0] for p in f["geometry"]["coordinates"]] # MultiPolygon
xs = [x for r in ringen for x, _ in r]; ys = [y for r in ringen for _, y in r]
regios[f["properties"]["statcode"]] = {"naam": f["properties"]["statnaam"], "ringen": ringen,
"bbox": (min(xs), min(ys), max(xs), max(ys)), "fwi": [], "hitte": 0, "ha": 0}
def regio_van(lon, lat):
for code, r in regios.items():
x0, y0, x1, y1 = r["bbox"]
if x0 <= lon <= x1 and y0 <= lat <= y1 and binnen(lon, lat, r["ringen"]):
return code
# 2. Fase per regio van brandweer.nl (geen API: de pagina lezen; namen gelijktrekken op alleen letters).
sleutel = lambda s: re.sub(r"[^a-z]", "", s.lower().replace("â", "a")).replace("limburgzuid", "zuidlimburg")
html = get("https://www.brandweer.nl/natuurbrandrisico/").text
fase = {sleutel(n): f for n, f in re.findall(r'<div class="risk">\s*([^<]+?)\s*<div class="risk-phase">\s*([^<]+?)\s*</div>', html)}
# 3. Brandgevaar: EFFIS Fire Weather Index als PNG, kleur per klasse uit de legenda (GetLegendGraphic).
KLASSE = {(156, 255, 192): "laag", (205, 226, 78): "matig", (230, 172, 0): "hoog", (217, 112, 16): "zeer hoog",
(173, 6, 14): "extreem", (75, 0, 32): "zeer extreem"}
B = (3.2, 50.7, 7.3, 53.6); W, H = 82, 58 # 0,05 graad per pixel; het FWI-raster is grover
vandaag = date.today()
png = get("https://maps.effis.emergency.copernicus.eu/effis", params={
"service": "WMS", "version": "1.1.1", "request": "GetMap", "layers": "mf010.fwi", "styles": "", "srs": "EPSG:4326",
"bbox": ",".join(map(str, B)), "width": W, "height": H, "format": "image/png", "transparent": "true",
"time": vandaag.isoformat()}).content # zonder time krijg je 1 januari 2021!
im = Image.open(io.BytesIO(png)).convert("RGBA")
for j in range(H):
for i in range(W):
r, g, b, a = im.getpixel((i, j))
lon, lat = B[0] + (i + .5) * (B[2] - B[0]) / W, B[3] - (j + .5) * (B[3] - B[1]) / H
if a and (code := regio_van(lon, lat)):
regios[code]["fwi"].append(KLASSE.get((r, g, b), "?"))
# 4. Hittepunten: VIIRS laatste 7 dagen (Europa, open bestand) minus vaste warmtebronnen uit het jaarbestand 2025.
vorig = csv.DictReader(io.StringIO(get(f"https://firms.modaps.eosdis.nasa.gov/data/country/viirs-snpp/{vandaag.year - 1}/viirs-snpp_{vandaag.year - 1}_Netherlands.csv").text))
vast = [(float(x["longitude"]), float(x["latitude"])) for x in vorig if x["type"] == "2"] # fabrieken, fakkels
time.sleep(1) # robots.txt van FIRMS: Crawl-delay 1
nrt = list(csv.DictReader(io.StringIO(get("https://firms.modaps.eosdis.nasa.gov/data/active_fire/suomi-npp-viirs-c2/csv/SUOMI_VIIRS_C2_Europe_7d.csv").text)))
km = lambda a, b: 111.2 * math.hypot((a[0] - b[0]) * math.cos(math.radians(a[1])), a[1] - b[1])
in_nl = fabriek = 0
for x in nrt:
p = (float(x["longitude"]), float(x["latitude"]))
if not (B[0] <= p[0] <= B[2] and B[1] <= p[1] <= B[3]) or not (code := regio_van(*p)):
continue
in_nl += 1
if any(km(p, v) < 1 for v in vast):
fabriek += 1
else:
regios[code]["hitte"] += 1
# 5. Verbrande natuur dit jaar (EFFIS, alle gebieden in Nederland sinds 2003).
ba = get("https://api.effis.emergency.copernicus.eu/rest/2/burntareas/current/?country=NL").json()["results"]
dit_jaar = [g for g in ba if g["firedate"].startswith(str(vandaag.year))]
for g in dit_jaar:
lon, lat = g["centroid"]["coordinates"]
if code := regio_van(lon, lat):
regios[code]["ha"] += float(g["area_ha"])
# 6. Droogte op de Veluwe: KNMI Deelen (275), neerslagtekort sinds 1 april = som(verdamping EV24 - neerslag RH).
def tekort(jaar, tot):
d = requests.post("https://www.daggegevens.knmi.nl/klimatologie/daggegevens", headers=UA, timeout=120, data={
"stns": "275", "vars": "RH:EV24", "start": f"{jaar}0401", "end": f"{jaar}{tot}", "fmt": "json"}).json()
return sum((x["EV24"] or 0) - max(x["RH"] or 0, 0) for x in d) / 10, d[-1]["date"][:10]
nu, laatste = tekort(vandaag.year, f"{vandaag:%m%d}")
print(f"Natuurbrand-overzicht {vandaag:%d-%m-%Y}\n")
print(f"{'veiligheidsregio':28} {'fase':9} {'brandgevaar':13} {'hittepunten 7d':>14} {'verbrand ' + str(vandaag.year):>14}")
for code, r in regios.items():
meest = max(set(r["fwi"]), key=r["fwi"].count) if r["fwi"] else "geen data"
print(f"{r['naam']:28} {fase.get(sleutel(r['naam']), '?'):9} {meest:13} {r['hitte']:14} {r['ha']:11.0f} ha")
print(f"\nVIIRS 7 dagen: {len(nrt)} detecties in Europa, {in_nl} in Nederland, waarvan {fabriek} bij een vaste warmtebron uit {vandaag.year - 1}")
print(f"EFFIS {vandaag.year}: {len(dit_jaar)} verbrande gebieden, {sum(float(g['area_ha']) for g in dit_jaar):.0f} ha")
print(f"Neerslagtekort Deelen 1 april t/m {laatste}: {nu:.0f} mm", end="")
for j in (2018, 2022):
print(f"; {j} op dezelfde datum: {tekort(j, laatste[5:].replace('-', ''))[0]:.0f} mm", end="")
print()
Natuurbrand-overzicht 16-10-2026 veiligheidsregio fase brandgevaar hittepunten 7d verbrand 2026 Groningen Fase 1 laag 0 0 ha Fryslân Fase 1 laag 0 0 ha Drenthe Fase 1 laag 0 0 ha IJsselland Fase 1 laag 0 0 ha Twente Fase 1 laag 0 0 ha Noord- en Oost-Gelderland Fase 1 laag 0 446 ha Gelderland-Midden Fase 1 laag 0 0 ha Gelderland-Zuid Fase 1 laag 0 0 ha Utrecht Fase 1 laag 0 0 ha Noord-Holland-Noord Fase 1 laag 0 0 ha Zaanstreek-Waterland Onbekend laag 0 0 ha Kennemerland Fase 1 laag 1 0 ha Amsterdam-Amstelland Fase 1 laag 0 0 ha Gooi en Vechtstreek Fase 1 laag 0 0 ha Haaglanden Fase 1 laag 0 5 ha Hollands-Midden Fase 1 laag 0 0 ha Rotterdam-Rijnmond Fase 1 laag 0 0 ha Zuid-Holland-Zuid Fase 1 laag 0 0 ha Zeeland Fase 1 laag 0 0 ha Midden- en West-Brabant Fase 1 laag 0 0 ha Brabant-Noord Fase 1 laag 0 0 ha Brabant-Zuidoost Fase 1 laag 0 153 ha Limburg-Noord Fase 1 laag 0 89 ha Limburg-Zuid Fase 1 laag 0 0 ha Flevoland Fase 1 laag 0 0 ha VIIRS 7 dagen: 4404 detecties in Europa, 54 in Nederland, waarvan 53 bij een vaste warmtebron uit 2025 EFFIS 2026: 9 verbrande gebieden, 693 ha Neerslagtekort Deelen 1 april t/m 2026-10-14: 245 mm; 2018 op dezelfde datum: 288 mm; 2022 op dezelfde datum: 224 mm
Where it goes wrong
- Without time= the EFFIS map service silently returns the map for 1 January 2021 (the default in GetCapabilities), and for a day beyond the forecast an empty image with HTTP 200. Always pass a date and check that the image is not empty.
- Most hotspots in the Netherlands are not wildfires. In 2025, 77% of VIIRS detections were a static heat source (type 2), mainly around IJmuiden; in the week to 16 October 2026 it was 53 of 54. The open 24-hour and 7-day files have no type column: build your own mask from the annual file. That mask is not perfect either: one point 2.7 km from a known source near IJmuiden remained.
- A rectangle around the Netherlands is not the Netherlands. In the box 3.2 to 7.25 E and 50.75 to 53.7 N, one day of hotspots included points near Duisburg (6.7 E) and Ghent (3.8 E). Filter with the safety region polygons (point-in-polygon), not with a bbox.
- Phase, fire danger, hotspot and burnt area are four different things. The phase is a fire service decision, the FWI a calculation from the weather, a hotspot a 375 m pixel on one overpass and an EFFIS area a measured surface. Never count 'number of fires' from hotspots, and do not call EFFIS a complete statistic: small heath fires are missing and before 2018 there are only four Dutch areas.
- brandweer.nl is a web page, not an API: if the HTML changes, your reader breaks. Check that you find 25 regions, do not count 'Onbekend' as phase 1, read at most once a day (Crawl-delay 10) and store it yourself. The site's colour JSON is undocumented.
- Time zones are mixed: FIRMS acq_time in UTC (0245 is 04:45 Dutch summer time), EFFIS firedate with +02:00, KNMI dates as 00:00 UTC. Convert everything before you link a hotspot to a day or a dry spell.
Take it further
- Build an archive: store the phase per region, the FWI class per region and the hotspots every day. After one summer you can show how many days each region spent in phase 2 and whether the FWI turned red before the fire service scaled up.
- Alert for your own forest or heath: send a message when a hotspot falls within 5 km of a Natura 2000 site and is not near a known industrial source, or when the FWI for your region rises to High or above in the next three days.
- Compare fire years: count the type-0 detections per year from the annual files (2012 to now) next to the EFFIS hectares and the precipitation deficit on 1 August. Was 2022, with 15 EFFIS areas, also the driest year?
- What burnt: lay the EFFIS outline over ESA WorldCover or the PDOK Natura 2000 polygons and show per fire how much heath, forest or grass was lost.
More with this data
The largest wildfires in the Netherlands according to EFFIS: most Deurne, April 2020 (649 hectares), then Elburg, April 2026 and Ede, April 2014
The largest wildfires in the Netherlands according to EFFIS, 2003–2026, in hectares. Total: 3,049; the largest 12 of 53 categories are shown. Deurne, April 2020 is 21% of the total. All 53 areas EFFIS has mapped in the Netherlands since 2003, 3,049 hectares together. Municipality as EFFIS names it. Small fires are missing.
Satellite detections of presumed vegetation fires in the Netherlands: 708 detections in 2025, 7% more than in 2012
Satellite detections of presumed vegetation fires in the Netherlands, 2012 – 2025, in detections. The highest point was 2019 (741).
Satellite detections of presumed vegetation fires in the Netherlands by month: most June (1,312 detections), then April and August
Satellite detections of presumed vegetation fires in the Netherlands by month, 2012–2025, in detections. Total: 8,241; the largest 12 of 12 categories are shown. June is 16% of the total. All years 2012 to 2025 combined. A detection is one 375-metre pixel where the satellite saw a heat source; one fire can produce many detections.
The sources4
BWildfire risk (fire service)
The fire service states per safety region how high the risk of a wildfire is: phase 1 (normal, everyone is prepared) or phase 2 (it has been dry for a long time, a fire can develop quickly and unpredictably). brandweer.nl only shows today's state, with no history and no documented API. We read the page every day and store the result, so a series builds up from 16 October 2026.

EFFIS wildfires (Copernicus)
The European Forest Fire Information System maps fires in natural areas from satellite imagery (MODIS, VIIRS and Sentinel-2). For each burnt area: date, area in hectares, municipality, the outline as a polygon, what was growing and how much lies in Natura 2000. For the Netherlands 53 areas since 2003, the largest near Deurne (April 2020, 649 hectares) and Elburg (April 2026, 421 hectares). Plus an open map service with the fire danger for the coming days (Fire Weather Index) and today's hotspots.

NASA FIRMS (fires)
Hotspots reported by satellites within three hours of an overpass. In the Netherlands mostly heath and dune fires and industry.

KNMI daily weather dataIn depth
Daily values from over fifty weather stations: temperature, rainfall, sunshine and wind. The De Bilt series starts in 1901.
More to build
Earthquake tracker: every quake on the map, with municipality and homesMap
Alert when the river near you is too high or too lowAlert
Neighbourhood safety monitor: nuisance and crime per neighbourhoodDashboard
Climate risk check for an addressTool
Air quality alert for your own streetAlert
Nature in your neighbourhood: which species were seen and how green is it?App