I've been looking through all of the GRASS commands in the QGIS 2.10 processing toolbox and it seems like one of these must be able to do this but I haven't found one yet. There is 'v.sample' which can sample a DEM at a point location. Is there a way to do something similar to sample a DEM when calculating the length of a line segment?
You can also calculate the length of a line taking into account the topography the following way:
Use the "Profiles from line" (SAGA) tool, which adds points along the line, giving the length from the line start to each point ("DIST" as the length on a flat surface, "DIST_SURF" with heights included).
Select the point with the maximum length value with "extract by expression". If you have multiple lines, use this expression:
"DIST_SURF" = maximum("DIST_SURF","LINE_ID"), which will extract the max. point for each line.
Then join these values back to the original line layer, taking only "DIST_SURF" from the point layer.
Admittedly it's not in GRASS but it still works.
Yes and you can automate this process with python grass.script or bash script (bat script in Windows). I test it in my system and the individual commands are (for my line vector named route and raster dem named utah_demUTM2):
v.to.rast input=route value=1 output=route_raster r.thin input=route_raster output=route_raster_thin r.mapcalc route_raster_dem="if(route_raster_thin, utah_demUTM2)" #in GRASS console
to produce route_raster_dem with the raster values (see next image where I used the plugin Value Tool).
Afterward, you can use the command r.to.vect.points to create points (distance between points equal to raster resolution) along input line route_raster_dem for calculating the 3D length of the line segment by using the adequate algorithm (with code or in a spreadsheet).
At the next image you can see some selected features at the start of route_vector_dem (obtained by using r.to.vect.points) and its attributes table.
3D distance is the sum of the length of the hypotenuse given by the difference in height between two adjacent segments along the line (the individual steps are the same as the raster resolution).
Using QGIS3, it's possible to use v.drape in the processing toolbox to attach z-values from a DEM to a vector layer of linestrings. The output layer will be MultiLinestringZ.
As far as I know there is still no way in QGIS to then calculate the 3d length of those features and add them as an attribute because the $length function only calculates 2d length.
If you output this MultilinestringZ file to .gpx, however, you can see that the z-values attached from the DEM during the v.drape are correct and attached to each track point.