I am trying to plot points at specific positions along a line (which exists in the 'current layer' and is selected on the canvas) - these positions are irregular, so I am intending to loop through a list (chainage) and then add a new point layer.
I have created a python script by scrounging around various sources. You may recognise the code as mashed from yours. To get it to nearly work in QGIS 3.4 I've had to adapt some of the existing code to work with the changes to the API since some of the code was written... Introduced errors within this are mine. However, the problem appears to be that it cannot add the integer attribute, even though I used the QGIS pycookbook for that bit:
from qgis.core import (QgsFeature, QgsGeometry,
QgsVectorLayer, QgsProject,
QgsField)
from qgis.PyQt.QtCore import QVariant
from qgis.utils import iface
#list of positions along line (chainage) - to do - read a csv file!
chainage = [0,13,34,54]
# Create a new memory layer and add a distance attribute
vl = QgsVectorLayer("Point", "distance nodes", "memory")
pr = vl.dataProvider()
pr.addAttributes( [ QgsField("distance", QVariant.Int) ] )
layer = iface.activeLayer()
selection = layer.selectedFeatures()
for feature in selection:
geom = feature.geometry()
# Loop though all the chainage distances
for dist in chainage:
fet = QgsFeature()
fet.setGeometry(geom.interpolate(dist))
fet.setAttributes(dist)
pr.addFeatures([fet])
vl.updateExtents()
QgsProject.instance().addMapLayer(vl)
This nearly works and then falls over at line 19 an error related to the integer.
TypeError: QgsFeature.setAttributes(): argument 1 has unexpected type 'int'
If I comment out that line it works, but obviously I don't have the distance as an attiribute, just the geometry.
Maybe it's because I've cherry picked from different places / versions, because I'm not a python programmer.
I've included all my code because it might be useful to others... There seem to be a few similar questions out there.
I know my code is clumsy and not 'best practice' - once I get it working I can prettify it and probably rationalise it a bit.