[GIS] Editing geometry field using QGIS Python API

pyqgisqgis-processing

I have shapefile representing roads as polylines, I want to add 1 arc degree to lat & lot of every point constructing each poly line:

from qgis.PyQt.QtCore import *

layer = iface.addVectorLayer("file_path.shp", "my_layer", "ogr")
iter = layer.getFeatures()
for feature in iter:
    geom = feature.geometry().asPolyline()
    new_geom = []
    for point in geom:
        lon = point[0]
        lat = point[1]
        lon = lon + 1  # or whatever calculation doesn't matter
        lat = lat + 1
        new_geom.append(QgsPoint(lon, lat))
    layer.dataProvider().changeGeometryValues({feature.id(): QgsGeometry.fromPolyline(new_geom)})
crs = layer.crs()
crs.createFromId(4326)
layer.setCrs(crs)
layer.beginEditCommand("edit")
layer.endEditCommand() 

When I load the shapefile after executing this script and print all the geoms, I see the editing took place.

However QGIS doesn't display the file (it's not a CRS issue) probably because in the properties->metadata of the file I see in the min/max values, old values before the editing took place.

What I'm doing wrong here?

Best Answer

Your code worked for me too. I think you should only apply a slight edit when importing the layer:

layer = QgsVectorLayer("file_path.shp", "my_layer", "ogr")

instead of the line you provided. Doing this, you will load the layer into QGIS, but it won't be shown in the Layers Panel until you will insert the following line at the end of the script:

QgsMapLayerRegistry.instance().addMapLayer(layer)

Applying these edits, your code will become:

from qgis.PyQt.QtCore import *

layer = QgsVectorLayer("file_path.shp", "my_layer", "ogr")
iter = layer.getFeatures()
for feature in iter:
    geom = feature.geometry().asPolyline()
    new_geom = []
    for point in geom:
        lon = point[0]
        lat = point[1]
        lon = lon + 1  # or whatever calculation doesn't matter
        lat = lat + 1
        new_geom.append(QgsPoint(lon, lat))
    layer.dataProvider().changeGeometryValues({feature.id(): QgsGeometry.fromPolyline(new_geom)})
crs = layer.crs()
crs.createFromId(4326)
layer.setCrs(crs)
layer.beginEditCommand("edit")
layer.endEditCommand()

QgsMapLayerRegistry.instance().addMapLayer(layer)
Related Question