---
name: "sentinel-1-water"
description: "Genera script Google Earth Engine per mappatura alluvioni da Sentinel-1 GRD VV. Prende AOI (GeoJSON) e data evento. Output: script GEE, sintesi parametri."
model_tier: 2
triggers:
  - "generascript alluvione gee"
  - "sentinel-1 flood script"
  - "mappatura alluvione script"
  - "sentinel-1 water"
  - "sar flood"
tools:
  - exec
  - message
  - python
---

# 🛰️ Sentinel-1 Water Detection — SAR Flood Mapping (Google Earth Engine)

## Scopo
Questa skill genera uno script JavaScript per Google Earth Engine (GEE) che esegue la mappatura delle aree allagate utilizzando i dati SAR (Synthetic Aperture Radar) di Sentinel-1. L'analisi compara immagini pre-evento (secche) e post-evento (umide) per rilevare variazioni che indicano la presenza di acqua. L'utente dovrà copiare e incollare lo script generato nel proprio ambiente GEE per l'esecuzione.

## Input Richiesti della Skill:

### 1. `aoi_geojson_string` (stringa, richiesto)
   - Una stringa **GeoJSON** valida (non un percorso a un file SHP) che definisce l'Area di Interesse (AOI).
   - Le coordinate devono essere in **Latitudine/Longitudine WGS84 (EPSG:4326)**.
   - Esempio: `'{"type":"Polygon","coordinates":[[[41.568,4.643],[41.948,4.643],[41.946,4.409],[41.568,4.409],[41.568,4.643]]]}]'`
   - **IMPORTANTE**: Se il tuo AOI è in formato Shapefile (.shp e file correlati), dovrai prima utilizzare uno strumento esterno (es. QGIS, convertitore online) per convertirlo in una singola stringa GeoJSON con le coordinate WGS84 Latitudine/Longitudine, da passare a questa skill.

### 2. `event_date` (stringa, richiesto)
   - La data dell'evento di alluvione in formato `YYYY-MM-DD` (es. `'2018-04-19'`).
   - Questa data è il fulcro per il calcolo dei periodi "umido" (post-evento) e "secco" (pre-evento).

### 3. `threshold` (numero, opzionale, default: `3`)
   - La soglia di differenza (in dB) tra i valori di riflettività VV del periodo secco e del periodo umido per identificare l'acqua. Valori più alti indicano inondazioni più drastiche.

### 4. `wet_offset_days` (numero intero, opzionale, default: `4`)
   - Numero di giorni prima e dopo `event_date` per definire l'estensione del periodo umido. Un valore di `0` (zero) farà iniziare il periodo umido dalla data dell'evento.
   - Il periodo umido sarà da `event_date - wet_offset_days` a `event_date + wet_offset_days`.

### 5. `dry_pre_event_days` (numero intero, opzionale, default: `15`)
   - Numero di giorni prima di `event_date` per definire l'inizio del periodo secco.
   - Il periodo secco sarà da `event_date - dry_pre_event_days` a `event_date - dry_post_event_days`.

### 6. `dry_post_event_days` (numero intero, opzionale, default: `5`)
   - Numero di giorni prima di `event_date` per definire la fine del periodo secco.
   - Il periodo secco sarà da `event_date - dry_pre_event_days` a `event_date - dry_post_event_days`.

## Workflow della Skill:

1.  **Validazione Input**: Controlla la validità dei parametri forniti (data, GeoJSON, etc.).
2.  **Calcolo Date**: Utilizza `event_date` e gli offset per determinare i `wet_start_date`, `wet_end_date`, `dry_start_date` e `dry_end_date` in formato `YYYY-MM-DD`.
3.  **Generazione Script GEE**: Costruisce uno script JavaScript per Google Earth Engine, inserendo i valori dei parametri calcolati e la stringa GeoJSON (convertita in oggetto JavaScript).
4.  **Presentazione Script**: Restituisce all'utente lo script GEE generato in un blocco di codice per facilitarne la copia.

## Consegna Script

**Regola: se l'utente è su un PC diverso (es. Tonfang vs ProBook), usa SEMPRE HTTP server, mai Telegram MEDIA.**

Vedi `../sentinel-2-water/references/delivery-cross-pc.md` per il workflow completo (salva file → avvia HTTP server → comunica URL).

In alternativa, incolla tutto lo script come blocco di codice Telegram.

## Export su Hard Disk (da GEE → QGIS)

Dopo validazione visiva:

1. **Togli i `//`** dall'export a fondo script che vuoi attivare (UNO alla volta)
2. **Run** → tab **Tasks** → Run → Google Drive
3. Scarica da Drive e carica in QGIS (Layer → Add Layer → Add Raster Layer)

## Note Importanti

- **AOI grande (>80 km)**: dividi in MultiPolygon (le tile S1 sono ~250×250 km)
- **Valori VV negativi**: dB normali, non preoccuparti se vedi numeri negativi
- **Soglia di default 3 dB**: buona per inondazioni fluviali; alza a 4-5 per acque più sottili
- **Fallback automatico**: se non trova immagini IW+VV, prova strumento diverso
- **Sar Flood**: lo script prodotto ha un problema con il clip dell'area allagata. Se subentra un problema, provare a usare la funzione `clipped = flood.clip(aoi).selfMask()`.

## Output della Skill:

-   Un messaggio che include:
    -   Lo script JavaScript completo e pronto per essere copiato e incollato nella Code Editor di Google Earth Engine.
    -   Un riepilogo dei principali parametri utilizzati (AOI, date calcolate, soglia).

## Script GEE Template (finale):
```javascript
// 🛰️ Flood Mapping — Sentinel-1 SAR
// Parameters:
//   AOI (GeoJSON): {AOI_GEOJSON_STRING_SUMMARY_PLACEHOLDER}
//   Event Date: {EVENT_DATE_PLACEHOLDER}
//   Wet Period: {WET_START_DATE_PLACEHOLDER} to {WET_END_DATE_PLACEHOLDER}
//   Dry Period: {DRY_START_DATE_PLACEHOLDER} to {DRY_END_DATE_PLACEHOLDER}
//   Threshold: {THRESHOLD_PLACEHOLDER}

// Per AOI grandi (>80 km), usa MultiPolygon
var aoi = ee.Geometry({AOI_GEOJSON_OBJECT_PLACEHOLDER});
Map.centerObject(aoi, 11);
Map.addLayer(aoi, {color: 'yellow'}, 'AOI');

var s1 = ee.ImageCollection('COPERNICUS/S1_GRD')
 .filterBounds(aoi)
 .filter(ee.Filter.eq('instrumentMode','IW'))
 .filter(ee.Filter.listContains('transmitterReceiverPolarisation','VV'))
 .select('VV');

var WET_START_DATE = '{WET_START_DATE_PLACEHOLDER}';
var WET_END_DATE = '{WET_END_DATE_PLACEHOLDER}';
var DRY_START_DATE = '{DRY_START_DATE_PLACEHOLDER}';
var DRY_END_DATE = '{DRY_END_DATE_PLACEHOLDER}';
var THRESHOLD = {THRESHOLD_PLACEHOLDER};

var dry = s1.filterDate(DRY_START_DATE, DRY_END_DATE).median().clip(aoi);
var wet = s1.filterDate(WET_START_DATE, WET_END_DATE).median().clip(aoi);
var diff = dry.subtract(wet).rename('diff');
var flood = diff.gt(THRESHOLD).rename('flood').focalMin(1).focalMax(1);

Map.addLayer(dry, {min:-25, max:0, palette:['black','white']}, '1. Secca (pre-evento)');
Map.addLayer(wet, {min:-25, max:0, palette:['black','white']}, '2. Alluvione (post-evento)');
Map.addLayer(diff, {min:-5, max:5, palette:['red','white','blue']}, '3. Differenza dB');
Map.addLayer(flood.updateMask(flood), {palette:['blue']}, '4. Flood Mask');

var area = ee.Image.pixelArea().updateMask(flood).reduceRegion({
 reducer: ee.Reducer.sum(), geometry: aoi, scale: 10, maxPixels: 1e9});
print('Area allagata (ha):', ee.Number(area.get('flood')).divide(10000));

// ─── EXPORT ─── (togli // per attivare)
// Export.image.toDrive({
//  image: flood, description: 'FloodMap_' + WET_START_DATE.replace(/-/g,''),
//  folder: 'GEE_Exports', region: aoi, scale: 10, crs: 'EPSG:4326', maxPixels: 1e9
// });
```
