Geographic Information Systems Asked on January 13, 2021
For an examination of a local power grid, I need to mark the transformation stations (substation) by simply create a point for each station.
What I want to do is that QGIS creates a point at the end of a line automatically.
How can I get there?
There is a possibility using a "Virtual Layer" through Layer > Add Layer > Add/Edit Virtual Layer...
Let's assume there is a polyline layer called 'polylines'
(blue lines).
With the following query, it is possible to create a point at the end of each line.
SELECT st_endpoint(geometry), *
FROM "polylines"
The output point layer (yellow) with its attribute table will look like
Mind the difference between ST_StartPoint()
and ST_EndPoint()
. Basically, what @TeddyTedTed meant by Which one you need will depend on the direction of the line.
Correct answer by Taras on January 13, 2021
In the Processing Toolbox use the Extract Specific Vertices
tool, for the Vertex indices
use 0
for the first vertex and -1
for the last vertex. Which one you need will depend on the direction of the line.
EDIT: Apologies, I didn't read your question properly, you said automatically. If it's just for display purposed you could use a geometry generator symbology to show a point at the end of the line using end_point($geometry)
as the expression. If you need to create an actual data point automatically every time a line is created then I'm not sure how to do that.
Answered by TeddyTedTed on January 13, 2021
A simple solution could be:
Using Vector ‣ Geometry Tools ‣ Extract verticas. Afterwards simply delete all points but thoose which were generated at the end and beginning.
Answered by Ma Fo on January 13, 2021
You can use the processing tool "Geometry by Expression" and either use start_point($geometry)
or end_point($geometry)
as expression.
If you want them for display purposes only, you can use these expression within layersymbology and add an geometry generator.
Answered by MrXsquared on January 13, 2021
Additionally, I may suggest using PyQGIS, tested on QGIS 3.10.4-A Coruña.
Let's assume there is a point layer "lines"
, see image below.
Proceed with Plugins > Python Console > Show Editor
and paste the script below
# providing the polyline layer's name
layer_name = "line"
# accessing the line layer by name
try:
layer = QgsProject.instance().mapLayersByName(layer_name)[0]
except IndexError:
raise ValueError("The layer {} does not exist.".format(layer_name))
# creating an empty point layer for output
point_layer = QgsVectorLayer("Point?crs={}&index=yes".format(layer.crs().authid()), "End Points", "memory")
provider = point_layer.dataProvider()
# detecting layer wkb and wkb type
layer_wkb = layer.wkbType() # integer
layer_wkb_type = QgsWkbTypes.displayString(layer_wkb) # string
# checking geometry type of the layer
if layer.wkbType() == QgsWkbTypes.MultiLineString: # getting end points for each part of a MultiLineString layer geometry type
print("Your layer is a {}-geometry type".format(layer_wkb_type))
for feature in layer.getFeatures():
multi_geom = feature.geometry().asMultiPolyline()
for part in multi_geom:
end_point = QgsPoint(part[-1])
f = QgsFeature()
f.setGeometry(end_point)
provider.addFeature(f)
elif layer.wkbType() == QgsWkbTypes.LineString: # getting end points for a LineString layer geometry type
print("Your layer is a {}-geometry type".format(layer_wkb_type))
for feature in layer.getFeatures():
geom = feature.geometry().asPolyline()
end_point = QgsPoint(geom[-1])
f = QgsFeature()
f.setGeometry(end_point)
provider.addFeature(f)
else: # other layer geometry types are not accepted
print("Your layer is a {}-geometry type, when only 'LineString' or 'MultiLineString' is accepted".format(layer_wkb_type))
# adding a new layer to the map
QgsProject.instance().addMapLayer(point_layer)
Press Run script
and get the output that will look like
References:
Answered by Taras on January 13, 2021
Another approach via RMB > Duplicate Layer
.
Then for a new layer by means of "Geometry Generator" apply RMB > Properties > Symbology > Geometry Generator
as Point/MultiPoint. This will be for display purposes only.
If you are using "Geometry by Expression" from processing toolbox this is not for display purposes only. It creates the geometry as new layer.
Answered by Taras on January 13, 2021
Another example using pyqgis:
layer = iface.activeLayer()
def find_endpoint(feat):
for item in feat.geometry().vertices(): #https://stackoverflow.com/questions/2138873/cleanest-way-to-get-last-item-from-python-iterator
pass
return QgsPointXY(item)
ends = [find_endpoint(f) for f in layer.getFeatures()]
vl = QgsVectorLayer("Point?crs={}&index=yes".format(layer.crs().authid()), "endpoints", "memory")
provider = vl.dataProvider()
for e in ends:
g = QgsGeometry.fromPointXY(e)
f = QgsFeature()
f.setGeometry(g)
provider.addFeature(f)
QgsProject.instance().addMapLayer(vl)
Answered by BERA on January 13, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP