2

I'm using QGIS 3.10 with Python 3.7.

I have two layers: "line_layer" and "vertices_layer". I want to add only the names of my vertices (attributtable: "node_name") to the attributtable of my "line_layer" (like start and end node --> attributtable: "node_start" and "node_end"). I have a net so for one line a point A is the start, while for another line this point A is the end. Thats why I can't divide my vertices into start-/endpoints. I want to do this in the console using python (I'm a beginner). My (definetly wrong) code is:

for f in line_layer.getFeatures():
    geom = f.geometry().asMultiPolyline()
    start_point = QgsPoint(geom[0])    #first point
    end_point = QgsPoint(geom[-1])     #last point
    f.['node_start'] = QgsGeometry.nearestPoint(start_point)
    f.['node_end'] = QgsGeometry.nearestPoint(end_point)

line_layer.commitChanges()

The code doesn't work and I don't know how to get only th name of the nearest point in the attributtable of my line_layer.

Just for understanding the situation:

enter image description here

3

So here is a Python solution to find the nearest point to the endpoints of the lines. In my sample I have a MultiPolyline layer with attributes: l_id (unique identifier), start_p and end_p integer. And a Point layer with an id attribute which I filled by $id (so the id attribute of the points are the same as the featureID), it make the solution simpler.

# get the line layer by name
line_layer = QgsProject.instance().mapLayersByName('lll')[0]
# get the point layer by name
point_layer = QgsProject.instance().mapLayersByName('ppp')[0]
point_provider = point_layer.dataProvider()
# build spatial index for point layer (used by search)
sp_index = QgsSpatialIndex()
for f in point_layer.getFeatures():
    sp_index.insertFeature(f)    # insert feature in the spatial index
line_layer.startEditing()    
for f in line_layer.getFeatures():
    geom = f.geometry().asMultiPolyline()
    start_point = geom[0][0]    # get the first point of the first part
    # feature id of nearest point to start point
    nearest_to_startpoint = sp_index.nearestNeighbor(start_point, 1)[0]
    f['start_p'] = nearest_to_startpoint
    # get id ttribure
    end_point = geom[0][-1]    # get the last point of the first part
    # feature id of nearest point to start point
    nearest_to_endpoint = sp_index.nearestNeighbor(end_point, 1)[0]
    f['end_p'] = nearest_to_endpoint
    line_layer.updateFeature(f)
line_layer.commitChanges()

Weaknesses of the code:

No error handling at all.

It will find the nearest point to the endpoint of the line, not the point at the endpoint of the line (if a point missing the result will be false), you should check distance.

It works with the first part of the multipolyline feature.

If you would like to store the id attribute of point features instead of the feature ID you have to get the point feature somehow this:

fs =  point_layer.getFeatures(QgsFeatureRequest().setFilterFid(nearest_to_start))
point_feature = QgsFeature()
fs.nextFeature(point_feature)
p_id = point_feature['id']
1
  • Thanks a lot! Works perfect! – Julz_Mos May 6 '20 at 10:39
1

I think it is easier to do it in DB Manager using SQL. In my example I created two layers, ppp is a point layer with point IDs, lll is a line layer connecting points with l_IDs. Check if DB Manager plug-in is active, Plugins/Manage and Install plugins.., on the Installed tab turn on DB Manager.

In the DB Manager open Virtual layers and Project layers. Select the SQL window from the toolbar (second icon).

In the upper box insert the following query:

SELECT lll.geometry, l_id, a.id as start_id, b.id as end_id 
FROM lll  
INNER JOIN ppp a on ST_Distance(ST_StartPoint(lll.geometry), a.geometry) < 1 
INNER JOIN ppp b on ST_Distance(ST_EndPoint(lll.geometry), b.geometry) < 1

Press the execute button and you'll get the result table. Check Load as new Layer and finally press Load button.

enter image description here

You will get a new QueryLayer in the layer list with the IDs of start and end point. Finally save this layer.

3
  • 1
    thanks for the reply but I want to automate several steps. Thats why I wrote a (python) script and searching for help with python.. – Julz_Mos May 6 '20 at 5:48
  • I added a Python solution, too. – Zoltan May 6 '20 at 8:27
  • Unfortunately this does not answer the author's desire, author tends to achieve the result by means of pyqgis. By the way almost similar answer I put to author's previous question, check it here QGIS add attributes of points to attributtable of lines. – Taras May 6 '20 at 8:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.