Iterando sobre camadas de mapa no QGIS Python?

30

Estou tendo problemas para descobrir como iterar sobre as camadas do mapa. Posso acessar a camada atualmente destacada no sumário via iface.activeLayer()mas quero que meu código funcione em todas as camadas.

Não vejo nada na API que ofereça acesso fácil a essa funcionalidade e não consegui encontrar um bom exemplo on-line, mas talvez eu tenha perdido alguma coisa?

spencerrecneps
fonte
Não vejo como vocês estão usando QgsMapLayerRegistry ou QgsProject. No QGIS 3.0.2, isso não funciona. No entanto, iface.mapCanvas (). Layers () faz. Bem, tipo isso. Parece apenas fornecer as camadas ativas (as que você verificou no painel Camadas). Alguém sabe como obter uma lista de todas as camadas, mesmo as desmarcadas no painel Camadas? Além disso, se você usar o Plugin Builder, ele criará o shell do seu plugin para você. A função de execução possui um parâmetro "self", necessário para usar o iface. ie self.iface.mapCanvas (). layers (), apenas para sua informação.
11388 Ajpieri

Respostas:

24

Experimentar...

# 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

Selecionado de consolidatethread.py do plug-in QConsolidate .

Descrição do objeto QgsLegendInterface retornado de legendInterface ().

Edit : informações adicionadas sobre 'self' acima.

dakcarto
fonte
Obrigado! Isso fez o truque. Acho que estou muito acostumado ao mundo da ESRI, onde a legenda é o objeto no layout do mapa e o índice refere-se à lista de camadas.
Spencerrecneps
2
Observe que há uma diferença no que é retornado entre isso e a técnica mapCanvas () que Nathan menciona. O objeto legendInterface () retornará todas as camadas, mesmo que não sejam mostradas na tela do mapa, enquanto mapCanvas () retornará apenas as mostradas na tela. Usar mapCanvas () é uma maneira rápida e agradável de obter uma referência às camadas visíveis.
Dakcarto 27/05
11
Em outra nota, as versões mais recentes do QGIS (> = 1.8) permitem ao usuário definir uma ordem de renderização de camadas separadamente da ordem listada na legenda (muito bom!). Os métodos legendInterface () e mapCanvas () retornam a ordem das camadas para cada um, respectivamente.
Dakcarto 27/05
19

Existem também outras duas maneiras:

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

lhe dará uma lista de camadas

ou

layers = QgsMapLayerRegistry.instance().mapLayers()

for name, layer in layers.iteritems():
     print name, layer.type()
Nathan W
fonte
Esta resposta parece não funcionar em 2.16e acima de
raphael
10

Para o QGIS 2.6, aqui está o código para identificar cada camada e agrupá-las:

#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: Após o agrupamento, tenho que remover a camada duplicada, então usei root.removeLayer(lyr).

Abhijit Gujar
fonte
9

Para o QGIS 3, QgsMapLayerRegistrya funcionalidade do foi movida para QgsProject.

Portanto, para iterar sobre as camadas do mapa, você deve usar essa estrutura:

layers = QgsProject.instance().mapLayers()

.mapLayers()retorna um dicionário estruturado como {layer_x_id: layer_x, layer_y_id: layer_y, ....}. Em seguida, você pode iterar sobre camadas como:

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

Como .mapLayers()retorna um dicionário ( dict), você também pode usar o .values()método do dicionário, que retorna apenas um listque contém camadas nesse caso. Em seguida, você pode iterar sobre camadas como:

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

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

Se preferir, você pode iterar desta maneira:

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

for layer in layers.values():
    print(layer.name())
Kadir Şahbaz
fonte
Oi! Obrigado por compartilhar. Imprimir os nomes das camadas funciona bem ... mas não consigo imprimir as teclas do dicionário. Você pode me ajudar com isso?
caio villaca 18/06
11
for layer in layers: print(layer)Você pode usar o script para imprimir as chaves. Ou apenas use print(layers.keys())sem forloop.
Kadir Şahbaz 18/06