I struggle with creating a deep copy of a memory layer in QGIS. Whenever I modify the layer copy, the original gets modified, too. Can anybody point me to the mistake I am making in the following code:
def createMemoryLayer(self, layerName, sourceLayer):
# create empty memory layer
memoryLayer = QgsVectorLayer(
QgsWkbTypes.geometryDisplayString(sourceLayer.geometryType()) +
"?crs=" + sourceLayer.crs().authid() +
"&index=yes",
layerName,
"memory"
)
memoryLayerDataProvider = memoryLayer.dataProvider()
# copy the table structure
memoryLayer.startEditing()
memoryLayerDataProvider.addAttributes(
sourceLayer.fields().toList()
)
memoryLayer.commitChanges()
# copy the features
#memoryLayerDataProvider.addFeatures(
# [QgsFeature(feature) for feature in sourceLayer.getFeatures()]
#)
# DEEP copy the features
features= []
for feature in sourceLayer.getFeatures():
f = QgsFeature(feature)
f.setGeometry(QgsGeometry(feature.geometry()))
features.append(f)
memoryLayerDataProvider.addFeatures(features)
return memoryLayer
see the commented-out lines for what I had thought to fix with the lines thereafter.
According to the API docs, QgsFeature(QgsFeature)
and QgsGeometry(QgsGeometry)
both create deep copy of the original object.
Any clues?
"Polygon?crs=" + sourceLayer.crs().authid() +
, then usedQgsMapLayerRegistry.instance().addMapLayer(createMemoryLayer(None, 'dest', QgsMapLayerRegistry.instance().mapLayersByName('source')[0]))
interactively to copy a memory polygon layer. I could then edit both layers independently. Which szenario did you test?QThread
. Note that I only add it to themapLayerRegistry
after the processing has finished. The curious thing is that it seems to depend on whether the original layer is a memory layer too (all works as expected, if the input layer is a shape file) Just compiling qgis-2.18 to test your code, thanks!QgsAbstractGeometry
objects remain the same – even if theQgsFeature
s andQgsGeometry
s change.[repr(f.geometry().geometry()) for f in memoryLayer.getFeatures()]
and[repr(f.geometry().geometry()) for f in sourceLayer.getFeatures()]
return the same memory addresses. Working on it – I’m going to report back once I know more