You can do this with two "Rule-based Labelling" labels, with no filters. This lets you put multiple labels on a feature. The first rule labels the feature with the attribute you want at the start, the second rule with the end attribute. Initially your labels will appear in the centre of the line, so we need to fix that.
Do that with "data defined" expressions for the position. Use the drop-down and hit "Edit...". For the label at the start, use x_at(0)
and y_at(0)
for the position expressions. For the end label, use x_at(-1)
and y_at(-1)
. End result is:
In PyQGIS you can use interpolate method from QgsGeometry to do that. Generated points can be stored as a memory layer. Complete example code is:
layer = iface.activeLayer()
feat = layer.getFeatures().next()
geom = feat.geometry()
length = geom.length()
distance = 100
points = []
iter = distance
while iter <= length:
pt = feat.geometry().interpolate(iter).exportToWkt()
points.append(pt)
iter += distance
epsg = layer.crs().authid()
uri = "Point?crs=" + epsg + "&field=id:integer""&index=yes"
mem_layer = QgsVectorLayer(uri,
'points',
'memory')
prov = mem_layer.dataProvider()
feats = [ QgsFeature() for i in range(len(points)) ]
for i, feat in enumerate(feats):
feat.setAttributes([i])
feat.setGeometry(QgsGeometry.fromWkt(points[i]))
prov.addFeatures(feats)
QgsMapLayerRegistry.instance().addMapLayer(mem_layer)
I tried it out with line shapefile of next image; where it is also observed memory point layer produced.
Editing Note:
A shorter code could be generated if you have installed in your system fiona and shapely python modules.
import fiona
from shapely.geometry import shape, mapping
line = fiona.open('pyqgis_data/new_line.shp')
crs = line.crs
line = line.next()
geom = shape(line['geometry'])
# length of the LineString
length = geom.length
# creation of the resulting shapefile
schema = {'geometry': 'Point','properties': {'id': 'int'}}
with fiona.open('pyqgis_data/new_shape.shp', 'w', 'ESRI Shapefile', schema, crs=crs) as output:
# create points every 100 meters along the line
for i, distance in enumerate(range(0, int(length), 100)):
point = geom.interpolate(distance)
output.write({'geometry':mapping(point),'properties': {'id':i}})
It produces same result layer (but it's saved in disk as shapefile; not as memory layer).
Best Answer
If you have QGIS 3.4 you can use
Extract specific vertices tool
to extract the endpoints by inputting0, -1
at the vertex indices as you can see below:The tool is located in
Processing toolbox -> Vector geometry -> Extract specific vertices tool
.The input is a polyline composing of several segments
Using the above tool with
0,-1
indices provides the endpoints only: