4

I want to create a LineString using points/coordinates in QGIS 3.26 using Python/PyQGIS.

Here is my code :

points = []

x = QgsPointXY(783648,1397243)
points.append(x)

y = QgsPointXY(788883,1396853)
points.append(y)

layer = iface.activeLayer()

fields = layer.dataProvider().fields()

feature = QgsFeature()
feature.setGeometry(QgsGeometry.fromPolylineXY(points))
feature.setFields(fields)
feature.setAttribute(0,12)

layer.addFeature(feature)

QgsProject.instance().addMapLayer(layer)

I am facing no error but I can't see any LineString in QGIS from the given points.

7
  • 2
    Try layer.dataProvider().addFeatures([feature]). And remove the last line. If your layer is in the layers panel it is already added to the project. Replace it with layer.triggerRepaint().
    – Ben W
    Commented Nov 14, 2022 at 10:28
  • Thank you this works
    – BenStone
    Commented Nov 14, 2022 at 10:34
  • Is this a LineString?
    – BenStone
    Commented Nov 14, 2022 at 10:34
  • 1
    The error you may get is AttributeError: 'NoneType' object has no attribute 'dataProvider'
    – Taras
    Commented Nov 14, 2022 at 13:39
  • Yes its a linestring
    – BenStone
    Commented Nov 16, 2022 at 11:02

1 Answer 1

4

The fundamental reason why your code is not working is that you are trying to add a feature to your layer without making it editable. If you want to immediately commit the changes to the layer's underlying data store, you should work with layer.dataProvider() instead. Also, you should remove the last line from your code snippet, since the active layer is already added to the project, and replace it with a few lines to reflect the changes to the layer.

points = []
x = QgsPointXY(783648,1397243)
points.append(x)
y = QgsPointXY(788883,1396853)
points.append(y)

layer = iface.activeLayer()

if layer.dataProvider().capabilities() & QgsVectorDataProvider.AddFeatures:
    feature = QgsFeature(layer.fields())
    feature.setGeometry(QgsGeometry.fromPolylineXY(points))
    feature.setAttributes([0, 12])
    layer.dataProvider().addFeatures([feature])
    layer.updateExtents()
    layer.triggerRepaint()
    iface.mapCanvas().refresh()
    # Optional...
    iface.zoomToActiveLayer()

On the other hand, if you want the opportunity to undo/ redo then save the edits via the GUI, you can just call layer.startEditing() before adding the feature to the layer:

points = []
x = QgsPointXY(783648,1397243)
points.append(x)
y = QgsPointXY(788883,1396853)
points.append(y)

layer = iface.activeLayer()

if layer.type() == QgsMapLayerType.VectorLayer:
    feature = QgsFeature(layer.fields())
    feature.setGeometry(QgsGeometry.fromPolylineXY(points))
    feature.setAttributes([0, 12])

    if not layer.isEditable():
        layer.startEditing()
        
    layer.addFeature(feature)
    layer.updateExtents()
    layer.triggerRepaint()
    iface.mapCanvas().refresh()
    # Optional...
    iface.zoomToActiveLayer()

I strongly recommend reading the PyQGIS Cookbook section on Modifying Vector Layers.

1
  • thank you, this worked for me.
    – BenStone
    Commented Nov 30, 2022 at 9:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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