GDACS quickstart — recent disaster alerts¶
Fetch the last 30 days of multi-hazard disaster alerts — earthquakes, tropical cyclones, floods, volcanoes, wildfires, droughts — from the public GDACS feed through the earthlens GDACS backend, and plot them coloured by alert level.
GDACS is a vector backend: download() returns a pyramids FeatureCollection (a geopandas.GeoDataFrame), not a raster. It needs no credentials — the feed is public, and there is no extra to install (pip install earthlens is enough).
Setup¶
The imports for the whole notebook. earthlens provides the unified EarthLens entry point; the standard-library datetime and pathlib helpers build the date window and the output directory.
import datetime as dt
from pathlib import Path
from earthlens import EarthLens
Output directory¶
GDACS is a file-writing-and-returning backend, so we point it at a local gdacs_output/ folder. The downloaded alerts are written to gdacs_output/gdacs_alerts.gpkg and also returned in memory.
OUT_DIR = Path('gdacs_output')
OUT_DIR.mkdir(exist_ok=True)
Date window¶
GDACS is a live alert feed, so the most populated windows are the most recent ones. We build a ~30-day window ending today.
TODAY = dt.date.today()
START = (TODAY - dt.timedelta(days=30)).strftime('%Y-%m-%d')
END = TODAY.strftime('%Y-%m-%d')
print('window:', START, 'to', END)
Query¶
variables=[] defaults to all six hazard types; they all come back in one request. The alert-level filter is the explicit alert_level= keyword (here we keep all three levels). We build the request first, keeping the constructor on its own statement.
gdacs = EarthLens(
variables=[], # all six hazard types
data_source='gdacs',
start=START,
end=END,
aoi=[-180, -90, 180, 90],
alert_level=['Green', 'Orange', 'Red'],
path=str(OUT_DIR),
)
Download the alerts¶
Now run the live query. It is wrapped in a try/except so the notebook stays safe under nbval-lax when run offline — the cell prints a skip message instead of raising. The result is written to gdacs_output/gdacs_alerts.gpkg and returned in memory.
alerts = None
try:
alerts = gdacs.download()
print(f'{len(alerts)} alerts')
print(alerts['hazard_type'].value_counts().to_dict())
except Exception as exc:
print(f'live GDACS query skipped (offline?): {type(exc).__name__}: {exc}')
Inspect the alerts¶
A quick look at the key columns and the coordinate reference system of the returned GeoDataFrame.
if alerts is not None and len(alerts):
cols = ['name', 'hazard_type', 'alert_level', 'from_date', 'country', 'geometry']
display(alerts[cols].head())
print('CRS:', alerts.crs)
Plot the alerts on a world map¶
Points are coloured by alert level (green / orange / red).
if alerts is not None and len(alerts):
import matplotlib.pyplot as plt
colours = {'Green': 'green', 'Orange': 'orange', 'Red': 'red'}
ax = alerts.plot(
color=alerts['alert_level'].map(colours).fillna('grey'),
markersize=25,
alpha=0.6,
)
ax.set_title(f'GDACS alerts, {START} to {END} (by alert level)')
ax.set_xlabel('longitude')
ax.set_ylabel('latitude')
ax.set_xlim(-180, 180)
ax.set_ylim(-90, 90)
plt.show()
Filter to the most serious alerts¶
The alert_level column makes it trivial to focus on Orange/Red alerts, and the glide column cross-references the same disaster in ReliefWeb and Copernicus EMS.
if alerts is not None and len(alerts):
serious = alerts[alerts['alert_level'].isin(['Orange', 'Red'])]
print(f'{len(serious)} Orange/Red alerts')
if len(serious):
display(serious[['name', 'hazard_type', 'alert_level', 'glide']].head())