3

I have seen Duplicating layer in memory using pyqgis? and I would like to do the same but for any active layer in the TOC whether it is a Polygon, Linestring or Point layer.

Is it possible?

This is the code I tried

 iface = qgis.utils.iface 
vl = iface.activeLayer() 
feats = [feat for feat in vl.getFeatures()] 
mem_layer = QgsVectorLayer(vl.source(), "duplicated_layer", "memory")   mem_layer_data = mem_layer.dataProvider() 
attr = layer.dataProvider().fields().toList() mem_layer_data.addAttributes(attr) mem_layer.updateFields() mem_layer_data.addFeatures(feats) QgsMapLayerRegistry.instance().addMapLayer(mem_layer)
E. Salas
  • 33
  • 3

2 Answers2

2

Try using the following in the Python Console which should do the following:

  • Determines layer type (e.g. point, linestring or polygon).
  • Creates a duplicated layer containing a copy of all features and attributes.
  • Assigns a CRS (Coordinate Reference System) which you specify when running the function.

Here is the code:

def dup_layer(crs):
    layer = iface.activeLayer()
    layer_type = {'0':'Point', '1':'LineString', '2':'Polygon'}
    mem_layer = QgsVectorLayer(layer_type[str(layer.geometryType())] + "?crs=epsg:" + str(crs), "duplicated_layer", "memory")
    feats = [feat for feat in layer.getFeatures()]
    mem_layer_data = mem_layer.dataProvider()
    attr = layer.dataProvider().fields().toList()
    mem_layer_data.addAttributes(attr)
    mem_layer.updateFields()
    mem_layer_data.addFeatures(feats)
    QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

After you type the code into the console, select a layer and type the following:

dup_layer(4326)

This will create a duplicated layer with a CRS of EPSG:4326. You change the CRS to fit your needs.

Joseph
  • 75,746
  • 7
  • 171
  • 282
0

The question you referenced has a new answer now that should do what you need (and with considerably less code):

layer.selectAll()
clone_layer = processing.run("native:saveselectedfeatures", {'INPUT': layer, 'OUTPUT': 'memory:'})['OUTPUT']

To deselect everything afterwards you can use:

layer.removeSelection()
seaplant
  • 1
  • 1