When I try to modify a features geometry in a vector layer (linestrings) resulting from a processing.runalg() operation like

clip = processing.runalg('qgis:clip', ...)
layer = QgsVectorLayer(clip['OUTPUT'], 'TheLayerName', 'ogr')

# add layer to map registry, load named style, create spatial index

layer_dp = layer.dataProvider()

# assume feat is a feature of mem_layer
# assume pt some QgsPoint on feat.geomatry(), but not a vertex

dist, p2, to_id = feat.geometry().closestSegmentWithContext(pt)

# obviously, insertVertex() does not accept QgsPoint as first argument 
newgeom = feat.geometry().insertVertex(pt.x(), pt.y(), to_id)

layer_dp.changeGeometryValues({feat.id() : newgeom})

as decribed in the PyQGIS Programming Cookbook 2.18, Section 5.4.3, p.21 (https://docs.qgis.org/2.18/pdf/en/QGIS-2.18-PyQGISDeveloperCookbook-en.pdf)

I get the following error:

QgsVectorDataProvider.changeGeometryValues(unknown-type): argument 1 has unexpected type 'dict'

What can be possibly gone wrong here?

  • Can you update your question and show where you are defining newgeom? – artwork21 Jan 5 '18 at 13:27
  • Sorry, it's not about a memory layer, not shure if this is important... I updated my question, hope this is is helpful in the context of this error – Jochen Schwarze Jan 5 '18 at 13:48
  • @JochenSchwarze - What do you receive when you print newgeom? – Joseph Jan 5 '18 at 13:53
  • Should mem_layer_dp.changeGeometryValues..... be layer_dp.changeGeometryValues.....? – artwork21 Jan 5 '18 at 14:06
  • 1
    @Joseph this pointed me to right direction (again): when I print newgeom I receive True, so insertVertex() obviously does not return the changed geometry, but changes the geometry in-place and returns True, when successful. So, my error message might have lead to slight misinterpretations... Going to add this as an answer. – Jochen Schwarze Jan 5 '18 at 14:18

The erroneous part in my code is, that the insertVertex() method of the QgsGeometry class does not return a QgsGeometry, but changes the geometry from which it is called in-place, and returns 'True' if the insertion was successful.

So the problem is not the dictionary passed to the QgsVectorDataProvider.changeGeometryValues({id:geom}) method, but the value being a boolean value instead of a QgsGeometry, so the above code works with a small alteration:

newgeom = feat.geometry()
newgeom.insertVertex(pt.x(), pt.y(), to_id)

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.