Suite

Activer la couche par son nom dans PyQGIS


J'écris un script qui nécessite que les attributs de différentes couches fonctionnent, et j'aimerais savoir comment appeler une couche qui n'est pas celle actuellement active et obtenir ses fonctionnalités.

Par exemple, j'ai trois calques, nommés "Pôles", "Lignes" et "Charges", et j'ai besoin d'obtenir toutes les caractéristiques des calques aveclayer.getFeatures()et enregistrez ces fonctionnalités dans une liste pour chaque couche. Pour une seule couche, nous faisons généralement ceci :

Si mon calque actif est "Pôles", j'écris :

layer = iface.activeLayer() pôles = layer.getFeatures()

Et puis je peux tout faire avec des "pôles", mais comment faire avec les autres calques qui ne sont pas actifs ? Si je voulais faire de même avec le calque "Lignes", je devrais l'activer "manuellement" en cliquant dessus, et en répétant ce code.

J'ai essayé avec cette méthode : Obtenir la couche par nom dans PyQGIS ?

Et celle-ci : Obtenir une couche qui n'est pas active avec PyQGIS

Mais je reçois toujours ce message d'erreur, car je n'active pas le calque, je ne fais que créer une liste de noms de calques.

Traceback (appel le plus récent en dernier) : Fichier "", ligne 1, dans  AttributeError : l'objet 'list' n'a pas d'attribut 'getFeatures'

Comment puis-je activer une couche par son nom pour y obtenir les fonctionnalités ?


TL;DR

Pour obtenir toutes les fonctionnalités d'une couche par le nom de la couche, vous n'avez pas besoin de l'activer. Utilisez simplement

name = 'counties' layer = QgsProject.instance().mapLayersByName( name )[0] poles = layer.getFeatures() for pole in poles: if is_north(pole): print('c'est le pôle nord')

Couche active

Tout d'abord, vous n'avez pas à vous soucier de la couche active. Le couche active est le calque qui est actuellement sélectionné dans l'arborescence des calques et est donc utile pour deux choses

  1. laisser l'utilisateur sélectionner une couche sur laquelle opérer
  2. sélection d'une couche pour tester rapidement le code à partir de la console python

Le second est pratique lorsque vous développez, le premier est ce sur quoi tous les maptools sont basés : le calque actuellement sélectionné (le actif un) est modifié, sélectionné, supprimé…

Méthodes pour accéder aux couches

Cependant, vous semblez vouloir accéder aux couches non pas en fonction des entrées de l'utilisateur mais en fonction d'autre chose.

Identification des couches

Toutes les couches ont

  • Une identifiant qui doit être unique
  • UNE Nom qui n'est pas nécessairement (mais souvent) unique et peut être modifié par l'utilisateur
  • UNE référence (aussi souvent appelé aiguille mais en python, les deux termes sont interchangeables) qui est unique et stable pour la durée de vie d'une couche pendant l'exécution de l'application et peut être affecté à une variable (par ex.vlayerest une référence au calque actuellement actif dans votre exemple).
  • Des propriétés comme le URI (nom de la table, etc.)

Si vous avez déjà une référence à la couche (parce que vous l'avez créée/ajoutée dans votre plugin), utilisez simplement celle-ci.

Si ce n'est pas le cas, réfléchissez à la propriété que vous souhaitez utiliser pour accéder à la couche. Très probablement quelque chose de stable (l'ID de couche est très stable pour la durée de vie d'un projet mais est toujours différent pour différents projets), le nom est réglable par l'utilisateur, le tableau peut dépendre de la source de données.

Accéder aux calques

Il existe le registre des couches de carte qui vous permet d'accéder aux couches. Il gère les références à toutes les couches. Auparavant, cela s'appelait QgsMapLayerRegistry, mais ce n'est plus disponible dans QGIS 3, donc QgsProject peut être utilisé à la place.

registre = QgsProject.instance()

Si vous avez l'identifiant de la couche avec

couche = registre.mapLayer( id )

Si vous avez le nom du calque

layer = registration.mapLayersByName( name )[0] # La méthode renvoie une liste car elle peut être ambiguë, 0 sélectionne la première entrée de la liste

Si vous avez autre chose, vous devez écrire votre propre code :

pour lyr dans register.mapLayers().values() : si lyr.dataProvider().dataSourceUri().table() == 'mytable' : layer = lyr break

Ou un raccourci qui fait la même chose et vous fait vous sentir plus hacker mais fera que les personnes qui devront maintenir le code plus tard coûteront un peu plus de temps à déchiffrer :

layer = (l pour l dans registration.mapLayers().values() si l.dataProvider().dataSourceUri().table() == 'mytable').next()

Ce n'est pas complètement par nom mais, vous pouvez également utiliser QgsMapCanvas objets. Code suivant :

mapcanvas = iface.mapCanvas() n = mapcanvas.layerCount() couches = [mapcanvas.layer(i) for i in range(n)] layer_names = [ layer.name() pour la couche dans les couches ] #vraiment les noms des couches vectorielles print "layers_names = ", layer_names poles = [ pole for pole in layers[0].getFeatures() ] #testing only one feature if poles[0].geometry().type() == QGis.Point: print "It's un calque de points" lines = [ ligne pour la ligne dans les calques[1].getFeatures() ] #tester une seule entité si lines[0].geometry().type() == QGis.Line: print "C'est un calque de lignes "

il a été utilisé avec ces couches vectorielles à l'image suivante :

Lorsque le code a été exécuté sur la console Python, le résultat était :

layer_names = [u'random_points', u'line'] C'est un calque de points C'est un calque de lignes

Si vous inversez l'ordre des couches dans la légende de la carte, seule cette liste est imprimée :

layer_names = [u'line', u'random_points']


Voir la vidéo: Basic QGIS Tutorial - Open some Shapefile layers and a Project (Octobre 2021).