¿Iterando sobre capas de mapa en QGIS Python?

30

Tengo problemas para descubrir cómo iterar sobre las capas del mapa. Puedo acceder a la capa resaltada actualmente en la tabla de contenido, iface.activeLayer()pero quiero que mi código funcione en todas las capas.

No veo nada en la API que proporcione fácil acceso a esta funcionalidad y no pude encontrar un buen ejemplo en línea, pero ¿tal vez me perdí algo?

spencerrecneps
fuente
No veo cómo están usando QgsMapLayerRegistry o QgsProject. En QGIS 3.0.2 esto no funciona. Sin embargo, iface.mapCanvas (). Layers () sí. Bueno, más o menos. Solo parece darle las capas activas (las que ha marcado en el panel Capas). ¿Alguien sabe cómo obtener una lista de todas las capas, incluso aquellas sin marcar en el panel de capas? Además, si usa Plugin Builder, crea el shell de su complemento para usted. La función de ejecución tiene un parámetro "self", que es necesario para usar iface. es decir, self.iface.mapCanvas (). layers (), solo para tu información.
ajpieri

Respuestas:

24

Tratar...

# 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

Seleccionado de consolidatethread.py del complemento QConsolidate .

Descripción del objeto QgsLegendInterface devuelto por legendInterface ().

Editar : se agregó información sobre 'self' arriba.

dakcarto
fuente
¡Gracias! Eso hizo el truco. Supongo que estoy demasiado acostumbrado al mundo de ESRI donde la leyenda es el objeto en el diseño del mapa y la tabla de contenido se refiere a la lista de capas.
spencerrecneps
2
Tenga en cuenta que hay una diferencia en lo que se devuelve entre esto y la técnica mapCanvas () que Nathan menciona. El objeto legendInterface () devolverá todas las capas, incluso si no se muestran en el lienzo del mapa, mientras que mapCanvas () devuelve solo las que se muestran en el lienzo. Usar mapCanvas () es una forma rápida y agradable de obtener una referencia a capas visibles.
dakcarto
1
En otra nota, las últimas versiones de QGIS (> = 1.8) permiten al usuario definir un orden de representación de las capas por separado del orden enumerado en la leyenda (¡muy bien!). Los métodos legendInterface () y mapCanvas () devuelven el orden de las capas para cada uno respectivamente.
dakcarto
19

También hay otras dos formas:

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

te dará una lista de capas

o

layers = QgsMapLayerRegistry.instance().mapLayers()

for name, layer in layers.iteritems():
     print name, layer.type()
Nathan W
fuente
Esta respuesta no parece funcionar en 2.16y más allá
raphael
10

Para QGIS 2.6 aquí está el código para identificar cada capa y agruparlas:

#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: Después de la agrupación, tengo que eliminar la capa duplicada, así que la usé root.removeLayer(lyr).

Abhijit Gujar
fuente
9

Para QGIS 3, QgsMapLayerRegistryla funcionalidad se ha movido a QgsProject.

Entonces, para iterar sobre las capas del mapa, debe usar esa estructura:

layers = QgsProject.instance().mapLayers()

.mapLayers()devuelve un diccionario estructurado como {layer_x_id: layer_x, layer_y_id: layer_y, ....}. Luego puede iterar sobre capas como:

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

Como .mapLayers()devuelve un diccionario ( dict), también puede usar el .values()método de diccionario que devuelve solo un listque contiene capas en ese caso. Luego puede iterar sobre capas como:

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

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

Si lo prefiere, puede iterar de esta manera:

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

for layer in layers.values():
    print(layer.name())
Kadir Şahbaz
fuente
¡Hola! Gracias por compartirlo. Para imprimir los nombres de las capas funciona bien ... pero no puedo imprimir las claves del diccionario. ¿Me puede ayudar con eso?
caio villaca
1
for layer in layers: print(layer)Puede usar el script para imprimir las claves. O simplemente usar print(layers.keys())sin forbucle.
Kadir Şahbaz