Layer nach Namen in PyQGIS bekommen?

14

Ich habe ein Plugin, das Puffer für die Liste der Städte findet, sofern die Entfernung angegeben ist. Die Namen der Bundesstaaten und Städte werden aus der Attributtabelle übernommen und entsprechend gefiltert. Ich möchte, dass mein Plugin den Ebenennamen oder die Reihenfolge der Ebene in der Zeichenfläche unabhängig von den anderen in der Zeichenfläche vorhandenen Ebenen identifiziert und über diese Ebene auf die entsprechenden Attribute zugreift.

Ich bin auch nur neugierig, ob das Zeigen eines bestimmten Ebenennamens im Code einen Fehler bei der Iteration verursachen würde, obwohl einige andere Ebenen vorhanden sind.

Unten ist mein Code, bitte sagen Sie mir, wo ich Änderungen vornehmen soll und was die Änderung sein würde.

    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)
User123
quelle

Antworten:

38

UPDATE: 10.04.2018

Mit QGIS 3.x können Sie die mapLayersByNameMethode from QgsProjectclass folgendermaßen verwenden:

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

Da Sie im Ebenenbedienfeld mehrere Ebenen in QGIS mit demselben Namen haben können, erhalten Sie mit der obigen Methode eine Liste der übereinstimmenden Ebenen.


Für QGIS 2.x :

Sie müssen lediglich sicherstellen, dass Ihre Ebene einen Namen hat, den Sie von anderen unterscheiden können. Stattdessen layer = self.iface.activeLayer()machen Sie:

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

Wenn Sie dem Ebenennamen nicht vertrauen (er kann schließlich jederzeit vom Benutzer geändert werden), können Sie versuchen, die Ebenenquelle zu überprüfen. Wenn Ihre Ebene ein Shapefile ist, können Sie den Pfad zum Shapefile folgendermaßen überprüfen:

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

BEARBEITEN: Wie @Jakob in Kommentaren ausgeführt hat, können Sie den ersten Block in eine Zeile schreiben:

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

Oder:

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

Auf jeden Fall müssen Sie überprüfen, ob das layerListFeld nicht leer ist, bevor Sie auf das erste Element zugreifen können:

if layerList: 
    layer = layerList[0]
Germán Carrillo
quelle
2
print [lyr für lyr in QgsMapLayerRegistry.instance (). mapLayers (). values ​​() if lyr.name () == "LAND"] [0] .name ()
Jakob
7
layer = QgsMapLayerRegistry.instance (). mapLayersByName ("mylayername") [0]
Jakob
Warum setzen Sie layer = noneam Anfang Ihres Codes? Es scheint unnötig, vor allem, wenn es in einer Funktion ist
user32882
1
Es ist ein Standardwert, da es ein if innerhalb des for gibt. Wenn das if nie erfüllt wird, wird der Layer nach dem for überhaupt nicht existieren. Nur um sicherzustellen, dass Sie die Ebenenvariable anschließend lesen können.
Germán Carrillo