Short answer

Contours are iso-elevation lines interpolated through a DEM, and the quality of the result is decided almost entirely by two choices made before you run the tool: the contour interval (driven by map scale and relief) and how much smoothing you allow without implying precision the DEM does not have. The mechanics are one command — gdal_contour or QGIS Contour — but contours are derived geometry that inherit every flaw of the source raster: voids, striping, quantization, and vertical error.

Below: the interpolation that produces a contour, how to choose an interval, smoothing that is honest, a worked GDAL/QGIS example, and the artifacts that make contours look wrong.

How a contour is computed

A DEM is a grid of elevation samples. A contour for value z is the set of locations where elevation equals z. The tool walks the grid, and for every cell edge where one endpoint is below z and the other above, it linearly interpolates the crossing point along that edge, then connects crossings into polylines (a marching-squares style algorithm). Two consequences follow directly:

  • Contours can only be as detailed as the cell size. A 30 m DEM cannot resolve a 5 m-wide gully; the contour will cut straight across it.
  • Contours are sensitive to the values, not just the surface shape. If the DEM is stored as integer meters, every cell snaps to a whole-meter elevation, and contours at sub-meter or whole-meter intervals will hug those steps and look blocky.

This is why "contours look jagged" is usually a DEM property, not a tool setting.

Choosing the contour interval

The interval is the vertical spacing between lines. Pick it from three constraints:

  • Map scale / legibility. Lines that fall closer than roughly 0.2-0.5 mm apart at print scale merge into a solid band. In steep terrain a fine interval becomes unreadable; in flat terrain a coarse interval shows nothing.
  • Relief. Total relief divided by interval gives the line count; aim for a count that reads as structure, not noise.
  • DEM vertical accuracy. Do not set an interval finer than the DEM's vertical accuracy. A DEM with ~3-5 m vertical RMSE cannot honestly support a 1 m interval; the extra lines are interpolation artefacts dressed up as data.

Rough field-tested starting points:

Map scaleModerate relief interval
1:10,0002-5 m
1:25,0005-10 m
1:50,00010-20 m
1:100,00020-50 m

Use index contours (a bold, labeled line every 5th interval) to keep dense maps readable. In flat coastal or floodplain terrain, drop to 1-2 m only if the DEM (e.g., lidar at ~0.1-0.3 m vertical accuracy) genuinely supports it.

Worked example with GDAL

Generate 10 m contours with an elevation attribute and index flags:

gdal_contour -a elev -i 10.0 \
  -snodata -9999 \
  dem_utm.tif contours_10m.gpkg
  • -a elev writes each line's elevation into an elev field.
  • -i 10.0 sets a fixed 10 m interval. Use -fl 100 200 300 instead to extract specific levels (e.g., a flood elevation), or -e for an exponential base.
  • -snodata -9999 excludes NoData so contours do not wrap around voids and ocean.

If the DEM is in geographic degrees (EPSG:4326), reproject to a metric CRS first so the interval is in real meters and line geometry is undistorted:

gdalwarp -t_srs EPSG:32633 -r bilinear dem_4326.tif dem_utm.tif

bilinear resampling slightly smooths the surface and reduces stair-stepping from a quantized source — appropriate for contouring, though never use aggressive resampling that invents detail.

The same in QGIS

Use Raster > Extraction > Contour (the gdal:contour Processing algorithm). Set Interval between contour lines, the Attribute name for elevation, and tick Produce 3D vector only if you need Z. For index lines, add an Offset / index expression, or post-process by selecting elev % 50 = 0.

Smoothing honestly

Two smoothing choices, and they are not the same thing:

  1. Smooth the line geometry (cartographic). After generating contours, apply Smooth (QGIS native:smoothgeometry, Chaikin-style) or a spline. This rounds the polyline for a cleaner map without changing which elevation it represents. This is fine and standard.
  2. Smooth the DEM first (e.g., a 3x3 low-pass / Gaussian filter) before contouring. This reduces noise-driven wiggle and stair-steps. Reasonable for presentation DEMs, but it shifts line positions slightly, so do not use a smoothed DEM for measurement.

What is not honest: choosing an interval finer than the DEM accuracy and then smoothing to hide the resulting noise. That manufactures the appearance of precision. Keep the interval truthful and smooth only the line shape.

Common pitfalls and why they happen

  • Stair-stepped / blocky contours. The DEM is integer-meter quantized, or the interval is at/below the quantization step. Light DEM smoothing or a coarser interval fixes it; the geometry is honest, just ugly.
  • Contours wrapping around NoData holes. NoData was not declared, so the tool treats sentinel values (0 or -9999) as real elevations. Set -snodata / a proper NoData value.
  • Bullseye rings in flat areas. Tiny DEM noise around a near-flat surface crosses the contour level repeatedly, producing concentric blobs. Increase interval or smooth the DEM.
  • Interval in degrees. Contouring a 4326 DEM gives an interval interpreted against degree-based elevation only if the vertical unit is also wrong; more often the line geometry is just distorted. Reproject to a metric CRS first.
  • False precision. A 1 m interval on a 30 m SRTM-class DEM produces lines that move with noise, not terrain. Match interval to accuracy.

QA and validation

  • Check against spot heights. Where you have surveyed benchmarks or labeled summits, the surrounding contours should bracket the known elevation.
  • No crossing lines. Contours of different elevations must never cross; if they do, the input is corrupt or the tool ran on a non-elevation raster.
  • Closed vs open at extent. Contours should close on themselves or end cleanly at the DEM boundary, not at NoData.
  • Density read at print scale. Zoom the layout to final scale and confirm lines stay separable in the steepest area.
  • Legend honesty. State source DEM, resolution, vertical accuracy, interval, and any smoothing applied.

Bathyl perspective

Contours are a communication layer, not the measurement layer — the DEM remains the source of truth. Bathyl sets the interval from scale and the DEM's real vertical accuracy, smooths line geometry for legibility rather than to hide noise, and labels every contour product with its source resolution so a reader knows exactly how much precision to read into the lines.

Related reading

Sources