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.
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 (Float32is 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;GEOuses the CRS units (metres in a metric projection)-maxdist <d>— stop counting past this distance (output is-nodatabeyond)-nodata <value>— value for pixels beyond-maxdistor 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.