0

I would like to split a linelayer with points in QGIS. For that, i found this answer: Splitting line with point layer in QGIS

I have one point layer: QBW_Strukturgütekartierung and one line layer: FWK_GESAMT

I used the following code in 'Geometry by expression'. Hereby my input layer is my line layer. And the 'point' expression in the code line 4 is my point layer.

collect_geometries (
    array_foreach (
        aggregate( 
            'point', 
            'array_agg', 
            $geometry),
        extend (
            make_line(
                line_interpolate_point( 
                    $geometry,
                    line_locate_point($geometry,@element)
                ),
            project (
                 line_interpolate_point( 
                    $geometry,
                    line_locate_point($geometry,@element)
                ),
                10,
                radians(
                    90+line_interpolate_angle( 
                        $geometry,
                        line_locate_point($geometry,@element)
            )))),
            10,
            0
)))

The problem is that i had a multipoint layer but did not refer to it in the expression. The problem was solved by using the following expression in the sixth line of the code: geometry_n($geometry,1)

My data structure looks like the following:

  1. The point layer has 10,857 entries with multiple features.
  2. The line layer has 558 entries with multiple features.
  3. Both the line and point layer share one attribute thats the same. The name of the river.

Is this enough insight into the data or is more needed?

I am not allowed to share the data. I am rather new to QGIS.


@she_weeds answered that I could generate an auxiliary line at every point on the line with the following code in 'geometry by expression'. I substituted point_layer_name with my point layer and attribute_name with the attribute the point and line layer share:

collect_geometries (
    array_foreach (
        aggregate(
            'point_layer_name',
            'array_agg', 
            geometry_n($geometry,1),
            filter:="attribute_name"=attribute(@parent,'attribute_name')
        ),
        extend (
            make_line(
                line_interpolate_point( 
                    $geometry,
                    line_locate_point($geometry,@element)
                ),
            project (
                 line_interpolate_point( 
                    $geometry,
                    line_locate_point($geometry,@element)
                ),
                10,
                radians(
                    90+line_interpolate_angle( 
                        $geometry,
                        line_locate_point($geometry,@element)
            )))),
            10,
            0
)))

However, there are still more lines created than i actually wanted. I also tried the other suggestions but the solutions were not as sufficient.

Any more suggestions?

enter image description here

PolyGeo
  • 65,136
  • 29
  • 109
  • 338
  • 2
    This is unclear. What data do you have? What have you tried (incl. tool names and settings, or expressions)? Where does your workflow not meet your expectations? – Erik Feb 12 '24 at 08:51
  • Your question grew and got a bit confusing with the differents versions and edits. It is also not clear what exactly your workflow is and why the problem appears. Maybe would be helpful sharing your project + data as we don't know many things. Maybe a CRS issue? Why do you apply a buffer to the line (step 2) when you want to split the line? – Babel Mar 03 '24 at 09:45

1 Answers1

2

Using multipart points for line interpolate functions

The issue is that after you ran the intersection tool, the layer geometry type was changed from Point to MultiPoint (even if each feature still only has one part), but in the expression you used, line_interpolate_point() requires a single point geometry input, and not a MultiPoint geometry.

To get the correct geometry from a MultiPoint layer you need to aggregate geometry_n($geometry,1) instead of $geometry like so, which will return a single point per feature to be used in the rest of the expression:

        aggregate( 
            'point', 
            'array_agg', 
            geometry_n($geometry,1)
        )

Matching only the appropriate points

Secondly, if you have multiple features in your line layer, you need to further filter the aggregated point layer to only points that are appropriate to each line. If they share the same attribute, then you can just use a filter in the aggregate() expression:

        aggregate(
            'Intersection',
            'array_agg', 
            geometry_n($geometry,1),
            filter:="name"=attribute(@parent,'name')
        )

Alternatively, if you want to filter the points based on whether they actually intersect or are within x metres of each line, rather than aggregate() it is more efficient to use overlay functions.

  • If the points and lines just intersect:
    overlay_intersects('point',
                       geometry_n($geometry,1))
    
  • If the points are within 5 metres from your line:
    overlay_nearest('point',
                    geometry_n($geometry,1),
                    limit:=1,
                    max_distance:=5) --change as appropriate
    

Example expression:

I'll asssume your points intersect the line after having used snap to layer, etc.

Use something like the following expression in the Geometry by Expression Processing Tool, to create a new layer with the generated line geometries (don't forget to set Output geometry type to Line).

collect_geometries (
    array_foreach (
        overlay_intersects(           --if points aren't snapped to line use overlay_nearest() with limit:=1 and appropriate max_distance parameter
            'points',                 --name of point layer
            geometry_n($geometry,1)), --use geometry_n(...) if point layer is multipart, otherwise $geometry
        extend (
            make_line(
                line_interpolate_point( 
                    $geometry,
                    line_locate_point($geometry,@element)
                ),
            project (
                 line_interpolate_point( 
                    $geometry,
                    line_locate_point($geometry,@element)
                ),
                10,
                radians(
                    90+line_interpolate_angle( 
                        $geometry,
                        line_locate_point($geometry,@element)
            )))),
            10,
            0
)))

Splitting lines

Finally, you can use the result of the above from Geometry by Expression to split the original lines, using the Split by Line processing tool.

In the example below, I had two line features; five points intersected each line, so now I have 12 features instead.

Result (click to enlarge):

enter image description here

she_weeds
  • 12,488
  • 1
  • 28
  • 58
  • Thank you very much! It worked! However, i have another problem now (see edited post). – IchmagNuss Feb 22 '24 at 07:19
  • @IchmagNuss are there multiple features in your line layer? If so may need to use overlay_nearest() instead of aggregate() , with limit:= -1 and an appropriate max_distance parameter – she_weeds Feb 22 '24 at 11:08
  • Yes i have a line layer with 557 features. I changed the row with the aggregate function as above. I attached another picture to the post. It does not work like that. What did i do wrong? – IchmagNuss Feb 26 '24 at 12:53
  • @IchmagNuss it's missing the key component, the field for overlay_nearest() to aggregate, I didn't think to make it explicit as I was in a rush. The expression needs to be something like overlay_nearest('layer', $geometry, limit:=-1, max_distance:= 25) – she_weeds Feb 27 '24 at 13:55
  • I have not found a solution yet. I have tried your initial suggestions with $geometry_n($geometry,1) on one single feature of the line layer and still the problem is the same. However when i use only the points associated with the line layer feature the newly created lines are on the right location. Is it possible to create the new lines by condition that the points are only used to split the line layer feature when there is the same feature in the point layer? For example: The points refer to a river in the line layer and both have the river name in their features. – IchmagNuss Feb 28 '24 at 12:05
  • The newly created auxiliary lines can be used to split the layer into segments. I dont know how to do that with the tool split with lines. Or is it possible to save the auxiliary lines as a seperate line layer? – IchmagNuss Feb 28 '24 at 12:36
  • 1
    @IchmagNuss I'm getting confused as to what the issue is. Weren't you using Geometry by Expression? That generates a line layer you can use with Split by Lines. Also I don't know why you suddenly need the points to join to the river line name. I thought it was based on intersection. I've updated the answer with the full expression you can just use in Geometry by Expression, try that out. – she_weeds Feb 29 '24 at 06:40