Obtenir une couche par nom dans PyQGIS?

14

J'ai un plugin qui trouve un tampon pour la liste des villes, à condition que la distance. Les noms d'état et de ville sont extraits de la table attributaire et filtrés en conséquence. Ce que je veux, c'est que mon plug-in identifie le nom ou l'ordre du calque dans le canevas, quels que soient les autres calques présents dans le canevas, et accède aux attributs correspondants à partir de ce calque.

Je suis également curieux de savoir si le fait de pointer un nom de couche spécifique dans le code entraînerait une erreur d'itération bien que d'autres couches soient présentes?

Ci-dessous mon code s'il vous plaît dites-moi où dois-je apporter des modifications et quel serait le changement?

    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
la source

Réponses:

39

MISE À JOUR: 10.04.2018

En utilisant QGIS 3.x, vous pouvez utiliser la mapLayersByNameméthode de QgsProjectclasse de cette manière:

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

Étant donné que vous pouvez avoir plusieurs couches dans QGIS avec le même nom dans le panneau des couches, la méthode ci-dessus vous donne une liste des couches correspondantes.


Pour QGIS 2.x :

Il vous suffit de vous assurer que votre calque porte un nom que vous pouvez distinguer des autres. Au lieu de layer = self.iface.activeLayer(), faites:

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

Si vous ne faites pas confiance au nom du calque (après tout, il peut être modifié par l'utilisateur à tout moment), vous pouvez essayer de vérifier la source du calque. Si votre calque est un fichier de formes, vous pouvez vérifier le chemin d'accès au fichier de formes, de cette façon:

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

EDIT: Comme @Jakob l'a souligné dans les commentaires, vous pouvez écrire le premier bloc sur une seule ligne:

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

Ou:

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

Quoi qu'il en soit, vous devrez vérifier qu'il layerListn'est pas vide avant d'accéder à son premier élément:

if layerList: 
    layer = layerList[0]
Germán Carrillo
la source
2
print [lyr pour lyr dans QgsMapLayerRegistry.instance (). mapLayers (). values ​​() si lyr.name () == "LAND"] [0] .name ()
Jakob
7
layer = QgsMapLayerRegistry.instance (). mapLayersByName ("mylayername") [0]
Jakob
pourquoi définissez-vous layer = noneau début de votre code? Cela semble inutile surtout si c'est dans une fonction
user32882
1
C'est une valeur par défaut, car il y a un if à l'intérieur du for. Si le if n'est jamais rencontré, le calque n'existera pas du tout après le for. Donc, juste pour vous assurer que vous pouvez lire la variable de couche par la suite.
Germán Carrillo