4

In QGIS I have a map of source [square] and receptor points [circles], see map. I also have a layer with ground-type data (Corine Land Type 2018). I want to know how the ground type changes along straight-line paths from the source point to each receptor point. I can't find any solutions for obtaining layer attributes along paths between two points.

The application is for a sound propagation prediction program which needs information on the ground type along the source-receptor paths. It would be then helpful to have some array with land type vs distance between the two points. How can I do this? Also if there's a way to batch-perform this operation in Python that would be useful.

See map

1
  • You need to limit your question to either QGIS tool or python.
    – Padmanabha
    Commented Jun 13, 2023 at 13:48

3 Answers 3

4

One solution that doesnt require your raster to be converted to polygons:

  1. Densify by interval with your line layer as input. Set the interval to whatever distance you want to sample raster values as.
  2. Extract vertices to create points along the lines.
  3. Field Calculate a new column in the output with the formula below. Each point will get the value of the pixel beneath it.

raster_value(layer:='landuse', band:=1, point:=$geometry)

(I dont know what you want to do next.)

enter image description here

2

If you create actual line features you can use the intersect tool to split those lines using the polygons.

Once the lines are split you can populate the lines with the polygon attributes using a spatial join. Here is a tutorial on a spatial join.

The attribute table of the resulting spatial join would have a row for each line segment and a column for each data value - thus the array you desire.

Populating that table with distances or lengths should get posted to another question. So should question about automating these steps with Python.

2
  1. Create the paths. Run the Geometry by expression tool, set as Input layer the source layer, set the Output geometry type as lines and set the Geometry expression to the following expression.
    aggregate(
        'source layer name/id', --replace here with your layer name/id
        'collect',
        make_line($geometry, geometry(@parent))
    )
    
  2. now you'll have a MultiLine geometry layer connecting each source with each receptor. Convert this result to LineString geometry type, use the Multipart to singleparts algorithm.
  3. Polygonize the raster running the Polygonize tool. The pixel values will be stored by default in a field called DN, this field name will be required in the last step.
  4. Use the following expression to calculate a new text field in the resulting layer of step 2, this text will store the array with the information of what landcover thus a line crosses and the distance. It could be a long text so set the length to a considerable length (512).
    array_to_string(aggregate(
        layer:='Polygonized layer name/id', -- set here the poligonized layer name/id
        aggregate:='array_agg',
        expression:="Landcover category field name" || ': ' || length(intersection( -- set inside double quotes the field name where you stored the landcover info in the step 3.
            $geometry,
            geometry(@parent)
        )),
        filter:=intersects(
            $geometry,
            geometry(@parent)
        )
    ))
    

Notes:
All the layers must be in the same CRS
The array will be a key value pair where keys are the land cover codes and the values will be the lengths (cat1: length1, cat2: length2, catn: lengthn)
Length will be returned in the project CRS units

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.