Services
Services handle specific domains of logic: networking, geospatial operations, the index repositories, and data management.
Index & lookups (consumer)
The repositories that resolve a query against the local or remote index.
IndexRepository
IndexRepository(settings: Settings | None = None)
Locate index artifacts locally or from a remote published index.
Bind to a settings object (defaults to get_settings).
Methods:
| Name | Description |
|---|---|
index_source |
Return the path/URI to open the index COG with rasterio. |
open_index |
Return an open rasterio dataset for the index COG, cached per thread. |
local_index_missing |
True when the COG is neither local nor available remotely (hard error). |
ensure_tables |
Mirror the small tables (dict/events/meta/manifest) once, if hosted. |
mirror |
Download the full published bundle to the cache (offline / HPC mirror). |
Attributes:
| Name | Type | Description |
|---|---|---|
is_remote |
bool
|
True when the hosted index may be used (mode allows it + a base URL exists). |
Attributes
is_remote
property
True when the hosted index may be used (mode allows it + a base URL exists).
Methods:
index_source
Return the path/URI to open the index COG with rasterio.
A local file if present; otherwise a /vsicurl URL so the COG is read
remotely, one ROI window at a time, without downloading it.
open_index
Return an open rasterio dataset for the index COG, cached per thread.
Opening a remote COG re-reads its tile index over /vsicurl each time; caching
the open handle lets a repeat floods() in one process reuse it (and GDAL's
in-process block cache), so the second query is near-instant instead of paying the
re-open. Local COGs are cached too (cheap, harmless). Callers must not close the
returned dataset — use close_cached_datasets to release the cache.
local_index_missing
True when the COG is neither local nor available remotely (hard error).
ensure_tables
Mirror the small tables (dict/events/meta/manifest) once, if hosted.
No-op when reading a local bundle, or once the dictionary + events table are
cached. Leaves the big COG remote (streamed via /vsicurl).
DictionaryRepository
DictionaryRepository(settings: Settings | None = None)
Keyed lookup of flood events by combo_id (Parquet, with JSON fallback).
Detect the dictionary format; raise if none is present.
Methods:
| Name | Description |
|---|---|
lookup_combos |
Return |
EventsRepository
EventsRepository(settings: Settings | None = None)
Keyed lookup of flood-event metadata by global_id (from events.parquet).
Bind to a settings object; the table is read lazily per lookup.
Methods:
| Name | Description |
|---|---|
lookup_events |
Return |
Attributes:
| Name | Type | Description |
|---|---|---|
available |
bool
|
Whether the normalized events table exists in the cache. |
Attributes
Methods:
Geospatial
LocationResolver
LocationResolver(
settings: Settings | None = None,
geocoder: GeocodingService | None = None,
)
Resolve a region specification to a single WGS84 shapely geometry.
Initialize the resolver.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
settings
|
Settings | None
|
Optional configuration. Defaults to |
None
|
geocoder
|
GeocodingService | None
|
Optional injected GeocodingService (for place names). |
None
|
Methods:
| Name | Description |
|---|---|
resolve |
Resolve exactly one location input to a WGS84 geometry. |
buffer_metric |
Buffer a WGS84 geometry by metres (project → buffer → project back). |
Methods:
resolve
resolve(
region: (
str
| BaseGeometry
| GeoDataFrame
| tuple[float, float, float, float]
| None
) = None,
*,
point: tuple[float, float] | None = None,
radius_m: float = 0.0,
bbox: tuple[float, float, float, float] | None = None,
shapefile: str | Path | None = None,
buffer_m: float = 0.0,
level: int | None = None,
shape: str = "exact"
) -> BaseGeometry
Resolve exactly one location input to a WGS84 geometry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
region
|
str | BaseGeometry | GeoDataFrame | tuple[float, float, float, float] | None
|
A place name, shapely geometry, GeoDataFrame, or bbox tuple. |
None
|
point
|
tuple[float, float] | None
|
A (lat, lon) point; combine with |
None
|
radius_m
|
float
|
Radius in metres around |
0.0
|
bbox
|
tuple[float, float, float, float] | None
|
A (minx, miny, maxx, maxy) bounding box in WGS84. |
None
|
shapefile
|
str | Path | None
|
Path to a vector file (read via geopandas, unioned). |
None
|
buffer_m
|
float
|
Optional extra metric buffer applied to the result. |
0.0
|
level
|
int | None
|
Optional NUTS level filter for place-name resolution. |
None
|
shape
|
str
|
How to regularize the resolved geometry before buffering:
|
'exact'
|
Returns:
| Name | Type | Description |
|---|---|---|
BaseGeometry |
BaseGeometry
|
The resolved geometry in EPSG:4326. |
Raises:
| Type | Description |
|---|---|
GeocodingError
|
If zero or more than one input is given, the input type
is unsupported, or |
buffer_metric
staticmethod
Buffer a WGS84 geometry by metres (project → buffer → project back).
join_style controls corners: "round" (default) for organic shapes,
"mitre" to keep a bounding box / convex hull sharp-cornered so it grows
into a larger polygon of the same kind rather than a rounded one.
GeocodingService
GeocodingService(
settings: Settings | None = None,
downloader: DownloadService | None = None,
)
Resolve administrative-area place names to WGS84 geometries.
The backend is chosen by settings.geocoder_backend:
"online_first"(default) — query OpenStreetMap Nominatim, then fall back to the offline Eurostat NUTS dataset on any network failure or empty result."nominatim"— online only (no offline fallback)."local"— the offline NUTS dataset only (fully offline). Tolerant of accents/case, bilingual and suffixed names, common exonyms, and close typos.
Attributes:
| Name | Type | Description |
|---|---|---|
settings |
The active configuration. |
|
backend |
The resolved backend name (see above). |
Initialize the GeocodingService.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
settings
|
Settings | None
|
Optional configuration. Defaults to |
None
|
downloader
|
DownloadService | None
|
Optional injected DownloadService used to fetch the local boundary dataset on first use. |
None
|
Methods:
| Name | Description |
|---|---|
get_geometry |
Resolve a place name to a single shapely geometry in EPSG:4326. |
Methods:
get_geometry
Resolve a place name to a single shapely geometry in EPSG:4326.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
str
|
Place name, e.g. "Cologne, Germany". Only the part before the first comma is matched against the local dataset. |
required |
level
|
int | None
|
Optional NUTS level filter (0=country ... 3=small region). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
BaseGeometry |
BaseGeometry
|
The (possibly multi-) polygon in EPSG:4326. |
Raises:
| Type | Description |
|---|---|
GeocodingError
|
If the place cannot be resolved. |
RasterOps
Utilities for manipulating raster files.
Methods:
| Name | Description |
|---|---|
project_geometry |
Reproject a shapely geometry to a different Coordinate Reference System. |
crs_of |
Return a raster's CRS without materializing a band (a cheap header read). |
read_array |
Read one band of a raster into memory with its georeferencing. |
crop_raster |
Crop a raster to a given geometry. |
mosaic_and_crop |
Mosaic one or more rasters over an ROI window, then crop to a geometry. |
Methods:
project_geometry
staticmethod
Reproject a shapely geometry to a different Coordinate Reference System.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
geom
|
BaseGeometry
|
The input shapely geometry. |
required |
to_crs
|
CRS
|
The target CRS (e.g., CRS("EPSG:3857")). |
required |
from_crs
|
CRS
|
The source CRS. Defaults to CRS("EPSG:4326"). |
WGS84
|
Returns:
| Name | Type | Description |
|---|---|---|
BaseGeometry |
BaseGeometry
|
The reprojected geometry. |
crs_of
staticmethod
Return a raster's CRS without materializing a band (a cheap header read).
Lets callers branch on the CRS (e.g. reproject-if-geographic) before deciding how to read, so the band is read exactly once instead of once to inspect the CRS and again to actually use it.
read_array
staticmethod
read_array(
source_path: str | Path,
*,
band: int = 1,
to_crs: Any = None,
resampling: Resampling = bilinear
) -> tuple[Any, Any, Any, float | None]
Read one band of a raster into memory with its georeferencing.
Returns the (array, transform, crs, nodata) triple that plotting needs
— the same data crop_raster / mosaic_and_crop compute but
write to disk. The raster is assumed to already be on disk (e.g. a
.download() output).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source_path
|
str | Path
|
Path (or |
required |
band
|
int
|
1-based band index to read (default 1). |
1
|
to_crs
|
Any
|
If given (e.g. |
None
|
resampling
|
Resampling
|
Resampling method used when |
bilinear
|
Returns:
| Type | Description |
|---|---|
Any
|
The 2-D array, the affine |
Any
|
|
crop_raster
staticmethod
crop_raster(
source_path: Path,
output_path: Path,
geometry: BaseGeometry,
crop_to_poly: bool = True,
) -> bool
Crop a raster to a given geometry.
This method reads a source raster, masks it using the provided geometry, and writes the result to a new file. It handles CRS mismatches by reprojecting the geometry to match the raster's CRS.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source_path
|
Path
|
Path to the input TIF file. |
required |
output_path
|
Path
|
Path where the cropped TIF will be saved. |
required |
geometry
|
BaseGeometry
|
The shapely geometry defining the crop area (usually in WGS84). |
required |
crop_to_poly
|
bool
|
If True, sets pixels outside the polygon to NoData. If False, crops to the bounding box of the geometry. Defaults to True. |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if successful and data was written, False otherwise (e.g., no overlap or empty result). |
mosaic_and_crop
staticmethod
mosaic_and_crop(
sources: Sequence[str | Path],
output_path: Path,
geometry: BaseGeometry,
*,
nodata: float | None = None,
crop_to_poly: bool = True
) -> bool
Mosaic one or more rasters over an ROI window, then crop to a geometry.
Opens each source (a local path or a /vsicurl/ URL), merges them
with rasterio.merge.merge(bounds=geometry.bounds) so only the ROI
window of each source is read (bounded memory regardless of full tile
size), optionally masks pixels outside the polygon to nodata, and
writes an LZW GeoTIFF. Handles 1..N sources uniformly (a single source is
a no-op mosaic).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sources
|
Sequence[str | Path]
|
Local paths or |
required |
output_path
|
Path
|
Where to write the cropped mosaic. |
required |
geometry
|
BaseGeometry
|
ROI geometry (usually WGS84); reprojected to the source CRS. |
required |
nodata
|
float | None
|
NoData value for merge/masking and the emptiness check. |
None
|
crop_to_poly
|
bool
|
If True, set pixels outside the polygon to |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if non-empty data was written, False otherwise (no overlap |
bool
|
or an entirely-NoData result). |
HazardTileIndex
HazardTileIndex(
settings: Settings | None = None,
downloader: DownloadService | None = None,
)
Cache and query the GLOFAS tile-extents GeoJSON.
Build the index.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
settings
|
Settings | None
|
Optional configuration. Defaults to |
None
|
downloader
|
DownloadService | None
|
Optional injected DownloadService. Defaults to one writing
into |
None
|
Methods:
| Name | Description |
|---|---|
tiles_for |
Return the tiles whose extent intersects |
all_tiles |
Return every tile for |
Network & IO
ScraperService
ScraperService(settings: Settings | None = None)
Handles navigation and parsing of the remote JRC FTP-like website.
This service connects to the base URL defined in settings, recursively navigates year directories, and parses HTML links to identify valid flood map TIF files based on a regex pattern.
Attributes:
| Name | Type | Description |
|---|---|---|
base_url |
str
|
The root URL to scrape. |
session |
Session
|
Persistent HTTP session for efficiency. |
file_pattern |
Pattern
|
Regex pattern to match valid filenames. |
Initialize the ScraperService.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
settings
|
Settings | None
|
Optional configuration. Defaults to |
None
|
Methods:
| Name | Description |
|---|---|
fetch_all_records |
Crawls all year directories and returns raw record dictionaries. |
Methods:
fetch_all_records
Crawls all year directories and returns raw record dictionaries.
Iterates through every year folder found by _get_year_links, scrapes
the TIF files within, and extracts metadata using the regex pattern.
Returns:
| Type | Description |
|---|---|
list[dict[str, Any]]
|
List[Dict[str, Any]]: List of dictionaries compatible with the FloodRecord schema. Each dict contains keys: global_id, filename, year, start_date, cluster_id, download_url. |
Note
Failures in specific year folders are logged as errors but do not stop the scraping of other years.
DownloadService
DownloadService(
download_dir: Path | None = None,
settings: Settings | None = None,
)
Manages file downloads with caching and retry logic.
This service ensures files are downloaded reliably to the local cache. It checks if files already exist to avoid redundant downloads and uses atomic file writing (download to .tmp -> rename) to prevent partial files.
Attributes:
| Name | Type | Description |
|---|---|---|
download_dir |
Path
|
The directory where downloaded files are stored. |
Initialize the DownloadService.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
download_dir
|
Optional[Path]
|
Target directory for downloads.
Defaults to |
None
|
settings
|
Settings | None
|
Optional configuration. Defaults to |
None
|
Methods:
| Name | Description |
|---|---|
download_file |
Download a file if it doesn't exist locally (or is the wrong size). |
Methods:
download_file
download_file(
url: str,
filename: str,
expected_size: int | None = None,
*,
on_bytes: Callable[[int], None] | None = None
) -> Path | None
Download a file if it doesn't exist locally (or is the wrong size).
Checks the cache first. If the file is missing, empty, or — when
expected_size is given — a different size than expected, it is
(re-)downloaded. A size mismatch means a stale/corrupt cache file (e.g.
from an older interrupted run), so it is re-fetched.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
Remote URL. |
required |
filename
|
str
|
Target filename to save as in the download directory. |
required |
expected_size
|
Optional[int]
|
Expected file size in bytes. When set, a cached file whose size differs is treated as corrupt and re-downloaded. |
None
|
on_bytes
|
Callable[[int], None] | None
|
Optional per-chunk progress callback |
None
|
Returns:
| Type | Description |
|---|---|
Path | None
|
Optional[Path]: Path to the downloaded file if successful, or None if failed. |
Data processing (producer)
RasterProcessor
RasterProcessor(settings: Settings | None = None)
Converts raw Flood TIFs into standardized sparse point data (Parquet).
The processor performs the following steps:
1. Reads the raster TIF in full-width row stripes (bounded memory).
2. Filters for valid data (wet pixels > 0).
3. Transforms pixel coordinates to WGS84 Lat/Lon.
4. Maps these Lat/Lon coordinates to the GlobalGrid indices (col, row).
5. Saves the result as a Parquet file for efficient aggregation later.
Initialize the RasterProcessor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
settings
|
Settings | None
|
Optional configuration. Defaults to |
None
|
Methods:
| Name | Description |
|---|---|
process |
Process a single TIF file. |
Methods:
process
Process a single TIF file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tif_path
|
Path
|
Path to source TIF file. |
required |
global_id
|
int
|
Unique ID assigned to this flood event (from inventory). |
required |
year
|
str
|
Year string for directory organization. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Number of points stored in the parquet file. Returns 0 if the file was empty, skipped, or had no valid pixels. |
Raises:
| Type | Description |
|---|---|
ProcessingError
|
If an error occurs during raster reading or processing. |
InventoryRepository
InventoryRepository(settings: Settings | None = None)
Handles loading, saving, and querying the flood map inventory.
The inventory is stored as a CSV file defined in settings.inventory_filename.
It uses Pydantic for validation before saving to ensure data integrity.
Attributes:
| Name | Type | Description |
|---|---|---|
csv_path |
Path
|
Path to the inventory CSV file. |
Initiate Inventory Repository.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
settings
|
Settings | None
|
Optional configuration. Defaults to |
None
|
Methods:
| Name | Description |
|---|---|
save |
Validate and save records to CSV. |
load |
Load the inventory into a pandas DataFrame. |
exists |
Check if inventory file exists. |
Methods:
save
Validate and save records to CSV.
Converts raw dictionaries into FloodRecord Pydantic models to validate them,
then serializes them to a CSV file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
records
|
List[Dict[str, Any]]
|
List of raw dictionaries obtained from the scraper. |
required |
Note
If records is empty, no file is written and a warning is logged.
load
Load the inventory into a pandas DataFrame.
Returns:
| Type | Description |
|---|---|
DataFrame
|
pd.DataFrame: DataFrame containing the inventory. Returns an empty DataFrame if the file does not exist. |
Statistics
depth_raster_stats
depth_raster_stats(
path: str | Path,
*,
scale: float = 0.01,
max_depth: float | None = None
) -> dict[str, float]
Summarize one downloaded depth GeoTIFF.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
A downloaded depth GeoTIFF. |
required |
scale
|
float
|
Multiplier applied to raster values (EFAS depth is centimetres, so
the default |
0.01
|
max_depth
|
float | None
|
Optional upper bound (in raster units) above which pixels are treated as suspect and excluded. |
None
|
Returns:
| Type | Description |
|---|---|
dict[str, float]
|
A dict with |
dict[str, float]
|
|
dict[str, float]
|
(million m³). An all-dry raster yields zeros. |
catalogue_stats
Per-event depth statistics for a catalogue's downloaded rasters.
One row per downloaded event, carrying the identifying columns (event_id /
date for historic, return_period for hazard) alongside the
depth_raster_stats fields. Reads only already-downloaded rasters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frame
|
Any
|
A catalogue (a downloaded |
required |
scale
|
float | None
|
Raster-value->metre multiplier. |
None
|
Raises:
| Type | Description |
|---|---|
ProcessingError
|
If nothing has been downloaded. |
catalogue_summary
Aggregate (envelope) depth statistics across a catalogue's downloaded rasters.
Combines the rasters into a per-pixel MAX composite and summarizes that, so
overlapping events are counted once: the returned flooded_area_km2 is the
union footprint and volume_m3 the envelope volume. Adds n_events (how
many rasters went in). Reads only already-downloaded rasters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frame
|
Any
|
A catalogue (a downloaded |
required |
scale
|
float | None
|
Raster-value->metre multiplier. |
None
|
Raises:
| Type | Description |
|---|---|
ProcessingError
|
If nothing has been downloaded. |