Summary:
I would like to create a raster where each cell contains the vertical distance to the nearest water (a decent approximation would be acceptable). The problem is that I'm not sure how to go about it.
Current approach:
I've looked through the documentation for my GIS (I'm using Grass 6.4 if that matters). And I can't find any direct way to perform this calculation. I've also searched the web without luck.
So I dreamed up the following:
- convert my water vector to a water raster (1=water, null=everything else)
- replace the 1s in the water raster with the altitude above sea level
- perform "neighborhood" (moving window) analysis. Calculate the average altitude of water for a 100 meter radius for every cell in my region (ignoring nulls)
- repeat the above with 100m, 200m, 300m, ..., 2000m. One raster for each distance.
- using r.grow.distance calculate the distance between each cell and it's nearest water
- then, using map algebra, I look at the distance to nearest water for each cell and its own altitude and subtract the average altitude of water for the appropriately distanced raster.
The problems with my method:
It is very computationally demanding. I am working at a 10m resolution and I need to perform this modelling on around 60 million cells. I've been creating rasters on a fast desktop for days and days and I'm not even close to finished.
At small radii, the calculation seems reasonable. If the distance to nearest water is 75 meters and I use a 100 m average altitude to water, the approximation is pretty good. But if the distance to nearest water is 1875 meters and I use the 1900 meter raster I will be averaging in the altitude to water of many cells far removed from the nearest water to my cell. The results are dissatisfying. I considered using some kind of smoothing process for the final raster but I wonder if there is a completely different approach that I am not seeing.
I've been reading about predictive modeling projects where vertical distance to nearest water is a one of the inputs to the model so I know it can be done but I'm just not sure how.
I'd appreciate any help I can get with this problem. Thanks.
Answer
Perform a hydrologic analysis on your data. Taking your first step of water bodies as a raster, you can then use that as a sinks raster. I'll specify the rest of this analysis in terms of GRASS as you mentioned that's the GIS system you're using:
Set up r.watershed
(documentation) with the elevation data layer you'd like to analyze and the sinks raster you generated in the first step:
r.watershed elev=input_dem depression=input_sinks basin=output_basins \
stream=output_streams threshold=1000
Where threshold is something appropriate for the scale of your data-- this should give you a map of each watershed: if you subtract that elevation from all the cells in that basin, you should get the vertical distance to the nearest water. You may need to iterate over smaller regions than your full raster to get good performance. You might find these tutorials (1, 2) also helpful in understanding how to use the command.
Mike helpfully mentioned an addon called r.watershed.distance which can be used to calculate this all in one go:
r.stream.distance -o dir=dirs stream=streams dem=elev \
distance=distance_outlets elevation=elevation_outlets
Which will result in an output close to what you're interested in:
This example was taken from the R.stream.* page, you can download the extension itself from the addon page.
No comments:
Post a Comment