Obtendo a camada pelo nome no PyQGIS?

14

Eu tenho um plugin que encontra buffer para lista de cidades, desde a distância. Os nomes de estado e cidade são obtidos da tabela de atributos e são filtrados de acordo. O que eu quero é que Meu plugin identifique o nome ou a ordem da camada na tela, independentemente de outras camadas presentes na tela e acesse os atributos correspondentes dessa camada.

Também estou curioso para saber se apontar um nome de camada específico no código causaria algum erro na iteração, embora algumas outras camadas estejam presentes?

Abaixo está o meu código, por favor me diga onde devo fazer alterações e qual seria a alteração?

    if dist and centerCity:
        #QMessageBox.information(self.dlg, "info", "both True")
        st = '"name" = \'' + centerCity + '\''
        exp = QgsExpression(st)
    else:
        QMessageBox.warning(self.dlg, "Enter the distance","Enter the distance and try again.")        
        return          #terminate the function

    layer = self.iface.activeLayer() 
    it = layer.getFeatures(QgsFeatureRequest(exp))
    feature = it.next()
    mbuf = feature.geometry().buffer(dist, 2)       

    iterFeat = layer.getFeatures()

    for f in iterFeat:
        geom2 = f.geometry()
        valTest = QgsGeometry.within(geom2, mbuf)
Usuário123
fonte

Respostas:

38

ATUALIZAÇÃO: 10.04.2018

Usando o QGIS 3.x, você pode usar o mapLayersByNamemétodo da QgsProjectclasse desta maneira:

layers = QgsProject.instance().mapLayersByName('my layer name')

Como você pode ter várias camadas no QGIS com o mesmo nome no painel de camadas, o método acima fornece uma lista de camadas correspondentes.


Para o QGIS 2.x :

Você só precisa garantir que sua camada tenha um nome que você possa distinguir das outras. Em vez de layer = self.iface.activeLayer(), faça:

layer=None
for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.name() == "YOUR_LAYER_NAME":
        layer = lyr
        break

Se você não confia no nome da camada (afinal, ele pode ser alterado pelo usuário a qualquer momento), tente verificar a origem da camada. Se sua camada for um Shapefile, você poderá verificar o caminho para o Shapefile, desta maneira:

layer=None
for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.source() == "/path/to/shapefile.shp":
        layer = lyr
        break

EDIT: Como @Jakob apontou nos comentários, você pode escrever o primeiro bloco em uma linha:

layerList = QgsMapLayerRegistry.instance().mapLayersByName("YOUR_LAYER_NAME")

Ou:

layerList = [lyr for lyr in QgsMapLayerRegistry.instance().mapLayers().values() if lyr.name() == "YOUR_LAYER_NAME"]

De qualquer forma, você precisaria verificar layerListse não está vazio antes de acessar seu primeiro elemento:

if layerList: 
    layer = layerList[0]
Germán Carrillo
fonte
2
print [lyr para lyr em QgsMapLayerRegistry.instance (). mapLayers (). values ​​() if lyr.name () == "LAND"] [0] .name ()
Jakob
7
camada = QgsMapLayerRegistry.instance (). mapLayersByName ("mylayername") [0]
Jakob
por que você está definindo layer = noneno início do seu código? Parece desnecessário, especialmente se o seu em uma função
user32882
1
É um valor padrão, porque existe um if dentro do for. Se o if nunca for atendido, a camada não existirá depois do for. Portanto, apenas para garantir que você possa ler a variável de camada posteriormente.
Germán Carrillo