Hy,
I'm creating my layer like this:
crs = core.QgsCoordinateReferenceSystem(4326, core.QgsCoordinateReferenceSystem.EpsgCrsId)
uri = "Polygon"
uri += '?crs=' + crs.authid()
uri += '&field=id_tsk:integer' # IDX_ID
uri += '&field=name:string' # IDX_NAME
uri += '&index=yes'
layer = core.QgsVectorLayer(uri, 'name', "memory")
core.QgsMapLayerRegistry.instance().addMapLayer(layer)
When I look to the capabilities of the dataProvider (in QGis Python console) i've got this:
>>> layer.dataProvider().capabilitiesString()
PyQt4.QtCore.QString(u'Add Features, Delete Features, Change Attribute Values, Add Attributes, Delete Attributes, Create Spatial Index, Fast Access to Features at ID, Change Geometries')
My data are contains in a QAbstractItemModel of my own. So when the model data changed I want to update only element / geometry that has changed and not the whole layer (witch might be big).
self._layer.setReadOnly(False)
feat_2_del = set()
feat_2_add = []
feat_2_chg = {}
# +1 because we want the bottomRight row to be selected
for row_num in xrange(topLeft.row(), bottomRight.row() + 1):
idx_geo = self._model.index(row_num, self._col_geo)
wkt_v = idx_geo.data(QtCore.Qt.DisplayRole)
obj = self._get_object_from_idx(idx_geo)
feat = self._object_map.get(obj.id)
geom = None
if not wkt_v.isNull():
wkt = wkt_v.toString()
if wkt.size() > 0:
# some object do not have any geometry defined
geom = core.QgsGeometry.fromWkt(wkt)
old_exist = feat is not None
new_has_geo = geom is not None
if old_exist and new_has_geo:
# we just change the old feature
feat_2_chg[feat.id()] = geom
elif old_exist and not new_has_geo:
# we remove the old feature
feat_2_del.add(feat.id())
del self._feature_map[feat.id()]
elif not old_exist and new_has_geo:
# we create a new feature
feat = core.QgsFeature(id(obj))
feat.addAttribute(IDX_ID, QtCore.QVariant(obj.id))
feat.addAttribute(IDX_NAME, QtCore.QVariant(obj.name))
feat.setGeometry(geom)
self._object_map[obj.id] = feat
self._feature_map[feat.id()] = obj
feat_2_add.append(feat)
self._layer.dataProvider().deleteFeatures(feat_2_del)
self._layer.dataProvider().addFeatures(feat_2_add)
self._layer.dataProvider().changeGeometryValues(feat_2_chg)
self._layer.commitChanges()
self._layer.setReadOnly(True)
self._iface.mapCanvas().refresh()
When I add a geometry information to an object (addFeatures), the layer is correctly updated (with the according geometry). But If I change the geometry (changeGeometryValues) or remove a feature (deleteFeatures) nothing is done. But my dataProvider should handle it.
What am I doing wrong ?