# Adding z-value attribute to lines

I have a shapefile of 200 lines (all connected) with the coordinates x and y and a DEM raster. I would like to give the z value to the lines by taking it from the raster.

I have read several discussion on how to do the same operation with a points shapefile but I was wondering if would be possible to have the same results with lines. Maybe applying the z-value to a line vertex, or calculating the average elevation of the line length?

• Have you tried `Drape (set z-value from raster)` tool? Commented Apr 13, 2020 at 10:41
• Yes, but he does not add the extra column. Commented Apr 13, 2020 at 11:45
• What kind of 'extra column' do you expect? Commented Apr 13, 2020 at 11:47
• I am expecting an extra column with the altitude value: e.g. [01] line, altitude 57meters. Commented Apr 13, 2020 at 12:02

You can use the Field Calculator to create a new elevation field, using a way similar to the point layer. The operation will give you a punctual information extract from the raster.

In the line layer's Attribute Table use the Field Calculator to create a new field (numeric, real) with this expression

``````raster_value('DEM_NAME', 1, start_point(\$geometry))
+
raster_value('DEM_NAME', 1, end_point(\$geometry))/2
``````

changing the value `DEM_NAME` with the name of your DEM.

This will create a new field with the average of the elevations calculated at the beginning and at the end of the line.

But if you want to calculate a more accurate average you can, still using the Field Calculator, use a more complex expression that calculates the elevation average recorded at n points along your line.

Considering that using the expression

``````collect_geometries(array_foreach(
generate_series(0, length(\$geometry)/10, 1),
line_interpolate_point(\$geometry,@element * 10)))
``````

you can create a sequence of points along your line (as observable in the image below) starting from 0 to the end of the line, with 1 meter of distance

you can extract from your raster the elevation of each of those points and calculate the average elevation of all them.

To do it, you can use the following expression:

``````array_sum(
array_to_string(
array_foreach(
array_foreach(
generate_series(0, length(\$geometry)//10, 1),
line_interpolate_point(\$geometry, @element * 10)),
expression:=raster_value('DEM_NAME', 1, collect_geometries(@element))
),
delimiter:=' ,'))
/
array_length(
array_foreach(
generate_series(0, length(\$geometry) // 10, 1),
line_interpolate_point(\$geometry, @element * 10)))
``````

The resultant data will be the sum of calculation of all the elevations in all of the points (calculated by `array_sum`) divided by the number of points (calculated by `array_length`).

This is the result:

ADDENDUM: If you want a rounded number for your elevation just add `round(` at the beginning of the expression and close all the adding a `)` at the end of all.

I had a similar issue some time ago. If you want to split your lines into segments of a given lenght and then calculate the slope of the segments:

Calculate slope of line segments with QGIS