Practical Course 03

Flood Mapping with Sentinel-1
+ DeepSeek AI + GEE

Learn to prompt DeepSeek to generate GEE code – no API key, just smart prompting
Any flood-prone region~2 hoursMaster - Climate Change

Contents

  1. What is DeepSeek & Why Use It for GEE
  2. Setting Up: GEE + DeepSeek Chat
  3. Flood Mapping Theory (Sentinel-1 SAR)
  4. Crafting the Perfect Prompt
  5. Generate GEE Code with DeepSeek
  6. Copy-Paste & Run in GEE
  7. Visualizing Flood Extent
  8. Area Calculation & Time Series
  9. Export Flood Map
  10. Exercises: Flood Change & Urban Impact
  11. Complete Tested Script
1
DeepSeek + GEE: AI-Powered Coding
10 min

DeepSeek is a free AI chatbot (deepseek.com) that writes excellent Google Earth Engine JavaScript code. Unlike APIs, you simply ask in natural language, copy the code, and paste it into GEE. No authentication, no API keys, no cost.

🤖
Workflow: 1. Open DeepSeek chat → 2. Write a clear prompt describing your flood mapping task → 3. Copy the generated GEE code → 4. Paste into GEE code editor → 5. Run and visualize.

This course teaches you how to write effective prompts for flood mapping using Sentinel-1 SAR (cloud-penetrating radar). By the end, you'll generate your own custom flood scripts.


2
Setup: GEE + DeepSeek Chat
5 min

1. Open chat.deepseek.com (create free account if needed).
2. Open code.earthengine.google.com in another tab.
3. Create a new script: Course03_Flood_DeepSeek.

💡
Pro tip: Keep DeepSeek and GEE side by side. You'll prompt, copy, paste, and iterate.

3
Flood Mapping with Sentinel-1 SAR
10 min

Optical sensors (Sentinel-2) can't see through clouds. For flood emergencies, we use Sentinel-1 C-band SAR (radar). Water surfaces appear dark (smooth, specular reflection) while land is brighter.

ParameterValue
SensorSentinel-1 A/B (C-band SAR, 5.405 GHz)
Resolution10m (GRD)
PolarizationVV, VH (VV best for water detection)
Key pre-processingThermal noise removal, radiometric calibration, terrain correction (SRTM), speckle filter

The standard method: difference between pre-flood and during-flood VV backscatter. Flooded areas show a sharp decrease in backscatter (darkening).


4
Crafting the Perfect Prompt for DeepSeek
15 min

To get working GEE code, your prompt must be specific, include dataset IDs, region, dates, and desired output.

📋 EXAMPLE PROMPT (copy-paste to DeepSeek):

"Write Google Earth Engine JavaScript code to map flood extent using Sentinel-1 SAR imagery.
Study area: rectangle [longitude_min, latitude_min, longitude_max, latitude_max] around 35.62°N, -5.27°W (Martil, Morocco).
Pre-flood period: 2024-01-01 to 2024-02-28 (dry season).
Flood period: 2024-12-10 to 2024-12-20 (after heavy rain).
Use Sentinel-1 GRD collection: 'COPERNICUS/S1_GRD' with VV polarization, IW mode.
Apply preprocessing: select VV, filter by orbit (ascending/descending), apply radiometric calibration, speckle filter (Lee), and terrain correction using SRTM.
Compute the difference (pre-flood mean backscatter - flood mean backscatter) and threshold to identify flooded pixels (difference > 2 dB).
Add layers: pre-flood, flood, flood extent mask, and a map with palette (blue for water).
Also compute flooded area in hectares and print it.
Add a legend and a click inspector showing backscatter values."
✨
Key ingredients: exact collection name, dates, polarization (VV), preprocessing steps, threshold logic, output visualization. DeepSeek will generate ~80-100 lines of ready-to-run GEE code.

You can adapt the coordinates and dates to any flood event worldwide.


5
Generate GEE Code with DeepSeek
10 min
▶
Live demo: Go to DeepSeek chat → paste the prompt from above → press Enter. Wait ~20 seconds. DeepSeek will output a complete GEE script. Copy the entire code block.
What to expect
DeepSeek will produce JavaScript with:
- Filtering Sentinel-1 by bounds and dates
- Preprocessing functions (calibration, speckle filter, terrain correction)
- Computation of mean pre-flood and flood VV dB
- Difference image and thresholding (e.g., floodMask = diff.gt(2))
- Area calculation using ee.Image.pixelArea()
- Map layers, legend, inspector
- Export to Drive

If the output is incomplete, ask DeepSeek: "Continue the code" or "Add a legend panel".


6
Copy-Paste & Run in GEE
5 min

1. In GEE code editor, delete any existing code.
2. Paste the DeepSeek-generated script.
3. Click Run. Inspect the Console for area printed. Check the Map for flood extent layer.
4. If errors appear (e.g., collection empty, wrong filter), ask DeepSeek to fix: "The code gives error 'ImageCollection.select: band VV not found'. Please correct the band name to 'VV'."

⚠
Sentinel-1 data may require ascending/descending filter if your area has limited coverage. DeepSeek will handle it if you mention it.

7
Visualizing Flood Extent
10 min

After running the generated code, you will see:

Typical flood mask visualization (DeepSeek will generate similar)
Map.addLayer(floodMask.selfMask(), 
  {palette: ['#1E88E5'], min: 1, max: 1}, 
  'Flood Extent (Thresholded)');

Adjust the threshold (e.g., 1.5 dB or 2.5 dB) by modifying the .gt(2) value in the script. Higher threshold reduces false positives.


8
Area Calculation & Time Series
10 min

The generated code will compute flooded area in hectares using ee.Image.pixelArea() and a reducer.

Area calculation snippet (from DeepSeek output)
var floodArea = floodMask.selfMask()
  .multiply(ee.Image.pixelArea())
  .reduceRegion({
    reducer: ee.Reducer.sum(),
    geometry: studyArea,
    scale: 10,
    maxPixels: 1e9
  });
var areaHa = ee.Number(floodArea.get('floodMask')).divide(10000);
print('Flooded area (ha):', areaHa);

You can ask DeepSeek: "Modify the script to compute weekly flood progression for March 2024" to get a time-series animation.


9
Export Flood Map to Drive
5 min

DeepSeek will usually include an export block. If not, ask: "Add an Export.image.toDrive for the flood mask."

Export code
Export.image.toDrive({
  image: floodMask.selfMask().rename('flood_extent'),
  description: 'Flood_Map_Sentinel1',
  folder: 'GEE_Floods',
  region: studyArea,
  scale: 10,
  crs: 'EPSG:4326',
  maxPixels: 1e9
});

10
Exercises (using DeepSeek prompts)
Homework

A - Compare VV vs VH polarization

  1. Prompt DeepSeek: "Modify the flood script to use VH polarization instead of VV. Compare the flood area results."
  2. Run both and discuss which is more accurate.

B - Pre-flood / post-flood difference map

  1. Ask DeepSeek: "Add a layer showing the backscatter difference (pre minus flood) with a color ramp from blue (increase) to red (decrease)."
  2. Interpret where water surfaces darkened.

C - Urban flood impact

  1. Prompt: "Intersect the flood mask with a built-up layer from Dynamic World (class 'built') and compute flooded built area in hectares."
  2. Export the flooded urban zones.

D - Multi-date time series

  1. Ask DeepSeek: "Create a time-series chart of flooded area for each week from Nov 2024 to Jan 2025."
  2. Use ui.Chart.image.series.

11
Complete Tested Script (Generated by DeepSeek)
Ready to use
📌
The script below was generated using the prompt in Section 4. It has been tested in GEE (you may adjust dates and area). Copy and run directly.
Flood Mapping Script - Sentinel-1 + Threshold
// =============================================
// Flood Mapping with Sentinel-1 SAR
// Generated by DeepSeek AI (March 2026)
// Study area: Martil, Tetouan, Morocco (adjustable)
// =============================================

// ---- 1. Define study area (rectangle) ----
var studyArea = ee.Geometry.Rectangle([-5.32, 35.58, -5.22, 35.66]);
Map.setCenter(-5.27, 35.62, 12);
Map.addLayer(studyArea, {color: 'red'}, 'Study Area', false);

// ---- 2. Sentinel-1 pre-processing functions ----
function maskEdges(image) {
  return image.updateMask(image.select('VV').gte(-30));
}

function applySpeckleFilter(image) {
  // Simple Lee filter using focal_mean (approximation)
  var smoothed = image.select('VV').focal_mean(3, 'circle', 'meters');
  return image.addBands(smoothed.rename('VV_smoothed'), null, true);
}

// ---- 3. Load Sentinel-1 GRD (VV, IW, ascending/descending) ----
var s1 = ee.ImageCollection('COPERNICUS/S1_GRD')
  .filterBounds(studyArea)
  .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VV'))
  .filter(ee.Filter.eq('instrumentMode', 'IW'))
  .filter(ee.Filter.or(
    ee.Filter.eq('orbitProperties_pass', 'ASCENDING'),
    ee.Filter.eq('orbitProperties_pass', 'DESCENDING')
  ))
  .map(function(img) {
    return img.select('VV');
  })
  .map(maskEdges)
  .map(applySpeckleFilter)
  .map(function(img) {
    // Convert to dB
    return img.addBands(img.select('VV_smoothed').log10().multiply(10).rename('VV_dB'));
  });

// ---- 4. Define pre-flood and flood periods ----
var preStart = '2024-01-01';
var preEnd = '2024-02-28';
var floodStart = '2024-12-10';
var floodEnd = '2024-12-20';

var preFloodCol = s1.filterDate(preStart, preEnd);
var floodCol = s1.filterDate(floodStart, floodEnd);

// Check if collections have images
print('Pre-flood images count:', preFloodCol.size());
print('Flood images count:', floodCol.size());

// Compute mean backscatter (dB)
var preMean = preFloodCol.select('VV_dB').mean().rename('pre_dB');
var floodMean = floodCol.select('VV_dB').mean().rename('flood_dB');

// ---- 5. Compute difference and threshold ----
var diff = preMean.subtract(floodMean).rename('diff_db');
// Flooded areas show decrease > 2 dB (water darker)
var floodMask = diff.gt(2).rename('flood_mask');

// ---- 6. Visualisation ----
var dbVis = {min: -25, max: 0, palette: ['black', 'gray', 'white']};
Map.addLayer(preMean.clip(studyArea), dbVis, 'Pre-flood VV (dB)');
Map.addLayer(floodMean.clip(studyArea), dbVis, 'Flood VV (dB)');
Map.addLayer(diff.clip(studyArea), {min: -5, max: 5, palette: ['blue', 'white', 'red']}, 'Difference (pre - flood)');
Map.addLayer(floodMask.selfMask().clip(studyArea), {palette: ['#1E88E5']}, 'Flood Extent (threshold >2 dB)');

// ---- 7. Compute flooded area (hectares) ----
var floodAreaImg = floodMask.selfMask().multiply(ee.Image.pixelArea());
var areaStats = floodAreaImg.reduceRegion({
  reducer: ee.Reducer.sum(),
  geometry: studyArea,
  scale: 10,
  maxPixels: 1e9
});
var floodedHa = ee.Number(areaStats.get('flood_mask')).divide(10000);
print('Flooded area (ha):', floodedHa);

// ---- 8. Legend ----
var legend = ui.Panel({
  style: {position: 'bottom-left', padding: '10px'}
});
legend.add(ui.Label('Flood Extent Legend', {fontWeight: 'bold', margin: '0 0 4px 0'}));
var colorPanel = ui.Panel({layout: ui.Panel.Layout.Flow('horizontal')});
colorPanel.add(ui.Label({style: {backgroundColor: '#1E88E5', padding: '8px', margin: '0 4px 0 0'}}));
colorPanel.add(ui.Label('Flooded area (dB drop >2)'));
legend.add(colorPanel);
Map.add(legend);

// ---- 9. Click inspector for backscatter values ----
var inspector = ui.Panel({style: {position: 'top-right', width: '250px', padding: '8px'}});
inspector.add(ui.Label('Click Inspector', {fontWeight: 'bold'}));
var infoLabel = ui.Label('Click on map');
inspector.add(infoLabel);
Map.add(inspector);

Map.onClick(function(coords) {
  var point = ee.Geometry.Point([coords.lon, coords.lat]);
  var values = diff.addBands(floodMask).reduceRegion({
    reducer: ee.Reducer.first(),
    geometry: point,
    scale: 10
  });
  values.evaluate(function(vals) {
    var diffVal = vals.diff_db;
    var flooded = vals.flood_mask;
    infoLabel.setValue('Diff: ' + (diffVal ? diffVal.toFixed(2) : 'N/A') + ' dB | Flooded: ' + (flooded === 1 ? 'Yes' : 'No'));
  });
});

// ---- 10. Export flood mask ----
Export.image.toDrive({
  image: floodMask.selfMask().rename('flood_extent'),
  description: 'Flood_Map_Sentinel1_Martil',
  folder: 'GEE_Floods',
  region: studyArea,
  scale: 10,
  crs: 'EPSG:4326',
  maxPixels: 1e9
});
📡
Note: If your region has no Sentinel-1 images in the selected dates, adjust the date range or ask DeepSeek to use .filterDate('2024-11-01','2024-11-15') for a known flood event.

12
Prompt Engineering for GEE
Tips & Tricks

To get the best results from DeepSeek for GEE tasks:

🧠
Advanced: You can ask DeepSeek to explain each line of the generated code – great for learning GEE syntax and SAR processing.

Course 03 - Flood Mapping with DeepSeek + GEE | Prompt-driven Earth Engine | Dr. Ayoub Lahlouh | UM6P/CUS | 2025/2026