# How to measure distance between points based on elevation?

I need to be able to measure distances between points, however the distance need to be calculated in relations to elevation. The points are homes of storytellers from the 19th century and the places which are mentioned in their stories. The distance therefore has to be "walking distance". A path along a valley will likely be shorter than a path over a mountain even though the actual straight distance is shorter. Attached is a screenshot illustrating my thinking. In the image, paths A and C would therefore be calculated shorter than path B. The points are from a CSV file but I also have a raster layer with the elevation data.

• I think it would be better to calculate walking time. The velocity of walking is depending on the slope, and upwards takes more time than downwards. – AndreJ Oct 16 '14 at 8:36
• "3D" distance compared to flat-map distance? The difference is probably smaller than you might think. Peter Guth, the man behind MICRODEM said "The distance or area will be increased by the secant of the angle of slope, and until you get to very large slopes, the secant is essentially 1." – nhopton Oct 16 '14 at 9:55

Achieving this goal is somewhat a basic task in GIS, however the method in QGIS might not be trivial. Your best chance is to use GRASS's `r.walk` function, which creates an anisotropic cost surface (dem+slope+other factors).

First, you have to create a friction surface as an input to `r.walk`. In your case it can be a single-valued raster (1.0) matching the extent of your DEM. You can create it with `r.mapcalculator` with the formula: `A*0+1` where A is your DEM.

Next, you have to select a set of starting points from your CSV. These are the points, the accumulated cost surface will be calculated from. You have to create an individual cost surface from every starting point. It might be smart to define the ending points associated with every starting point in this step (in individual layers off course). After, you can run `r.walk` with the created inputs. The starting points can be in a single layer, you can iterate through them with the green arrow in the dialogue box.

Now in an ideal case, you have the cost surfaces and the ending points for every cost surface. In theory you could find the least cost paths with `r.drain`, but for me, it ended up in an error (python couldn't import the QgisRaster library). If you run in the same issue, you can go with SAGA's "Least cost paths" algorithm. It will create a point and a line layer for every ending point with the cost surface (use the iteration button again). After you have all the lines, you can merge them into a single shapefile with SAGA's "Merge shapes layers" tool.

This method can be very slow with the increment of points, so if you have a lot of them, you might try to automatize the method with python. It will be still a lot of time to calculate (especially the cost surfaces), but you don't have to create tons of ending point layers manually.

• Thanks for this, I'll probably have to start learning how to use GRASS. I also think that I might have problems, in the illustration I posted I would assume many of the mountains impassable, so I would have to add something like "if mountain is higher than x, go around it"... But thanks for the answer, this will probably help me get started. – traustid Oct 16 '14 at 12:17
• That's an easy condition in `r.walk`. You can use the friction map to set up the impassable cells. Reclass your DEM with `r.reclass` with rules such `1 thru 2000 = 1` `2000 thru * = 9999` in a rules file (if your threshold is 2000m). This way the algorithm won't pass cells with high friction values, it will be less cost to go around it. – Gabor Farkas Oct 16 '14 at 13:33
• Thanks so much for this! I really do not have much knowledge of GRASS but this is a really great starting point. – traustid Oct 17 '14 at 9:03
• You're welcome. To be honest, I'm still amazed at your task. This is one of the best examples, how GIS can be applied on the widest scale of disciplines. – Gabor Farkas Oct 17 '14 at 14:05