I am looking for a way in which to take an input DEM and create an output raster whose pixel's value is the count of pixels "visible" from that location.

I use ArcGIS with Spatial Analyst, but also Manifold, GlobalMapper or GDAL.

How would I go about this task?


In ArcGIS you can use the Viewshed tool (Spatial Analyst Tools > Surface). The Viewshed lets you calculate the surface locations visible to a set of points or lines (see the documentation).

  • The viewshed tool will either (a) produce a binary grid of points visible from a single location or (b) produce a count grid showing how many (of a limited number of observers) can view each location. This question, on the other hand, appears to ask for a grid whose value at any given cell are the number of pixels visible from that cell. Although the meaningfulness of such an operation is questionable, it is differs from what Viewshed can provide unless somehow it can be persuaded to work with a large set of point observers, one per cell: have you tried to do that? – whuber Mar 26 '14 at 17:18
  • 1
    The meaningfulness lies in calculating a "visibility index", with applications in tower placement, viewpoint analysis, etc. Whitebox GIS contains a function for returning pixel values representing the percentage of total surface visible from that location, but no such facilities exist in the packages listed in the original post. Indeed, I have tried generating a single point feature at the centre of each pixel and running viewshed analysis based thereupon, but after a week of processing time I decided to see if there was another option. Thanks! – Joebocop Mar 29 '14 at 14:50
  • Joebocop, Thank you for the explanation. There are several reasons why this calculation may be questionable. In practical problems not all pixels should have equal weight in decision making or visibility characterization. Moreover, obtaining an entire grid of such counts, weighted or not, appears to have no advantage over computing such counts only at carefully selected locations--and is the direct reason why you are having to perform so much (likely unnecessary) processing. – whuber Apr 2 '14 at 21:27
  • Thanks again, whuber. I agree that it is less than ideal to be calculating visibility of EVERY other pixel in the surface, and ideally would only be interested in the number of pixels "below" the source pixel which are visible from each location. This helps determine optimal "viewpoints" over a valley, along an adjacent ridge. Better yet, analysing only a valley bottom would likely highlight points within the valley bottom which provide a good look around the valley itself (think archaeological applications). I have submitted the feature request to the creator of Whitebox GIS. – Joebocop Apr 3 '14 at 15:35

I had to do something rather like this for my masters thesis, but with much fewer observer and target points. I'm not aware of a reasonable way to create a complete raster of "visible area," at least not one that wouldn't take a long time. Repeatedly running Viewshed, once for each centroid of the raster's cells, would certainly work... but as you've, noticed it's incredibly time-consuming. This is likely to be true regardless of what software package's implementation you're using.

To shortcut the process somewhat, consider setting elevation limits -- e.g., "no point below X meters elevation will be able to see enough area, so only analyze points with elevation > X" -- and thereby narrow down your candidate points. This would reduce the number of Viewshed iterations required.

The alternative would be creating a custom python (gdal for handling raster, numpy for handling math) algorithm which can analyze visibility. However, for very large spatial areas, it may end up taking nearly as long as Viewshed to execute, and/or it won't be a simple algorithm. It may also run into memory problems for a particularly large DEM/DSM.

  • Thank you very much for your comments. I discovered an open source offering, Whitebox GIS, which contains a pre-written algorithm (Java) to calculate a "visibility index", returning cell values as a "percentage of the total surface visible from that pixel". I have requested that the author consider allowing the calculation to take place on a "window" (returning percentage visible of a window around each pixel), or to allow calculation only on pixels that are "lower" than the source pixel, somewhat as you've suggested. – Joebocop Apr 3 '14 at 15:30
  • Interesting! I'll have to take a look :) – Erica Apr 3 '14 at 20:27

I am slowly working on a gdal app that calculates viewshed with an eye on performance. It is still in development, and no where near done, but it may be useful. It'd actually be nice to have some input, as I just did it for fun. You can find it on my github account(see below).

The nearest neighbor sampling is pretty much a joke, but it's fast. Linear is better (one mean cell size towards the pixel of interest) but takes longer. DEMs I work with are typically about 1000 x 1000 cells, but I've tested various sizes:

kyle@kyle-workstation:~/src/gdal/git/gdal$ time gdalviewshed -alg linear smaller.tif a.tif 500 250
Processing input file.
Size is: 3171, 1080
0...10...20...30...40...50...60...70...80...90...100 - done.

real    0m0.766s
user    0m0.708s
sys     0m0.056s

kyle@kyle-workstation:~/src/gdal/git/gdal$ time gdalviewshed -alg nearest smaller.tif a.tif 500 250
Processing input file.
Size is: 3171, 1080
0...10...20...30...40...50...60...70...80...90...100 - done.

real    0m0.338s
user    0m0.256s
sys     0m0.080s

a really big one (US at 270 m):

kyle@kyle-workstation:~/src/gdal/git/gdal$ time gdalviewshed elevation.tif a.tif 1500 2500 
Processing input file.
Size is: 31718, 10803
0...10...20...30...40...50...60...70...80...90...100 - done.

real    0m44.694s
user    0m39.536s
sys     0m1.492s

Next is inverse distance weighting of 3 points at one mean cell size towards the pixel of interest.

Default output is 'view height', or how high above the elevation point the viewer is seeing, masks can also be output. Any feedback is appreciated, if anyone actually uses it.

PS, I know my terminology for sampling is wacko, and it's subject to change. I don't spend a lot of time naming things.


  • Also it has a small(ish) memory footprint, on the order of three lines from the dem. – user10353 Apr 11 '14 at 22:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.