8

How do I generate the dangle points (into shapefile or something) (blue dots in picture below) of any polyline in QGIS? These are not start/end vertices.

dangle points

5
  • 1
    How can that not be start/end points? Do they go out and back again? Can you share the data?
    – Bera
    Commented Apr 2, 2022 at 13:40
  • 1
    @BERA they might not be all the start/end points. I guess a line could start from a blue dot and end at a junction..
    – Spacedman
    Commented Apr 2, 2022 at 13:45
  • 1
    Not if there's other lines heading out from the junction. It seems the Questioner wants the perimeter of the line network, which is a set of points. If the network is fully noded at junctions, the set of vertices with no duplicates at that point would be the required set, I think. Otherwise some sort of DE9IM en.wikipedia.org/wiki/DE-9IM operation will get it, but I don't see that or a plugin in QGIS.
    – Spacedman
    Commented Apr 2, 2022 at 13:53
  • 1
    First approach: take all line segment start/end points, compute nearest neighbour of each point, select those where nearest neighbour distance > epsilon where epsilon is very small (ideally 0 for a precisely noded network). Assumes lines don't double-back at the blue dots.
    – Spacedman
    Commented Apr 2, 2022 at 13:55
  • Hi Bera @BERA , that is not how vertices work. the first vertex can be the junction while the last vertex is the endpoint. Conversely, an endpoint can be the first vertex. So, starting and ending vertices are not relevant; what relevant is dangling (whether they are start vertex, or end vertex). In terms of data, this is an openstreetmap data (which I assume everyone has. This is not exclusive to my data, this is a general polyline issue).
    – sutan
    Commented Apr 2, 2022 at 14:04

4 Answers 4

8
  1. Extract the vertices from road layer
  2. Explode the lines
  3. Join each line to the vertices, end points will get line count 1 and all other more than 1
  4. Extract them

enter image description here

7

The specification of any polyline is a little optimistic (given the possibility of duplicate geometries), but for a topologically correct network it can be done using a "Virtual Layer" through Layer > Add Layer > Add/Edit Virtual Layer....

This query first collects all start and end points into one table, then selects those points which intersect only once with the lines layer.

Assuming the line layer is called 'edges' and its geometry field is called geometry:

SELECT *
FROM (
    SELECT ST_StartPoint(geometry) AS geom
    FROM edges
    UNION 
    SELECT ST_EndPoint(geometry) AS geom
    FROM edges
    ) AS startend
JOIN edges
    ON ST_Intersects(startend.geom, edges.geometry)
GROUP BY startend.geom
HAVING COUNT(*) = 1

enter image description here

Note: The seemingly missing point towards the lower left of the image is actually a cul-de-sac and not a dangle! enter image description here

6

To just visualize the dangles, use Geomtetry generator with this expression (see below to create actual geometries):

difference (
    collect_geometries (
        array_foreach(
            array (start_point($geometry), end_point($geometry)),
            with_variable (
                'point',
                @element,
                if (
                    array_sum(
                        array_foreach(
                            overlay_nearest(
                                @layer, 
                                $geometry,
                                limit:=100,
                                max_distance:=0.1  -- change this distance to fit your needs
                            ),
                            intersects (
                                @element, 
                                buffer(@point,0.1)  -- change this distance to fit your needs
                            )
                        )
                    ) = 0,
                    @point,
                    make_point(0,0)
                )
            )
        )
    ),
    make_point(0,0)
)

enter image description here


To create acutal geometries that can then be saved as Shapefile, you can't use this expression, but - based on the expression above - must proceed in three steps:

  1. Extract all start- and end-points using Geometry by expression with this expression: union (start_point ($geometry), end_point($geometry))

  2. Run Multipart to singleparts

  3. On the resulting layer, once again use Geometry by expression, this time with this expression (based on the solution above with Geometry generator):

if (
    array_sum(
        array_foreach(
            overlay_nearest(
                'network', -- change the layer's name accordingly
                $geometry,
                limit:=100,
                max_distance:=0.1  -- change this distance to fit your needs
            ),
            intersects (
                @element, 
                buffer($geometry,0.1)  -- change this distance to fit your needs
            )
        )
    ) = 1,
    $geometry,
    NULL
)
2
  • thanks but can you export this to shapefile (which is the initial question)?
    – sutan
    Commented Apr 3, 2022 at 12:51
  • Added that to my solution
    – Babel
    Commented Apr 3, 2022 at 13:14
5

Let's assume there is a polyline layer called 'lines_test2' with several features in it, see the image below.

input

Step 1. Proceed with "Split with lines" tool to split the line layer with itself.

step1

Step 2. Apply the "Extract specific vertices" geoalgorithm to get the first and the last points.

window1

step2

Step 3. Make use of the "Extract by expression" tool together with the following expression:

count(1, group_by:=geom_to_wkt($geometry)) = 1

window2

and get the output

step3

1
  • 1
    thanks! very clear and neat.
    – sutan
    Commented May 10, 2022 at 12:06

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.