3

I'm trying to add features to a memory layer. This is the layer creation :

memlayer=QgsVectorLayer("{zr_typegeom}?crs=epsg:4326".format(zr_typegeom = typegeom), "memlayer", "memory")     
QgsMapLayerRegistry.instance().addMapLayer(memlayer, False)  
root = QgsProject.instance().layerTreeRoot()
memlayerNode = QgsLayerTreeLayer(memlayer)
root.insertChildNode(0, memlayerNode)
self.iface.setActiveLayer(memlayer)
memlayer.startEditing()

Then I create the "new_feature" list of features. Users have selected features in an active layer. Each feature is split if it is multipart, or just pasted in "new_features" if it is single part.

Then I copy all the features in the memory layer with the "addFeatures()" property.

new_features = []
for feature in coucheactive.selectedFeatures() :
    geom = feature.geometry()
    # check if feature geometry is multipart
    if geom.isMultipart():
        temp_feature = QgsFeature(feature)
        # create a new feature using the geometry of each part
        for part in geom.asGeometryCollection ():
            temp_feature.setGeometry(part)
            new_features.append(QgsFeature(temp_feature))
    else :
        new_features.append(feature)
memlayer.addFeatures(new_features, True)
memlayer.commitChanges()
print "memlayercount="+str(memlayer.featureCount())

The "new_feature" list contains features, I've checked that with

    new = [QgsGeometry(feature.geometry()) for feature in new_features]
    print "new="+str(new)

But the memory layer (memlayer) stays desesperately empty. (memlayercount = 0)

Is it possible to use the "addFeatures()" property on a memory layer? If so, what am I doing wrong?

4

What you want to do is to copy the original layer to a memory layer with some conditions.

If the original layer has fields and attributes, your script will not work because. you don't define any field in the memory layer (see pyQGIS manually copy all features with attributes from a layer into a memory layer )

If you work in the Python console, you don't need to use memlayer.startEditing()

1) Example with geometry only (no need to define fields in the memory layer)

orig_layer = qgis.utils.iface.activeLayer()
res_layer = QgsVectorLayer("Point", "test", "memory")
outFeat = QgsFeature()
for feature in orig_layer.selectedFeatures():
    outFeat.setGeometry(feature.geometry())
    res_layer.dataProvider().addFeatures([outFeat])
    res_layer.updateExtents()

Add the layer to the canvas (end of edition of the memory layer)

QgsMapLayerRegistry.instance().addMapLayers([res_layer])

2) Example with geometry and attributes copying the fields and attributes of the original layer (and not defining new fields as in the script of underdark)

orig_layer = qgis.utils.iface.activeLayer()
res_layer = QgsVectorLayer("Point", "test2", "memory")
# now you can add what you want to the resulting layers (as the fields of the original layer)
orig_layer_fields = orig_layer.dataProvider().fields().toList()
res_layer_fields= [QgsField(attrib.name(),attrib.type()) for attrib in orig_layer_fields]
# add the original fields to the memory layer
res_layer.dataProvider().addAttributes(res_layer_fields)
res_layer.updateFields()

Now copy the original layer geometries and attributes to the memory layer

res_layer.updateFields()
outFeat = QgsFeature()
for feature in orig_layer.selectedFeatures():
    outFeat.setGeometry(feature.geometry())
    outFeat.setAttributes(feature.attributes())
    res_layer.dataProvider().addFeatures([outFeat])
    res_layer.updateExtents()
    res_layer.updateFields()

QgsMapLayerRegistry.instance().addMapLayers([res_layer])

3) Put your conditions in the for loop

1
  • Oh yes! Indeed, I didn't need attributes. So, taking and adjusting your first example, everything works now. Entities or parts of entities are added to the memory layer. Thank you for this detailed answer.
    – V Damoy
    Nov 20 '15 at 10:35
2

I've had no problems adding features to memlayer.dataProvider() as shown in http://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/vector.html#memory-provider:

# create layer
vl = QgsVectorLayer("Point", "temporary_points", "memory")
pr = vl.dataProvider()

# add fields
pr.addAttributes([QgsField("name", QVariant.String),
                QgsField("age",  QVariant.Int),
                QgsField("size", QVariant.Double)])
vl.updateFields() # tell the vector layer to fetch changes from the provider

# add a feature
fet = QgsFeature()
fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(10,10)))
fet.setAttributes(["Johny", 2, 0.3])
pr.addFeatures([fet])

# update layer's extent when new features have been added
# because change of extent in provider is not propagated to the layer
vl.updateExtents()
4
  • Anita ... would u mind showing us how u then modify the attributes of an added QgsFeature (in a memory layer !) ? I'm stuck on that problem for a while, tried every syntax ...
    – Snaileater
    Nov 17 '15 at 20:22
  • 1
    Please start a separate thread for that question.
    – underdark
    Nov 17 '15 at 21:01
  • I started a similar question yesterday : gis.stackexchange.com/questions/170459/change-attributes-values
    – Snaileater
    Nov 17 '15 at 21:07
  • I didn't figure this answer would be in the cookbook. Next time, I'll look more deeply inside. I keep looking for a solution to my bug. Thank you very much.
    – V Damoy
    Nov 20 '15 at 9:08

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.