This page defines how the data mounted at HOST_RASTER_ROOT must be
organised. The backend discovers scenarios, rasters and FIAT outputs by
walking this folder structure — there is no database of file paths, so the
layout on disk is the contract.
Inside every container this folder is mounted at /data/rasters (set by
RASTER_ROOT) and served to the browser under the /rasters/ URL prefix.
The canonical tree¶
<HOST_RASTER_ROOT>/ # e.g. D:/Projects/RHTfolder/data/rat_data-500
└── <city>/ # MUST be a known city: "rotterdam" or "chennai" (alias "tambaram")
└── <scenario>/ # one folder per scenario; the folder name IS the scenario name
├── metadata.json # optional but recommended (see below)
├── <collection>/ # a "layer group", e.g. depth, water_level, hazard …
│ ├── h_20200101_000000.tif # Cloud-Optimized GeoTIFF, EPSG:3857
│ ├── h_20200101_010000.tif
│ └── …
├── velocity/ # special collection: paired flow vectors
│ ├── U_20200101_000000.tif
│ ├── V_20200101_000000.tif
│ └── …
├── FIAT/ # FIAT impact outputs (also accepts lowercase "fiat")
│ └── impact.gpkg # GeoPackage(s)
├── road/ # road-safety overlay (served statically, not via the catalog API)
│ └── safety_map.geojson
└── nc/ # source data — IGNORED by the catalog (see "skipped" below)A concrete, correct example¶
rat_data-500/
└── rotterdam/
└── 1_base_scenario/
├── metadata.json
├── depth/
│ ├── h_20200101_000000.tif
│ └── h_20200101_010000.tif
└── velocity/
├── U_20200101_000000.tif
└── V_20200101_000000.tifRules the backend enforces¶
These come straight from backend/api/views.py (RasterCatalogView,
FiatCatalogView) and the nginx config in deploy/.
Top level = city. Only folders whose name matches a known city alias are scanned. Recognised:
rotterdam,chennai(aliasestambaram,tambaramchennai). Anything else at the top level is silently ignored.Second level = scenario. Every sub-folder of a city is treated as one scenario. The folder name becomes the scenario’s name in the API (
scenarios: [...]). A numeric prefix such as1_base_scenariois allowed — it is just part of the name.Third level = collection. Each sub-folder of a scenario is a “collection” (a display layer group). The catalog recursively finds every
.tif/.tiffunder it. Name collections by what they contain (depth,water_level,hazard,velocity) — not after the scenario.velocity/is special. Files are paired into flow vectors by a shared key:U_<key>.tif+V_<key>.tif. Unpaired tifs fall back to magnitude-only frames.Skipped collections. Folders named
nc,netcdf, orsourceare treated as raw inputs and are not exposed as display layers.FIAT outputs. A folder named
FIATorfiatis scanned for*.gpkgfiles, surfaced via the/api/fiat/endpoint.Legacy layout. Loose
.tiffiles placed directly under a scenario folder (with no collection sub-folder) still work — they appear as an unnamed collection. Prefer explicit collection folders for new data.Rasters must be COGs in EPSG:3857. Convert source GeoTIFFs in place with:
python manage.py convert_rasters_to_cog --path rotterdam/1_base_scenario
metadata.json¶
Optional, placed at the scenario root. If absent, the city is inferred from the parent folder. Recognised keys:
{
"city": "rotterdam",
"name": "Base scenario",
"description": "Baseline run, no interventions",
"climate_scenario": "50",
"simulation_status": "completed"
}The road-safety overlay (important caveat)¶
The road overlay is not part of the catalog API — the frontend fetches a
fixed file directly through nginx’s /rasters/ static alias. The path is
hard-coded in frontend/src/routes/planning/+page.svelte:
/rasters/rotterdam/base_scenario/road/safety_map.geojsonTwo things to note:
The file must exist on disk at
<HOST_RASTER_ROOT>/rotterdam/base_scenario/road/safety_map.geojson, otherwise the “Show roads” button returns 404 (the rest of the app is unaffected).⚠️ The hard-coded path uses
base_scenariowithout a numeric prefix, which does not match the1_base_scenarioconvention used by the scenario catalog. If you keep number-prefixed scenario folders, either add a matchingbase_scenario/road/folder for this static file, or update theROAD_NETWORK_PATHSmap in the frontend to point at your actual folder.
How a file maps to a URL¶
For a raster at <root>/rotterdam/1_base_scenario/depth/h_20200101_000000.tif:
| Purpose | URL |
|---|---|
| Static download | /rasters/rotterdam/1_base_scenario/depth/h_20200101_000000.tif |
| Tile (via titiler) | /tiles/cog/...?url=file:///data/rasters/rotterdam/1_base_scenario/depth/h_20200101_000000.tif |
Common mistakes¶
Double-nesting the scenario name, e.g.
rotterdam/1_base_scenario/1_base_scenario/*.tif. This technically loads, but the layer group ends up named1_base_scenarioinstead of something meaningful likedepth. Rename the inner folder to a real collection name.City folder not recognised (typo, or a name outside the alias list) — the whole scenario disappears from the catalog with no error.
TIFFs not converted to COG / wrong CRS — tiles fail to render. Run
convert_rasters_to_cog.Missing
road/safety_map.geojson— only the road overlay breaks; see the caveat above.