[GIS] How to extract elevation values at line start and end points from a DEM

demflowlineqgis

I am new to the whole gis-experience and need your help working with QGIS.

I have:

  • DEM raster with heights (3d)
  • line-shapefile which contains the rivers (2d)

I need:
heights for "start" and "end" in lines (to get them 3d) then compare that heights with "flow direction" of the lines

qgis-help doesn't really help me out. Tried searching google, nothing useful found. I am pretty sure that it may be a really simple "standard-tool" that can do what I want. However I haven't found it yet.

Edit:

well, i am looking for a solution, not important wich way. dont have any experience with python.

i was working on that problem and think i am almost ready, but there seems to be a problem:

i extracted the nodes of the lines, they got the heights from the dem-grid. i even managed to add the values of the points back to the lines, but when i check the values, the "minimal height" (or maximal) dont always have the suitable x- and y-coordinates of the point.

example:
there is a line (columns: name, id, start_x, start_y, end_x, end_y). i imported the point-values (x, y, z coordinates) into the line. got 6 new columns in the table: min_x, min_y, min_z, max_x, max_y, max_z

now the min and max coordinates are mixed up and dont compare to those from the points.

my thoughts now are:

  • i delete the min_x, min_y, max_x, max_y
  • rename "max_z" and "min_z" to "up" and "down"
  • somehow i need to get the up_x, up_y and down_x, down_y from the points. maybe there is a way to do that in the field calculator like: (for up_x in table "lines") value = "x" FROM "points" WHERE "up.lines" = "z.points"

dont know if that can work in qgis or how the code should look like. maybe there is a way to manage this in python, but as i said, i dont have a clue about python.

Best Answer

One of the easier ways to do this is with a spatial database such as PostGIS. Load your raster into the database using raster2pgsql (which is installed with PostGIS) and then load your rivers with shp2pgsql (also installed with PostGIS).

Then, you can run a simple query that samples the elevation model at the end points of all your lines:

select 
    st_value(r.rast, st_startpoint(geom)) as a, 
    st_value(s.rast, st_endpoint(geom)) as b 
from 
    rivers, dem r, dem s 
where 
    st_contains(st_convexhull(r.rast), st_startpoint(geom)) and      
    st_contains(st_convexhull(s.rast), st_endpoint(geom));

I've named the DEM twice in the from clause because the ends of the line may be contained by two different tiles in the raster, and each tile will have to be matched independently. That's why there are two st_contains calls.

The great thing about PostGIS is that you can automate this kind of processing over millions of records with a minimum of effort.

Note that this works if the line geometry is LineString. If they're MultiLineStrings, you'll have to refine the query, or use st_dump to turn them into LineStrings.

Related Question