gdal_viewshed
What is gdal_viewshed?
gdal_viewshed computes a viewshed from a digital elevation model: given an observer coordinate and observer height, it produces a raster indicating which cells are line-of-sight visible from that point. It supports curvature-of-earth and atmospheric refraction corrections, observer and target heights, and a configurable maximum distance. The output is either a binary visible/invisible raster or a gradient "height above terrain required to see this cell" raster.
gdal_viewshed [options] -ox <x> -oy <y> <src_dem> <dst_raster>Commonly used options:
-ox <x>/-oy <y>— observer coordinates in the DEM's CRS-oz <z>— observer height above terrain (default 2 m)-tz <z>— target height above terrain (default 0 m)-md <max_distance>— maximum analysis distance (CRS units)-cc <coef>— atmospheric refraction coefficient (default 0.85714; use 1.0 to ignore)-f <format>— output driver-om <NORMAL|DEM|GROUND|ACCUM>— output mode;NORMALis binary visibility,DEMreturns minimum target height required to be visible,GROUNDreturns the terrain elevation where visible,ACCUMaccumulates visibility over multiple calls-vv <value>/-iv <value>/-ov <value>/-ndv <value>— visible, invisible, out-of-range, and NoData values-b <band>— source band
When would you use gdal_viewshed?
Use gdal_viewshed for any single-observer visibility analysis. Typical jobs: determining what terrain is visible from a proposed observation tower (gdal_viewshed -ox 412000 -oy 6100000 -oz 30 -md 10000 dem.tif viewshed.tif), evaluating wind-turbine visual impact from a nearby village, or computing the visible footprint of a mobile-phone mast at 40 metres. Aggregate several runs (or use -om ACCUM) to produce a cumulative visibility surface across many observers.
For meaningful long-range analysis, pass -oz for eye height (1.7 m pedestrian, 30 m tower) and optionally -tz for the height of the thing you are trying to see (0 for ground features, 20 for forest canopy, 50 for a turbine hub). -cc 0.85714 uses GDAL's default refraction model; set to 1.0 to disable refraction if your reference methodology demands geometric LOS only.
FAQs
Why does my viewshed have a jagged edge?
Viewsheds on pixel grids are inherently stair-stepped because each cell is tested as a discrete line-of-sight. The jagged edge is an artefact of DEM resolution and the LOS sampling density. Higher-resolution input DEM or a post-hoc vector smoothing cleans the appearance; do not simplify if the downstream analysis depends on exact cell-accurate visibility.
How do I compute a cumulative viewshed from many observers?
Use -om ACCUM repeatedly: gdal_viewshed -om ACCUM -ox ... -oy ... dem.tif accum.tif accumulates into accum.tif. Or run many single-observer viewsheds and sum them with gdal_calc.py --calc="A+B". The ACCUM mode is generally faster because it updates in place.
What refraction coefficient should I use?
-cc 0.85714 is GDAL's default, matching the commonly cited value of 1/7 for atmospheric refraction. For comparison against methodologies that use other refraction coefficients (e.g. 0.13 in some civil engineering guidelines), set -cc to match. Setting -cc 1.0 disables the curvature-adjusted refraction calculation altogether.
Can I compute a viewshed from a vector of observers?
Not directly — gdal_viewshed takes a single observer per call. Script a loop over your vector points and either ACCUM into one raster or produce per-observer viewsheds for individual analysis. WhiteboxTools and SAGA GIS offer multi-observer viewshed tools natively if you need a single invocation.