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.
-
1How can that not be start/end points? Do they go out and back again? Can you share the data?– BeraCommented 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..– SpacedmanCommented Apr 2, 2022 at 13:45
-
1Not 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.– SpacedmanCommented Apr 2, 2022 at 13:53
-
1First 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.– SpacedmanCommented 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).– sutanCommented Apr 2, 2022 at 14:04
4 Answers
- Extract the vertices from road layer
- Explode the lines
- Join each line to the vertices, end points will get line count 1 and all other more than 1
- Extract them
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
Note: The seemingly missing point towards the lower left of the image is actually a cul-de-sac and not a dangle!
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)
)
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:
Extract all start- and end-points using Geometry by expression with this expression:
union (start_point ($geometry), end_point($geometry))
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
)
-
thanks but can you export this to shapefile (which is the initial question)?– sutanCommented Apr 3, 2022 at 12:51
-
Let's assume there is a polyline layer called 'lines_test2' with several features in it, see the image below.
Step 1. Proceed with "Split with lines" tool to split the line layer with itself.
Step 2. Apply the "Extract specific vertices" geoalgorithm to get the first and the last points.
Step 3. Make use of the "Extract by expression" tool together with the following expression:
count(1, group_by:=geom_to_wkt($geometry)) = 1
and get the output
-
1