GDALRaster Processing

gdal_proximity

What is gdal_proximity?

gdal_proximity.py produces a raster where every pixel holds the distance to the nearest "target" pixel in a source raster. Targets are specified either as explicit pixel values (-values) or as any non-zero pixel. The result is the classic distance-to-features surface: distance to nearest road, distance to coast, distance to a fire point, distance to a building footprint.

Shell
gdal_proximity.py <srcfile> <dstfile> [options]

Commonly used options:

  • -srcband <n> / -dstband <n> — source and destination band
  • -of <format> — output driver
  • -ot <type> — output data type (Float32 is typical for Euclidean distances)
  • -values <v1,v2,...> — treat these source values as targets (else any non-zero is a target)
  • -distunits PIXEL|GEO — distance units; GEO uses the CRS units (metres in a metric projection)
  • -maxdist <d> — stop counting past this distance (output is -nodata beyond)
  • -nodata <value> — value for pixels beyond -maxdist or for no-target pixels
  • -fixed-buf-val <value> — burn a fixed value inside the buffer rather than distances
  • -co <NAME>=<VALUE> — creation options

When would you use gdal_proximity?

Use it whenever you need distance from each pixel to the nearest feature in a source raster. Typical jobs: rasterise roads with gdal_rasterize, then run gdal_proximity.py roads.tif distance_to_roads.tif -distunits GEO to get a distance-to-road surface for accessibility modelling; compute distance from every cell to the nearest urban pixel in a land-cover raster using -values 1 to target only class 1; or build a buffer-distance raster for wildfire risk modelling.

For vector inputs, first rasterise the geometry with gdal_rasterize -at at your target resolution, then feed the binary raster into gdal_proximity.py. The -at flag matters — without all-touched rasterisation, thin features under-represent and the proximity surface gets biased. Setting -maxdist dramatically speeds up large rasters when you only care about nearby cells.

FAQs

How do I get distances in metres rather than pixels?

Pass -distunits GEO. The tool multiplies pixel distance by the geotransform resolution, so the output is in the horizontal units of the raster CRS — metres if the source is in a metric projection, degrees if it is in WGS84 (which is usually wrong). Reproject to a metric CRS before running gdal_proximity.py for meaningful distances.

What output data type should I pick?

Float32 is the common choice for Euclidean distances expressed in geographic units. If distances are large, Float64 avoids precision loss. For integer pixel distance outputs (-distunits PIXEL), UInt16 or UInt32 suffice. Always pair with an appropriate NoData.

Why is my output all maximum values?

Usually the target pixels were not detected. gdal_proximity.py defaults to "any non-zero pixel is a target" — if your source raster is Float32 with values close to but not equal to zero, everything looks like a target. Either reclassify explicitly to integer 0/1 before running, or pass -values with the specific target value(s).

How does gdal_proximity differ from a cost-distance surface?

gdal_proximity.py computes straight-line Euclidean distance and ignores the intervening pixels. Cost-distance (cumulative friction) tools like QGIS's r.cost or WhiteboxTools' CostDistance account for traversal cost through each cell. If slope, barriers, or land cover matter for your distance model, pick a cost-distance tool; gdal_proximity.py is purely geometric.