Skip to content

Commit fac0a5d

Browse files
docs(cems): seed CEMS source analysis (#20 familiarisation)
Groundwork for the CEMS Rapid Mapping source analysis (esa-montandon#21), from hands-on exploration of the live public API (esa-montandon#20): - Capture real API fixtures under docs/model/sources/CEMS/api-files/: EMSR847 (storm; carries gdacsId + charterNumber/charterUrl), EMSR871 (flood; has FEP), EMSR842 (wildfire; minimal), plus list-endpoint samples. - FINDINGS.md: endpoint map, activation/AOI/product model, GRA stats -> Impact source, statusCode/monitoring on version, and validation against the merged response taxonomy (REF/FEP/DEL/GRA -> eo-ref/fep/del/gra, SR=eo-sr Response). - Cross-source linkage guidance: derive the target source item id from gdacsId (GDACS {eventid}-{episodeid}) and charterNumber (charter-event-{id}) and emit explicit rel:related links, not only a shared monty:corr_id. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 04132f8 commit fac0a5d

6 files changed

Lines changed: 103 additions & 0 deletions

File tree

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# CEMS Rapid Mapping — API & Data Model Familiarisation (esa-montandon #20)
2+
3+
Hands-on exploration of the live CEMS Rapid Mapping API. Public, no auth. Sample
4+
activations captured in this folder: **EMSR847** (storm, rich), **EMSR842** (wildfire,
5+
minimal), **EMSR871** (flood, has FEP), plus list pages.
6+
7+
## 1. Endpoints & access
8+
9+
| Endpoint | Purpose |
10+
|---|---|
11+
| `GET rapidmapping.emergency.copernicus.eu/backend/dashboard-api/public-activations-info/?limit=&offset=` | RM activation **list** (224 activations). DRF pagination: `{count,next,previous,results}`. |
12+
| `GET rapidmapping.emergency.copernicus.eu/backend/dashboard-api/public-activations/?code=EMSR847` | **Rich activation detail** — AOIs, products, images, stats, cross-refs. **The ETL entry point.** Returns `{count,next,previous,results:[{...}]}` (single result). |
13+
| `GET mapping.emergency.copernicus.eu/activations/api/activations/?limit=&offset=` | Unified list (RM + Risk&Recovery). Different shape (`category` is an object `{slug,name}`, has `drmPhase`, `search_snippet`). Discovery only. |
14+
15+
- Pagination: `limit`/`offset`; list `count=224`. No auth, no obvious rate limit hit during exploration.
16+
- Licence: Copernicus — free & open, attribution "© European Union, Copernicus Emergency Management Service".
17+
18+
## 2. Activation payload (detail endpoint → `results[0]`)
19+
20+
Fields: `code` (EMSR847), `name`, `reason` (free-text description), `category` (Storm),
21+
`subCategory` (Tropical cyclone…), `sensitive` (bool), **`reportLink`** (ArcGIS StoryMap URL
22+
= the **Situational Report**), `activator`, `eventTime`, `activationTime`, `closed` (bool),
23+
**`gdacsId`** (e.g. `TC1001230`), `continent`, `countries` (`[{name}]`), **`aois`** (list),
24+
`centroid` (WKT POINT), `infobulletins`, **`stats`** (aggregated damage figures),
25+
**`charterNumber`** + **`charterUrl`** (Charter co-activation), `extent` (WKT POLYGON),
26+
`aws_bucket`, `productsPath`, `relatedevents`.
27+
28+
Activation-level `stats` = aggregated thematic figures, e.g.
29+
`{"Roads [km]":206.4,"Built-up [ha]":19.5,"Built-up [No.]":48253,"Population [No.]":13030,"max_extent":8552.7}`.
30+
31+
### AOI (`results[0].aois[i]`)
32+
`{name, extent (WKT POLYGON), number, activationCode, products:[...], blpPath}`.
33+
34+
### Product (`aois[i].products[j]`) — maps to Monty **Response**
35+
`{id, type, monitoring (bool), monitoringNumber (int), feasible (bool), images:[...],
36+
stats, mapsCount, activationCode, aoiName, aoiNumber, extent (WKT), expectedDelivery,
37+
layers:[...], downloadPath, version:{...}}`
38+
39+
- **`type`** observed: `REF`, `FEP`, `DEL`, `GRA` (all four RM map products). **`SR` is NOT a product** — it is the activation-level `reportLink` StoryMap.
40+
- **`version`** = `{uuid, number, reason, deliveryTime, statusCode}`. **`statusCode`** observed: `F` (final/produced), `N` (not produced / not feasible). Status lives on `version`, not the product root.
41+
- **`monitoring`/`monitoringNumber`**: base = 0; monitoring iterations = 1, 2, … (EMSR847: monitoringNumber ∈ {0,1,2}).
42+
- **`images[]`** (the acquisition): `{uuid, new, sensorType (sar/optical), sensorName (ICEYE…), resolutionClass (VHR2…), acquisitionTime, fileName}`.
43+
- **`layers[]`** (web/COG assets): `{name, format (cog)}` — ArcGIS/COG raster layers.
44+
- **`downloadPath`**: per-product ZIP, e.g. `…/backend/EMSR847/AOI01/GRA_PRODUCT/EMSR847_AOI01_GRA_PRODUCT_v1.zip`.
45+
46+
### GRA product `stats` — the **Impact** source
47+
Nested `{thematic_class: {sub_class: {unit, total, affected}}}`, e.g.
48+
`{"Landslide":{"None":{"unit":"","total":"NA","affected":1}},"Estimated population":{"None":{"total":84000}}}`.
49+
`total` may be `"NA"`. Only GRA carries per-product stats (REF/DEL/FEP: `stats:null`).
50+
51+
## 3. Validation against the merged taxonomy (`response-taxonomy.md`, `response-best-practices.md`)
52+
53+
- ✅ Product→type-code crosswalk holds: `REF→eo-ref`, `FEP→eo-fep`, `DEL→eo-del`, `GRA→eo-gra`, `SR→eo-sr`.
54+
-`monitoring`/`monitoringNumber``monty:response_detail.monitoring_number` (set only when `monitoring=true`).
55+
-`statusCode``monty:response_detail.status` (need enum mapping: `F`→published/finished, `N`→no-impact/withdrawn; confirm other codes exist historically).
56+
-`resolutionClass` (on `images[]`) → carried on the linked acquisition, not the Response root.
57+
- 🟢 `eventTime` vs `activationTime` — two distinct timestamps (event onset vs Charter/CEMS activation). Onset = `eventTime`.
58+
-`eo-sr` is **resolved as Response** in the taxonomy; structurally the SR is a StoryMap URL (`reportLink`), a produced report — consistent with Response. No geospatial asset; model as a Response item whose asset is the StoryMap link.
59+
60+
### 3b. Cross-source linkage — derive `related` links, not just a shared `corr_id`
61+
62+
The activation carries hard cross-references to sibling sources. Beyond co-referencing
63+
via a shared `monty:corr_id`, the ETL **SHOULD derive the target source's Monty item id
64+
and emit an explicit `rel: related` link** (with the appropriate `roles`). This makes the
65+
graph navigable directly (`related`) instead of only query-joinable (`corr_id`).
66+
67+
| CEMS field | Example | Target Monty item id (derivation) | Link to emit |
68+
|---|---|---|---|
69+
| `gdacsId` | `TC1001230` | GDACS uses `{eventtype}` + `{eventid}`; Monty id = `{eventid}-{episodeid}` in collection `gdacs-events` (e.g. `1001230-1`). Split `TC`/`1001230`; resolve/assume episode (default `1`, or link at event level). | `rel: related`, `roles: ["event"]` → GDACS **Event** |
70+
| `charterNumber` (+ `charterUrl`) | `996` | Charter Monty Event id = `charter-event-{activation_id}``charter-event-996` (collection `charter-events`); Charter VAP/eo-dat Responses under `charter-response`. | `rel: related`, `roles: ["event"]` → Charter **Event** (and optionally `roles: ["response"]` to Charter VAP Responses) |
71+
72+
Notes for #21 to resolve:
73+
74+
- **Episode ambiguity for GDACS**: `gdacsId` gives eventtype+eventid but not the episode; decide whether to link the latest episode, all episodes, or the event without episode.
75+
- **Existence**: the target item may not yet be ingested in Montandon; emit the `related`
76+
link by convention regardless (id is deterministic), or gate on presence — a #21 decision.
77+
- **Generalise**: treat this as a reusable pattern — any source cross-ref field that yields a
78+
deterministic source-item id (GLIDE, Charter, GDACS, EMSR↔EMSR `relatedevents`) becomes a
79+
typed `related` link, keeping `corr_id` as the fallback join.
80+
- Same idea applies **outward**: the Charter source doc already links a VAP to sibling
81+
Responses via `related`/`response` — the CEMS↔Charter edge should be reciprocal.
82+
83+
## 4. Data access patterns
84+
85+
- **Detail endpoint is the ETL unit**: one call per activation code yields everything (AOIs → products → images/stats/layers/downloads).
86+
- Discover codes via the list endpoint (paginated, 224 RM activations; `category` values seen: Flood, Wildfire, Storm, Earthquake, Other).
87+
- Assets: per-product `downloadPath` (ZIP of vector+raster), `layers[]` (COG), `images[].fileName` (source imagery). `aws_bucket` + `productsPath` give S3/backend roots.
88+
- Cross-source keys on the activation: `gdacsId` (GDACS), `charterNumber`/`charterUrl` (Charter).
89+
90+
## 5. Open items to carry into the analysis (#21)
91+
92+
1. Full **`statusCode` enum** (only `F`,`N` seen) and its `monty:response_detail.status` mapping.
93+
2. **FEP/REF** field completeness (fewer samples) — confirm images/assets shape.
94+
3. **Category → `monty:hazard_codes`** crosswalk (CEMS `category`/`subCategory` → UNDRR-ISC) — needs a table like Charter's.
95+
4. **Monitoring lineage**: how to link monitoring iteration *n* to *n-1* (`rel: prev`?) — `version.number` vs `monitoringNumber`.
96+
5. **AOI → geometry**: model per-AOI (like Charter Area→Hazard) or per-product extent.
97+
6. **RSS feeds** (WP2 trigger) not yet explored — listed in the epic but out of WP1 ETL scope.
98+
7. Reference activations for tests: **EMSR847** (storm, Charter+GDACS cross-refs, monitoring, 67 products), **EMSR871** (flood, has FEP), **EMSR842** (wildfire, minimal, 2 GRA).
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"count":1,"next":null,"previous":null,"results":[{"code":"EMSR842","name":"Wildfire in Spain and Portugal","reason":"On September 8, at 7:00 PM, a forest fire broke out in Castromil-Hermisende (Zamora), Castile and León. The CopernicusEMS Rapid Mapping classification product was used to\r\nassess the damage and obtain detailed maps of the affected area and vegetation. The fire was already under control.","category":"Wildfire","subCategory":"Forest fire","sensitive":false,"reportLink":"https://storymaps.arcgis.com/stories/5ea3a53eaf18421a935c7a18c86c5369","activator":"Spain|Ministry of Interior - Centro Nacional de Emergencias (CENEM) de la Direccion General de Proteccion Civil y Emergencias","eventTime":"2025-09-08T19:00:00","activationTime":"2025-09-19T09:53:00","closed":true,"gdacsId":null,"continent":"Europe","countries":[{"name":"Spain"}],"aois":[{"name":"Zamora","extent":"POLYGON ((-6.981267 42.01644, -6.980345 42.018271, -6.952763 42.016983, -6.922174 41.980112, -6.978841 41.959103, -7.001363 41.98741, -6.981509 42.003748, -6.982817 42.006956, -6.98463 42.009266, -6.981267 42.01644))","number":1,"activationCode":"EMSR842","products":[{"id":1955,"type":"GRA","monitoring":false,"monitoringNumber":0,"feasible":true,"images":[{"uuid":"f6faf877-504e-440d-805f-d9d8dbdace83","new":true,"sensorType":"optical","sensorName":"GeoSat-2","resolutionClass":"VHR1","acquisitionTime":"2025-09-21T09:41:00","fileName":"EMSR842_AOI01_GRA_PRODUCT_GEOSAT2_20250921_0941_ORTHO.tif"}],"stats":{"Built-up":{"Residential Buildings":{"unit":"","total":344,"affected":1}},"Land use":{"Pastures ":{"unit":"ha","total":69.4,"affected":51.9},"Heterogeneous agricultural areas ":{"unit":"ha","total":642.6,"affected":81.3},"Shrub and/or herbaceous vegetation association":{"unit":"ha","total":1248.6,"affected":239.4}},"Burnt area":{"None":{"unit":"ha","total":"NA","affected":372.6}},"Transportation":{"Cart Track":{"unit":"km","total":43.6,"affected":2.0}},"Estimated population":{"None":{"unit":"","total":90}}},"mapsCount":1,"activationCode":"EMSR842","aoiName":"Zamora","aoiNumber":1,"extent":"POLYGON ((-6.98463 42.009266, -6.981267 42.01644, -6.980345 42.018271, -6.952763 42.016983, -6.922174 41.980112, -6.978841 41.959103, -7.001363 41.98741, -6.981509 42.003748, -6.982817 42.006956, -6.98463 42.009266))","expectedDelivery":"2025-09-21T22:15:00","layers":[{"name":"EMSR842/AOI01/GRA_PRODUCT/EMSR842_AOI01_GRA_PRODUCT_GEOSAT2_20250921_0941_ORTHO_cog.tif","format":"cog"},{"name":"EMSR842/AOI01/GRA_PRODUCT/EMSR842_AOI01_GRA_PRODUCT_builtUpP_v1_VT","format":"vt","sld":"https://rapidmapping-viewer.s3.eu-west-1.amazonaws.com/EMSR842/AOI01/GRA_PRODUCT/EMSR842_AOI01_GRA_PRODUCT_builtUpP_v1.sld","json":"https://rapidmapping-viewer.s3.eu-west-1.amazonaws.com/EMSR842/AOI01/GRA_PRODUCT/EMSR842_AOI01_GRA_PRODUCT_builtUpP_v1.json"},{"name":"EMSR842/AOI01/GRA_PRODUCT/EMSR842_AOI01_GRA_PRODUCT_naturalLandUseA_v1_VT","format":"vt","sld":"https://rapidmapping-viewer.s3.eu-west-1.amazonaws.com/EMSR842/AOI01/GRA_PRODUCT/EMSR842_AOI01_GRA_PRODUCT_naturalLandUseA_v1.sld","json":"https://rapidmapping-viewer.s3.eu-west-1.amazonaws.com/EMSR842/AOI01/GRA_PRODUCT/EMSR842_AOI01_GRA_PRODUCT_naturalLandUseA_v1.json"},{"name":"EMSR842/AOI01/GRA_PRODUCT/EMSR842_AOI01_GRA_PRODUCT_observedEventA_v1_VT","format":"vt","sld":"https://rapidmapping-viewer.s3.eu-west-1.amazonaws.com/EMSR842/AOI01/GRA_PRODUCT/EMSR842_AOI01_GRA_PRODUCT_observedEventA_v1.sld","json":"https://rapidmapping-viewer.s3.eu-west-1.amazonaws.com/EMSR842/AOI01/GRA_PRODUCT/EMSR842_AOI01_GRA_PRODUCT_observedEventA_v1.json"},{"name":"EMSR842/AOI01/GRA_PRODUCT/EMSR842_AOI01_GRA_PRODUCT_transportationL_v1_VT","format":"vt","sld":"https://rapidmapping-viewer.s3.eu-west-1.amazonaws.com/EMSR842/AOI01/GRA_PRODUCT/EMSR842_AOI01_GRA_PRODUCT_transportationL_v1.sld","json":"https://rapidmapping-viewer.s3.eu-west-1.amazonaws.com/EMSR842/AOI01/GRA_PRODUCT/EMSR842_AOI01_GRA_PRODUCT_transportationL_v1.json"}],"downloadPath":"https://rapidmapping.emergency.copernicus.eu/backend/EMSR842/AOI01/GRA_PRODUCT/EMSR842_AOI01_GRA_PRODUCT_v1.zip","version":{"uuid":"41030326-0270-40d6-b966-287441057c4e","number":1,"reason":"","deliveryTime":"2025-09-21T18:53:53.876489","statusCode":"F"}}],"blpPath":"https://rapidmapping.emergency.copernicus.eu/backend/EMSR842/AOI01/EMSR842_AOI01_BLP.zip"},{"name":"Pendilla de Arbas","extent":"POLYGON ((-5.650652 43.049807, -5.639964 42.990481, -5.754141 42.979684, -5.754213 43.041957, -5.650652 43.049807))","number":2,"activationCode":"EMSR842","products":[{"id":1959,"type":"GRA","monitoring":false,"monitoringNumber":0,"feasible":true,"images":[{"uuid":"91962f46-aed3-4d18-9d99-b6b81876424f","new":true,"sensorType":"optical","sensorName":"Pleiades","resolutionClass":"VHR1","acquisitionTime":"2025-09-24T11:31:00","fileName":"EMSR842_AOI02_GRA_PRODUCT_PLEIADES_20250924_1131_ORTHO.tif"}],"stats":{"Land use":{"Shrub and/or herbaceous vegetation association":{"unit":"ha","total":5221.7,"affected":285.2}},"Burnt area":{"None":{"unit":"ha","total":"NA","affected":285.2}},"Estimated population":{"None":{"unit":"","total":80}}},"mapsCount":1,"activationCode":"EMSR842","aoiName":"Pendilla de Arbas","aoiNumber":2,"extent":"POLYGON ((-5.754213 43.041957, -5.650652 43.049807, -5.639964 42.990481, -5.754141 42.979684, -5.754213 43.041957))","expectedDelivery":"2025-09-26T14:27:00","layers":[{"name":"EMSR842/AOI02/GRA_PRODUCT/EMSR842_AOI02_GRA_PRODUCT_PLEIADES_20250924_1131_ORTHO_cog.tif","format":"cog"},{"name":"EMSR842/AOI02/GRA_PRODUCT/EMSR842_AOI02_GRA_PRODUCT_naturalLandUseA_v1_VT","format":"vt","sld":"https://rapidmapping-viewer.s3.eu-west-1.amazonaws.com/EMSR842/AOI02/GRA_PRODUCT/EMSR842_AOI02_GRA_PRODUCT_naturalLandUseA_v1.sld","json":"https://rapidmapping-viewer.s3.eu-west-1.amazonaws.com/EMSR842/AOI02/GRA_PRODUCT/EMSR842_AOI02_GRA_PRODUCT_naturalLandUseA_v1.json"},{"name":"EMSR842/AOI02/GRA_PRODUCT/EMSR842_AOI02_GRA_PRODUCT_observedEventA_v1_VT","format":"vt","sld":"https://rapidmapping-viewer.s3.eu-west-1.amazonaws.com/EMSR842/AOI02/GRA_PRODUCT/EMSR842_AOI02_GRA_PRODUCT_observedEventA_v1.sld","json":"https://rapidmapping-viewer.s3.eu-west-1.amazonaws.com/EMSR842/AOI02/GRA_PRODUCT/EMSR842_AOI02_GRA_PRODUCT_observedEventA_v1.json"},{"name":"EMSR842/AOI02/GRA_PRODUCT/EMSR842_AOI02_GRA_PRODUCT_transportationL_v1_VT","format":"vt","sld":"https://rapidmapping-viewer.s3.eu-west-1.amazonaws.com/EMSR842/AOI02/GRA_PRODUCT/EMSR842_AOI02_GRA_PRODUCT_transportationL_v1.sld","json":"https://rapidmapping-viewer.s3.eu-west-1.amazonaws.com/EMSR842/AOI02/GRA_PRODUCT/EMSR842_AOI02_GRA_PRODUCT_transportationL_v1.json"}],"downloadPath":"https://rapidmapping.emergency.copernicus.eu/backend/EMSR842/AOI02/GRA_PRODUCT/EMSR842_AOI02_GRA_PRODUCT_v1.zip","version":{"uuid":"1a0da3ce-da9b-497a-821a-ebd0d42b9e04","number":1,"reason":"","deliveryTime":"2025-09-25T11:33:38.979151","statusCode":"F"}}],"blpPath":"https://rapidmapping.emergency.copernicus.eu/backend/EMSR842/AOI02/EMSR842_AOI02_BLP.zip"}],"centroid":"POINT (-6.972019 41.975269)","infobulletins":[],"stats":{"Roads [km]":2,"Built-up [ha]":1,"Population [No.]":"-","Event Extent [ha]":657.8},"charterNumber":null,"charterUrl":null,"extent":"POLYGON ((-7.001363 41.959103, -7.001363 43.049807, -5.639964 43.049807, -5.639964 41.959103, -7.001363 41.959103))","aws_bucket":"https://rapidmapping-viewer.s3.eu-west-1.amazonaws.com","productsPath":"https://rapidmapping.emergency.copernicus.eu/backend/EMSR842/EMSR842_products.zip","relatedevents":[]}]}

docs/model/sources/CEMS/api-files/EMSR847-storm-detail.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

docs/model/sources/CEMS/api-files/EMSR871-flood-detail.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"count":224,"next":"https://rapidmapping.emergency.copernicus.eu/backend/dashboard-api/public-activations-info/?limit=3&offset=3","previous":null,"results":[{"code":"EMSR888","countries":["Spain"],"eventTime":"2026-07-03T07:16:00","name":"Wildfires in Les Gavarres, Spain","centroid":"POINT (3.02689832031625 41.85008701143381)","activationTime":"2026-07-03T16:38:00","category":"Wildfire","lastUpdate":"2026-07-06T11:41:14.133381","closed":false,"gdacsId":null,"n_aois":1,"n_products":3},{"code":"EMSR887","countries":["Spain"],"eventTime":"2026-06-24T19:17:00","name":"Wildfire in Congosto, Spain","centroid":"POINT (-6.494080932059824 42.64167229370756)","activationTime":"2026-07-03T11:17:00","category":"Wildfire","lastUpdate":"2026-07-06T08:27:31.841835","closed":false,"gdacsId":null,"n_aois":1,"n_products":2},{"code":"EMSR886","countries":["Germany"],"eventTime":"2026-06-27T15:00:00","name":"Wildfire in Rhineland-Palatinate, Germany","centroid":"POINT (7.826469502837607 49.829754729741964)","activationTime":"2026-06-27T15:51:00","category":"Wildfire","lastUpdate":"2026-07-01T13:13:44.879338","closed":true,"gdacsId":null,"n_aois":1,"n_products":2}]}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"count":1022,"next":"http://mapping.emergency.copernicus.eu/activations/api/activations/?limit=2&offset=2","previous":null,"results":[{"code":"EMSR888","countries":[{"short_name":"Spain"}],"category":{"slug":"fire","name":"Wildfire"},"name":"Wildfires in Les Gavarres, Spain","centroid":"POINT (3.02689832031625 41.85008701143381)","activationTime":"2026-07-03T16:38:00","lastUpdate":"2026-07-06T11:41:14.133381","drmPhase":"response","closed":false,"n_aois":1,"n_products":3,"search_snippet":"A wildfire that broke out in the municipality of La Bisbal d'Empordà is spreading southward. Seven municipalities have been placed on alert via the ES-Alert system, affecting a total of 12,000 residents. . Copernicus EMS Rapid Mapping is requested to provide initial rough estimation, wildfire ex...","past_items_search_text":""},{"code":"EMSR887","countries":[{"short_name":"Spain"}],"category":{"slug":"fire","name":"Wildfire"},"name":"Wildfire in Congosto, Spain","centroid":"POINT (-6.494080932059824 42.64167229370756)","activationTime":"2026-07-03T11:17:00","lastUpdate":"2026-07-06T08:27:31.841835","drmPhase":"response","closed":false,"n_aois":1,"n_products":2,"search_snippet":"On 24 June 2026 at 21:27, a wildfire was reported to have affected the Congosto area, León Province, Castilla y León, Spain. The event is on-going and spreading, with damage reported to affect forestry, natural vegetation and potentially nearby infrastructure. Copernicus EMS Rapid Mapping is requ...","past_items_search_text":""}]}

0 commit comments

Comments
 (0)