-1

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

2
  • 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 at 8: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 3 at 9:45

1 Answer 1

3

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

7
  • Thank you very much! It worked! However, i have another problem now (see edited post).
    – IchmagNuss
    Feb 22 at 7: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 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 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 at 13:55
  • 2
    @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 at 6:40

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