2

I am using QGIS 3.24,

I have 2 polylines layers:

  • First one is composed of 2 rivers, crossing. The two of them are named 1 and 2
  • Second one is composed of parallel lines form this rivers. 5 and 6

enter image description here

Starting from my parallel layer (red), i would like to find the nearest entity in my layer river (blue), BUT with a filter. Indeed, i want to join parallel line with the same river they're from. So I DON'T want my parallel line 5 to be joined with my river 1, but i want it to be joined with my river 2.

I've tried this, with field_calculator, from my layer parallel:

array_to_string(overlay_nearest('river_layer',id,filter:=river_name='river_name',limit:=1))

id is id from river_layer

But nothing happens! If i write it like this:

array_to_string(overlay_nearest('river_layer',id,filter:=river_name='1',limit:=1))

It's working, but it's only pointing to entity from river 1, ofc.

I've read https://github.com/qgis/QGIS/issues/43146 but I don't get this formula: \'layer2\'? Why \? And this [0]? I don't get it neither.


I think I've misled the first answerer. My river is 'segmented', so it may cause some trouble with that answer, even if it could work:

enter image description here

On this picture, lines 31, 32, 33 and 34 are from the same river (It's already stored in my tables, river and parallel lines). I have 4 parallel lines, and they are segmented too (I marked them with point at the middle of them). We can imagine a part of the attribute table like this:

enter image description here

If I put a buffer on my river (I can even do it BEFORE river is segmented), I fear that some parallel segmented lines might be associated with the wrong river, like on my picture, which shows some errors:

enter image description here

Maybe I could create a virtual layer, with something like this, considering P_para_line as my point layer with points in the middle of parallel segmented lines:

SELECT
    ST_startpoint(ST_ShortestLine(p.geometry, r.geometry)),
    r.id AS id_of_the_segmented_portion_of_river,
    ROUND(ST_Length(ST_ShortestLine(r.geometry, p.geometry)), 6) AS distance
FROM
    P_para_line AS p, river_layer AS r
WHERE
    p.river_name = r.river_name

After this, I get way too many points on the same coordinate! I wish I could keep only the point with the shortest distance. I can suppress other points manually, but I think i can change my virtual layer query.

3
  • 2
    Backslashes are used to escape characters, e.g. single quotes. For your expression you dont need it. [0] is called an index bracket. You can use it to return the nth element of an array. About your actual question: what does the field "river_name" contain? A string or an integer?
    – MrXsquared
    Mar 22, 2022 at 16:07
  • In the solution of @Babel, the target parallel line must be completely within the buffer, so I don't think you would get the wrong associations you are concerned about. Or perhaps I misunderstand the problem. I am not entirely clear on what the red arrows signify in your latest diagram.
    – Matt
    Mar 23, 2022 at 20:43
  • The red arrow signify a red point (or a segmented parallel line) SHOULD be associated with this river. For instance the red point with 8 SHOULD be associated with the segmented river id 33, because this point come from the same river. With your solution, if i place a buffer on my segmented river lines, it MIGHT misslead some segmented parallel lines to be associated with the wrong segmented river (even if it will be globally good.).
    – Cromex
    Mar 24, 2022 at 9:04

1 Answer 1

2

Create a buffer around the river layer (containing 1 and 2) with a distance slightly larger then the distance to the second line layer (containing 5 and 6).

Then check within which of the buffers the second line is and get the value of an attribute (like id) by its field name, e.g. using FIeld calculator.

Use this expression:

array_max (
    array_foreach(
        overlay_nearest (
            'buffer',  -- change the layer name
            $id,
            limit:=2  -- change the number, depending how many rivers/parallel lines you have
        ),
        if (
            within (
                $geometry,
                geometry(
                    get_feature_by_id (
                        'buffer',  -- change the layer name
                        @element
                    )
                )
            ),
            attribute (
                get_feature_by_id (
                    'buffer',  -- change the layer name
                    @element
                ),
                'id'  -- change the name of attribute whose value you want to get
            ),''
        )
    )
)

Red line is labeled with the expression above, getting the value of the id of from the layer river (blue):

enter image description here

Your Answer

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

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