1

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?

1
  • instead of printing the layer name, make a note of it's ID and then do a remove by id for each ID you noted – Ian Turton Aug 7 '20 at 15:01
2

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.

2

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)
1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.