I have fieldwork photos stored in a vector layer, geotagged from EXIF GPS data. Sometimes the GPS is off, or even missing, and I need to move their position manually. Unfortunately, the Advanced Digitization Move feature
command requires I click on the current (geotagged) position (after selecting the feature first) and only then the corrected position, which is awkward if the geotagged position is say Point (0 0)
.
As a workaround, I use the Lat Lon tools plugin to copy the desired position to the clipboard (as WKT), and then I've written a PyQGIS feature action to paste that as the feature's geometry. However, following the PyQGIS cookbook the code below uses the dataProvider()
to change the geometry, and so the currently open form and attribute table that are invoking the action don't pick up on the change. Even hitting the refresh icon isn't enough.
How could the action code be changed to use the (already active) QGIS editing session instead of going behind its back to the provider?
# find ourselves, layer first
ourLayerId = '[% @layer_id %]'
ourLayer = QgsProject.instance().mapLayer(ourLayerId)
# now the feature, note getFeatures returns an iterator, but will be unique
fid = [% $id %]
featIterator = ourLayer.getFeatures(QgsFeatureRequest().setFilterFid(fid))
feature=featIterator.__next__()
# figure out new geometry, using WKT from clipboard
# should check CRS (if WKT is output of Lat Long tools it should be 4326!). For now assume it's fine.
geomWkt = QgsApplication.clipboard().text()
geom = QgsGeometry.fromWkt(geomWkt)
# make the change. This bypasses the editing cache going to the data provider
result = ourLayer.dataProvider().changeGeometryValues({fid : geom})