PyQGIS Map Layer – Cloning the Map Layer Using PyQGIS

copygroup-layerpyqgisqgsvectorlayer

I want to clone my generated memory layer and apply different filters and symbology. The clone is visible in the layer tree, but doesn't show up in the canvas. What am I doing wrong?

uri = f'point?crs=EPSG:25832&field=id:integer&index=yes'
l_out = QgsVectorLayer(uri, 'new layer', 'memory')

x, y = 369000, 5616000
with edit(l_out):
    for i in range(10):
        f = QgsFeature(l_out.fields())
        g = QgsGeometry(QgsPoint(x, y))
        f.setGeometry(g)
        f.setAttributes([i])
        l_out.addFeature(f)
        x += 50
        y += 50

project = QgsProject.instance()
project.addMapLayer(l_out)

tree = project.layerTreeRoot()
group0 = tree.insertGroup(0, 'level 0')
group1 = group0.addGroup('level 1')

lcopy = project.addMapLayer(l_out.clone(), False)
nodecopy = group1.insertLayer(-1, lcopy)

Best Answer

There are several suggestions regarding your code:

  • adding the same layer l_out one more time to the project, even with the addToLegend = False does not make much sense to me. In the documentation for the addMapLayer() method, it says what Returns it possesses:

    nullptr if unable to add layer, otherwise pointer to newly added layer

    However, the type of the lcopy-variable is the QgsVectorLayer. On the another side, the insertLayer() method works with QgsMapLayer and QgsVectorLayer.

  • no need to create the nodecopy-object, simply proceed with:

    group1.insertLayer(-1, lcopy)
    
  • application of these methods i.e. isValid() and hasFeatures() can be useful to check if your QgsVectorLayer is solid:

    if l_out.isValid() and l_out.hasFeatures():
       ...
    

I can also suggest several workarounds:

  1. using the findLayer() method of the QgsLayerTreeGroup class:

    project = QgsProject.instance()
    project.addMapLayer(l_out)
    
    tree = project.layerTreeRoot()
    
    group0 = tree.insertGroup(0, 'level 0')
    group1 = group0.addGroup('level 1')
    
    layer = tree.findLayer(l_out.id()) # QgsLayerTreeLayer
    lcopy = layer.clone() # QgsLayerTreeLayer
    group1.insertChildNode(0, lcopy)
    
  2. proceeding without cloning:

    project = QgsProject.instance()
    project.addMapLayer(l_out)
    
    tree = project.layerTreeRoot()
    group0 = tree.insertGroup(0, 'level 0')
    group1 = group0.addGroup('level 1')
    
    group1.insertLayer(-1, l_out)
    
  3. applying the materialize() method:

     project = QgsProject.instance()
     project.addMapLayer(l_out)
    
     tree = project.layerTreeRoot()
     group0 = tree.insertGroup(0, 'level 0')
     group1 = group0.addGroup('level 1')
    
     lcopy = l_out.materialize(QgsFeatureRequest().setFilterFids(l_out.allFeatureIds())) # QgsVectorLayer
     group1.insertLayer(-1, lcopy)
    
Related Question