[Qgis-developer] Changes to a newly created memory layer are affecting the original layer from which it was copied

Tom Chadwin tom.chadwin at nnpa.org.uk
Wed Mar 16 02:43:18 PDT 2016


Sorry about the convoluted subject line. qgis2web is built from @volaya's
qgis-ol3 plugin (thanks as ever, Victor). That exported layers by making
temporary memory copies of them, in order to manipulate them pre-export
without affecting the original layer and corrupting the user's data. This
worked perfectly.

However, in building the 2.5d export functionality, something has gone
wrong, and I've introduced a very nasty new bug. Somehow, changes I make to
the memory layer (the copy of the original) are being written back to the
original user's layer. What have I done wrong?

The function which creates the memory copy layer is:

def writeTmpLayer(layer, popup):
    usedFields = getUsedFields(layer)
    if popup != ALL_ATTRIBUTES:
        uri = TYPE_MAP[layer.wkbType()]
        crs = layer.crs()
        if crs.isValid():
            uri += '?crs=' + crs.authid()
        if popup != NO_POPUP:
            usedFields.append(popup)
        for field in usedFields:
            fieldType = layer.pendingFields().field(field).type()
            fieldType = "double" if (fieldType == QVariant.Double or
                                     fieldType == QVariant.Int) else (
                                        "string")
            uri += '&field=' + unicode(field) + ":" + fieldType
        newlayer = QgsVectorLayer(uri, layer.name(), 'memory')
        writer = newlayer.dataProvider()
        outFeat = QgsFeature()
        for feature in layer.getFeatures():
            outFeat.setGeometry(feature.geometry())
            attrs = [feature[f] for f in usedFields]
            if attrs:
                outFeat.setAttributes(attrs)
            writer.addFeatures([outFeat])
        layer = newlayer
    return layer

The snippet which calls the function above and is meant to add the fields to
the memory layer is:

if (layer.type() == layer.VectorLayer)
    cleanLayer = writeTmpLayer(layer, popup)
    if is25d(layer, canvas):
        provider = cleanLayer.dataProvider()
        provider.addAttributes([QgsField("height", QVariant.Double),
                                QgsField("wallColor", QVariant.String),
                                QgsField("roofColor",
                                         QVariant.String)])
        cleanLayer.updateFields()

When the plugin runs, the new fields height, wallColor, and roofColor are
appearing in the original user's layer. Each time the plugin is run,
additional copies of those fields are created. Hence, a very nasty bug.

How is this affecting the original layer, rather than the newly created
cleanLayer?

The actual code is here:
https://github.com/tomchadwin/qgis2web/blob/master/utils.py#L63



--
View this message in context: http://osgeo-org.1560.x6.nabble.com/Changes-to-a-newly-created-memory-layer-are-affecting-the-original-layer-from-which-it-was-copied-tp5256690.html
Sent from the Quantum GIS - Developer mailing list archive at Nabble.com.


More information about the Qgis-developer mailing list