I want to select line features by their relationship to their neighbouring line features. To perform generalisation on the data set I need to select lines that:

  • Do not intersect with their end point with other features
  • OR
  • Do not intersect with their start point with other features
  • AND
  • are below a certain length (let's say 100)

I need to select dangles (line segments with one unconnected end (or start) point).

So far, I have tried (updated):

(intersects(start_point($geometry), difference(collect($geometry),$geometry)) AND  disjoint(end_point($geometry), difference(collect($geometry),$geometry))) OR (intersects( end_point( $geometry ), difference(collect($geometry),$geometry)) AND disjoint(start_point($geometry), difference(collect($geometry),$geometry)))

The output is not what I am looking for though. Some dangles don't get selected, and some line features that aren't dangles are selected.

How can I do this?

Update regarding topology tools: The tools "Topology Checker" and "Check Geometries" seem to have problems finding real dangles. Both tools target end or start points of line features that are definitly connected to other features (vertexes and segments).

  • What have you tried so far? Where are you stuck?
    – Erik
    Sep 3, 2019 at 13:55
  • I'm stuck in the select by expression field. I can't wrap my head around how I can select features by their end or starting point topology.
    – Boschetto
    Sep 3, 2019 at 13:59
  • Can you provide examples of what you tried so far?
    – Erik
    Sep 3, 2019 at 14:13
  • 1
    The geometry functions can't accept a whole layer, they need a single geometry as input. Use collect($geometry) instead of the non-existent @layer term you've been trying to use. This expression should give you "everything else except the feature looked at": difference(collect($geometry),$geometry)).
    – csk
    Sep 4, 2019 at 18:33
  • 1
    @Boschetto - Just a train of thought as but you could try running the GRASS tool v.clean and selecting the rmdangle tool then set a threshold which you think is enough to remove the dangles in the layer. Then use the Difference tool with your original layer and the cleaned layer. Hopefully you'll be left with just dangles in a new layer which you could then add a new attribute field identifying these as dangles when you join/merge with the original layer or copy the original features into this new layer etc.
    – Joseph
    Sep 5, 2019 at 12:47

1 Answer 1


The logic you can use is: if a linestring does not intersect with the endpoint or startpoint of another linestring, it has a dangle.

This logic can be written as:

filter:=intersects($geometry, end_point(geometry(@parent)))) - 1 = 0
filter:=intersects($geometry, start_point(geometry(@parent)))) - 1 = 0

Change the values your_layer with the name of your lineslayer and fid with the name of your id-field

Because this query evaluates the amount of intersections a feature makes on his own layer, includes also the intersection with itself. So we have substract the result with 1.

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.