Uzyskiwanie warstwy według nazwy w PyQGIS?

15

Mam wtyczkę, która wyszukuje bufor dla listy miast, pod warunkiem odległości. Nazwy stanów i miast są pobierane z tabeli atrybutów i są odpowiednio filtrowane. To, czego chcę, to Moja wtyczka powinna identyfikować nazwę warstwy lub kolejność warstwy w obszarze roboczym, niezależnie od innych warstw obecnych w obszarze roboczym i uzyskiwać dostęp do odpowiednich atrybutów z tej warstwy.

Jestem również ciekawy, czy wskazanie konkretnej nazwy warstwy w kodzie spowoduje błąd w iteracji, mimo że istnieją inne warstwy?

Poniżej znajduje się mój kod, proszę powiedzieć, gdzie powinienem wprowadzić zmiany i jaka byłaby zmiana?

    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)
Użytkownik123
źródło

Odpowiedzi:

41

AKTUALIZACJA: 10.04.2018

Korzystając z QGIS 3.x , możesz użyć mapLayersByNamemetody z QgsProjectklasy w następujący sposób:

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

Ponieważ możesz mieć kilka warstw w QGIS o tej samej nazwie w panelu warstw, powyższa metoda daje listę pasujących warstw.


W przypadku QGIS 2.x :

Musisz tylko upewnić się, że twoja warstwa ma nazwę, którą możesz odróżnić od innych. Zamiast layer = self.iface.activeLayer():

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

Jeśli nie ufasz nazwie warstwy (w końcu użytkownik może ją zmienić w dowolnym momencie), możesz spróbować sprawdzić źródło warstwy. Jeśli twoja warstwa jest Shapefile, możesz sprawdzić ścieżkę do Shapefile, w ten sposób:

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

EDYCJA: Jak zauważył @Jakob w komentarzach, możesz napisać pierwszy blok w jednym wierszu:

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

Lub:

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

W każdym razie layerListprzed uzyskaniem dostępu do pierwszego elementu należy sprawdzić, czy nie jest pusty:

if layerList: 
    layer = layerList[0]
Germán Carrillo
źródło
2
print [lyr dla lyr w QgsMapLayerRegistry.instance (). mapLayers (). values ​​() if lyr.name () == "LAND"] [0] .name ()
Jakob
7
layer = QgsMapLayerRegistry.instance (). mapLayersByName („moja_nazwa”) [0]
Jakob
dlaczego ustawiasz layer = nonena początku swojego kodu? Wydaje się niepotrzebne, zwłaszcza jeśli jest w funkcji
user32882
1
Jest to wartość domyślna, ponieważ wewnątrz for znajduje się if. Jeśli if nigdy nie zostanie spełniony, warstwa w ogóle nie będzie istnieć po for. Tak, aby upewnić się, że później można odczytać zmienną warstwy.
Germán Carrillo