Ottenere il layer per nome in PyQGIS?


14

Ho un plugin che trova buffer per l'elenco delle città, a condizione che la distanza. I nomi di stato e città sono presi dalla tabella degli attributi e vengono filtrati di conseguenza. Quello che voglio è Il mio plugin dovrebbe identificare il nome del livello o l'ordine del livello nell'area di disegno, indipendentemente dagli altri livelli presenti nell'area di disegno e accedere agli attributi corrispondenti da quel livello.

Sono anche solo curioso di sapere se puntare un nome di layer specifico nel codice provocherebbe un errore nell'iterazione sebbene siano presenti altri layer?

Di seguito è riportato il mio codice per favore dimmi dove dovrei apportare modifiche e quale sarebbe la modifica?

    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)

Risposte:


38

AGGIORNAMENTO: 10.04.2018

Utilizzando QGIS 3.x è possibile utilizzare il mapLayersByNamemetodo della QgsProjectclasse in questo modo:

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

Dal momento che è possibile avere più livelli in QGIS con lo stesso nome nel pannello dei livelli, il metodo sopra riportato fornisce un elenco di livelli corrispondenti.


Per QGIS 2.x :

Dovresti solo assicurarti che il tuo livello abbia un nome che puoi distinguere dagli altri. Invece di layer = self.iface.activeLayer(), fai:

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

Se non ti fidi del nome del livello (dopo tutto, può essere modificato dall'utente in qualsiasi momento), puoi provare a controllare l'origine del livello. Se il tuo livello è un file di forma, puoi controllare il percorso del file di forma, in questo modo:

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

EDIT: Come ha sottolineato @Jakob nei commenti, puoi scrivere il primo blocco in una riga:

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

O:

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

Ad ogni modo, dovrai verificare che layerListnon sia vuoto prima di accedere al suo primo elemento:

if layerList: 
    layer = layerList[0]

2
print [lyr per lyr in QgsMapLayerRegistry.instance (). mapLayers (). valori () se lyr.name () == "LAND"] [0] .name ()
Jakob,

7
layer = QgsMapLayerRegistry.instance (). mapLayersByName ("mylayername") [0]
Jakob,

perché stai impostando layer = noneall'inizio del tuo codice? Sembra inutile soprattutto se è in una funzione
user32882

1
È un valore predefinito, perché c'è un if all'interno di for. Se if non viene mai raggiunto, il layer non esiste affatto dopo il for. Quindi, solo per essere sicuro di poter leggere successivamente la variabile di livello.
Germán Carrillo,
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.