Map Flood Extents and Water Levels from a Drone DTM in QGIS

QGIStutorialhydrologyflood mappingdrone mappingaerial surveypond surveyreservoirPython
Map Flood Extents and Water Levels from a Drone DTM in QGIS

After surveying a valley or reservoir with a drone, you often need to answer: “if the water level rises to 850 m, how far does it extend?” This script answers that directly from your DTM, without needing to manually trace contours.

Here’s the result on a real farm pond survey — every pixel at or below 827.5 m turned into a filled polygon, overlaid on the orthomosaic. Notice the second, smaller polygon on the left: a separate low-lying puddle along the access road, picked up automatically as its own feature:

A filled polygon showing every area at or below a target elevation, overlaid in blue on a drone orthomosaic of a farm pond, with a smaller separate polygon marking a low puddle nearby

What it does

The generate_contour_level_polygon.py script finds every pixel in the DTM at or below a target elevation and converts those pixels into filled GeoJSON polygons. Multiple disconnected low-lying areas become separate polygon features, sorted largest-first by area.

The geometry is automatically simplified to reduce vertex count and file size. Each polygon gets three attributes: elevation (the target water level), area_m2, and polygon_id.

What you need

  • QGIS 3.28 or newer
  • numpy, rasterio, shapely, pyproj (rasterio and numpy bundled with QGIS; shapely and pyproj may need install via OSGeo4W Shell)
  • A DTM raster with “dtm” in the layer name, checked in the Layers panel
  • The generate_contour_level_polygon.py script from the Terrain Analysis Pack

The DTM this script reads, as coloured hillshade — the excavated pond basin clearly visible as the lower (purple) area, matching the polygon shape above:

DTM hillshade of a pond site, coloured by elevation, showing the excavated basin as a darker depression against the surrounding ground

Steps

  1. Load your DTM raster into QGIS. Make sure the layer name contains “dtm”.
  2. Check (tick) the DTM in the Layers panel.
  3. Open Plugins → Python Console → Show Editor.
  4. Paste the script. At the bottom, set the elevation parameter to your target water level in metres (e.g., elevation=847.5). Optionally adjust simplify_tolerance (default: 0.5 m).
  5. Click Run.

The output GeoJSON is saved to 2.Session/Geojsons/ in the project directory structure (inferred from the DTM file path) and loaded into your QGIS project.

Configurable parameters

ParameterWhat it controls
elevationTarget water level in metres (pixels ≤ this elevation are included)
simplify_tolerancePolygon simplification in metres — higher = fewer vertices, smoother shape (0 = no simplification)
min_areaMinimum polygon area in m² to keep — filters out tiny noise polygons. None (default) keeps all, including small ones like the puddle in the example above

Installing shapely and pyproj

If QGIS reports an import error for shapely or pyproj, install them via the OSGeo4W Shell (Windows) or the QGIS Python environment:

pip install shapely pyproj

Or use the OSGeo4W package manager for a more stable install on Windows.

Get the script

generate_contour_level_polygon.py is part of the Terrain Analysis Pack — five terrain analysis scripts for QGIS at $35 USD.