Suite

Utilisation de chaque caractéristique de la couche vectorielle comme masque de découpage sur une couche de points distincte, stockage des résultats dans une liste Python ou une couche de travail en mémoire


J'ai un calque de points (représentant des villes) et un ensemble de calques vectoriels dont les caractéristiques sont des centaines de disques concentriques, chacun d'eux que j'aimerais utiliser comme calque de découpage pour sélectionner uniquement les villes qui se trouvent dans ce disque, effectuez quelques opérations sur ces villes, puis passez au disque suivant.

Voici quelques captures d'écran du projet. Les disques bleu-gris concentriques sont les polygones de découpage - des tampons de 25/50/100/150 milles autour des emplacements des bases militaires (représentés par des losanges verts). Les points rouges sont les caractéristiques de la ville (affichées en tailles graduées par taux de criminalité violente) que j'essaie d'utiliser comme couche d'entrée :

J'essayais d'utiliser QGISEn traitementmodule pour le faire. Cependant, toute la documentation que j'ai pu trouver sur leqgis:clipLa fonction affiche sa sortie dans un fichier de formes. Par exemple, les réponses à la question Existe-t-il un moyen d'appeler la fonction clip dans pyQGIS à partir de la console python ? suggérer:

processing.runalg("qgis:clip",inputlayer,overlaylayer,"output_file.shp") processing.runandload("qgis:clip",inputlayer,overlaylayer,"output_file.shp")

Ce que je veux faire à la place, c'est parcourir tous les disques de la ou des couches d'écrêtage et enregistrer les résultats de l'utilisation de chacun dans un fichier temporaire. en mémoire couche vectorielle au lieu d'un fichier de formes.

Voici le code (non fonctionnel) que j'ai essayé d'écrire pour ce faire :

pour le disque dans les troopBuffers : # Le découpage nécessite que la couche villes et le disque tampon des troupes soient tous les deux sélectionnés buffLayer.select(disc.id()) cityLayer.selectAll() clipLayer = QgsVectorLayer("Point", "temporary_points", "memory:tmpClipLayer ") QgsMapLayerRegistry.instance().addMapLayer(clipLayer) processing.runandload("qgis:clip", cityLayer, disc, clipLayer) clippedCities = [f pour f dans clipLayer.getFeatures()] pour c dans clippedCities : # faire quelque chose avec chaque ville qui se trouve dans ce disque… buffLayer.removeSelection() QgsMapLayerRegistry.instance().removeMapLayer(clipLayer.id())

… cependant, quand je lance ceciVilles coupéessemble toujours être vide, donc quelque chose ne va manifestement pas.

Comment couper comme ça sans créer de fichiers de formes sur le disque pour chaque itération ?

Puis-je simplement avoirEn traitementafficher les résultats de chaque clip dans une "couche de travail" en mémoire ou (encore mieux) obtenir simplement une liste deFonctionnalité Qgsobjets de la couche villes pour chaque disque ?

Ou vais-je devoir utiliser autre chose en plusEn traitementici?


Lorsque j'ai bien compris votre question, vous souhaitez traiter les villes se trouvant à l'intérieur d'un polygone en tant que groupe et les manipuler d'une manière ou d'une autre, sans produire un certain nombre de fichiers à la suite d'un processus.

Mes suggestions :

Lorsque chaque ville doit être manipulée par rapport au polygone dans lequel elle se trouve, utilisez un code comme celui-ci :

buff_layer = QgsMapLayerRegistry.instance().mapLayersByName('buffLayer')[0] city_layer = QgsMapLayerRegistry.instance().mapLayersByName('cityLayer')[0] # passer en mode édition city_layer.startEditing() # par exemple obtenir l'index d'un champ à manipuler fni = city.fieldNameIndex('name') # boucle sur les polygones pour buff dans buff_layer.getFeatures() : pour la ville dans city_layer.getFeatures() : si buff.geometry().contains(city.geometry()) : # faire quelque chose avec une seule ville # accès à buff[attribute] city_layer.changeAttributeValue(city.id(), fni, buff['name']) city_layer.commitChanges()

Dans l'exemple ci-dessus chaque ville reçoit dans son domaineNomlesNomdu polygone dans lequel il se trouve.

Lorsque vous avez besoin d'accéder à toutes les villes de chaque polygone, vous pouvez utiliser un code comme celui-ci :

buff_layer = QgsMapLayerRegistry.instance().mapLayersByName('buffLayer')[0] city_layer = QgsMapLayerRegistry.instance().mapLayersByName('cityLayer')[0] # boucle sur les polygones pour buff dans buff_layer.getFeatures() : selection = [ ] pour la ville dans city_layer.getFeatures() : si buff.geometry().contains(city.geometry()): selection.append(city.id()) # sélectionner toutes les villes dans un seul tampon city_layer.setSelectedFeatures(selection) # faire quelque chose avec les villes sélectionnées

Dans ce dernier cas, sachez que vous ne pouvez pas appeler des fonctions en dehors de ce script à plusieurs reprises, car il s'exécute dans le même thread que Qgis lui-même. L'application attend donc la fin du script avant de démarrer autre chose. Lectures supplémentaires : sélectionnez une fonctionnalité qui ne fonctionne pas dans pyQGIS ? et Comment puis-je empêcher Qgis d'être détecté comme "ne répondant pas" lors de l'exécution d'un plugin lourd ?


Voir la vidéo: #QGIS#:Passer dun système de coordonnées à un autre (Octobre 2021).