Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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 ?

share|improve this question
add comment

Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.