Iterazione sui livelli delle mappe in QGIS Python?


30

Ho problemi a capire come scorrere i livelli della mappa. Posso accedere al livello attualmente evidenziato nel sommario tramite iface.activeLayer()ma voglio che il mio codice funzioni su tutti i livelli.

Non vedo nulla nell'API che fornisce un facile accesso a questa funzionalità e non sono riuscito a trovare un buon esempio online, ma forse ho perso qualcosa?


Non vedo come state usando QgsMapLayerRegistry o QgsProject. In QGIS 3.0.2 questo non funziona. Tuttavia, iface.mapCanvas (). Layers () lo fa. Bene, un po '. Sembra solo darti i livelli attivi (quelli che hai controllato nel riquadro Livelli). Qualcuno sa come ottenere un elenco di tutti i livelli, anche quelli non selezionati nel riquadro Livelli? Inoltre, se si utilizza Plugin Builder, crea la shell del plugin per te. La funzione di esecuzione ha un parametro "self", necessario per utilizzare iface. cioè self.iface.mapCanvas (). layers (), solo fyi.
ajpieri,

Risposte:


24

Provare...

# substitute 'self' with 'qgis.utils.iface' when run from Python console
# 'self.iface = iface' would usually precede this command in your class 
layers = self.iface.legendInterface().layers()

for layer in layers:
    layerType = layer.type()
    if layerType == QgsMapLayer.VectorLayer:
        # do some stuff here

Cullato da consolidatethread.py dal plugin QConsolidate .

Descrizione dell'oggetto QgsLegendInterface restituita da legendInterface ().

Modifica : aggiunte informazioni su 'self' sopra.


Grazie! Questo ha funzionato. Immagino di essere troppo abituato al mondo ESRI in cui la legenda è l'oggetto nel layout della mappa e il sommario si riferisce all'elenco dei livelli.
spencerrecneps,

2
Nota che c'è una differenza tra ciò che viene restituito tra questa e la tecnica mapCanvas () menzionata da Nathan. L'oggetto legendInterface () restituirà tutti i livelli, anche se non sono mostrati nell'area di disegno della mappa, mentre mapCanvas () restituisce solo quelli mostrati nell'area di disegno. L'uso di mapCanvas () è un modo semplice e veloce per ottenere un riferimento ai livelli visibili.
dakcarto,

1
In un'altra nota, le ultime versioni di QGIS (> = 1.8) consentono all'utente di definire un ordine di rendering dei livelli separatamente dall'ordine elencato nella legenda (molto bello!). I metodi legendInterface () e mapCanvas () restituiscono rispettivamente l'ordine dei layer per ciascuno.
dakcarto,

19

Esistono anche altri due modi:

layers = self.iface.mapCanvas().layers()

ti darà un elenco di livelli

o

layers = QgsMapLayerRegistry.instance().mapLayers()

for name, layer in layers.iteritems():
     print name, layer.type()

Questa risposta non sembra funzionare dentro 2.16e sopra
Raffaello,

10

Per QGIS 2.6 ecco il codice per identificare ogni livello e raggrupparli:

#make the desired groups for layers
toc = self.iface.legendInterface()
root = QgsProject.instance().layerTreeRoot()
group1 = root.insertGroup(0, "Group Point")
group2 = root.insertGroup(1, "Group Line")
group3 = root.insertGroup(2, "Group Polygon")
#get the list of layers  from registry
layers = QgsMapLayerRegistry.instance().mapLayers()
#segregate layers into groups 
for name, layer in layers.iteritems():
    # check the layer geometry type 
    if layer.geometryType() == QGis.Point:
        toc.moveLayer(layer, 0)

    if layer.geometryType() == QGis.Line:
        toc.moveLayer(layer, 1)

    if layer.geometryType() == QGis.Polygon:
        toc.moveLayer(layer, 2)

Nota: dopo il raggruppamento devo rimuovere il livello duplicato così ho usato root.removeLayer(lyr).


9

Per QGIS 3, QgsMapLayerRegistryla funzionalità di è stata spostata in QgsProject.

Quindi, per iterare sui livelli della mappa, dovresti usare quella struttura:

layers = QgsProject.instance().mapLayers()

.mapLayers()restituisce un dizionario strutturato come {layer_x_id: layer_x, layer_y_id: layer_y, ....}. Quindi puoi iterare su livelli come:

for layer_id, layer in layers.items():
    print(layer.name())

Poiché .mapLayers()restituisce un dizionario ( dict), è anche possibile utilizzare il .values()metodo del dizionario che restituisce solo un file listcontenente livelli in quel caso. Quindi puoi iterare su livelli come:

layers = QgsProject.instance().mapLayers().values()

for layer in layers:
    print(layer.name())

Se preferisci, puoi iterare in questo modo:

layers = QgsProject.instance().mapLayers() # dictionary

for layer in layers.values():
    print(layer.name())

Ciao! Grazie per averlo condiviso. Per stampare i nomi dei livelli funziona benissimo ... ma non riesco a stampare le chiavi del dizionario. Potete aiutarmi con quello?
Caio Villaca,

1
for layer in layers: print(layer)È possibile utilizzare lo script per stampare le chiavi. O semplicemente usa print(layers.keys())senza forloop.
Kadir Şahbaz il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.