TransWikia.com

Remove Layers only if layers already exist using PyQGIS

Geographic Information Systems Asked by Lino.Lohan on February 9, 2021

I have written a code that imports the different Layers from a folder to QGIS. The problem is that when I run the code again, the layers are duplicated and so on.
If I try to remove the layer at the beginning of the code with:

QgsProject.instance().removeMapLayers([layername.id()])

The first time I run the code, I wont work since the layers do not exist yet.
To check with layers are in the project, I used this command:

for layer in QgsProject.instance().mapLayers().values():
    print(layer.name())

With this I become a list with the following existing layers:

ne_50m_coastline
ne_50m_graticules_30
ne_50m_ocean
ne_50m_rivers_lake_centerlines

Is there a way to remove the layers only if they already exist in the project?

3 Answers

What I use is this:

def removeLayers(layerName):
    for layer in QgsProject.instance().mapLayers().values():
        if layer.name()==layerName:
            QgsProject.instance().removeMapLayers( [layer.id()] )           

If you have duplicate layers it will remove both of them.

Answered by Stephen Poley on February 9, 2021

To detect layers you want to remove, you can use the following

# List existing layers ids
existing_layers_ids = [layer.id() for layer in QgsProject.instance().mapLayers().values()]
# List existing layers paths
existing_layers_paths = [layer.dataProvider().dataSourceUri().split('|')[0] for layer in QgsProject.instance().mapLayers().values()]

# Imagining your layer path is "path_to_airports_layer"
if path_to_airports_layer in existing_layers_paths:
    id_to_remove = existing_layers_ids[existing_layers_paths.index(path_to_airports_layer)]
    QgsProject.instance().removeMapLayer(id_to_remove)

Limits are:

  • if you have two layers with the same path, it will remove both
  • the code is fine for simple shapefile but it's not enough in particular for GPKG as you need a path and a layer name or for other data sources like PostGIS

I've made the choice to not use layer name as the key but the data source path for removing layer as layer name can be renamed later. @stephen-poley approach based on layer name is also a good answer IMHO. Both approaches are fine: it depends of your use case.

Answered by ThomasG77 on February 9, 2021

Instead of removing layers you avoid adding them twice. Example:

import os

already_added = [lyr.source() for lyr in QgsProject.instance().mapLayers().values()]

rootfolder = '/home/bera/GIS/Data/testdata'
for root, folder, files in os.walk(rootfolder):
    for file in files:
        if file.endswith('.shp'):
            dataset = os.path.join(root, file)
            if dataset not in already_added: #If the source is not already added, add it
                lyr = QgsVectorLayer(dataset, os.path.splitext(file)[0], "ogr")
                QgsProject.instance().addMapLayer(lyr)

Answered by BERA on February 9, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP