Suite

Comment créer un Atlas basé sur des attributs de points ?

Comment créer un Atlas basé sur des attributs de points ?


Essentiellement, je souhaite produire un atlas basé sur un champ catégoriel dans une couche de points.

c'est-à-dire que j'ai une couche ponctuelle de prestataires de services de garde avec le champ catégoriel « Provision ». J'ai classé chaque fonctionnalité de ce champ avec "After School Club", "Breakfast Club", etc., et je souhaite maintenant produire un ensemble de cartes qui parcourent chaque catégorie et n'affichent que les points pour chacune. Une carte des clubs parascolaires, une carte des clubs de petit-déjeuner, etc. Les étendues peuvent être légèrement différentes.

Je pourrais le faire un par un, mais il semble qu'il devrait y avoir un moyen de produire un atlas basé sur l'étendue de chaque catégorie ? (J'ai l'impression qu'il me manque quelque chose d'évident :) )

Ou bien existe-t-il un moyen d'automatiser la création d'une couche de polygones et de l'utiliser comme couverture cachée pour l'atlas ?

EDIT : j'ai fait un peu de progrès avec cela - vous pouvez utiliser un style basé sur des règles pour activer et désactiver les fonctionnalités pertinentes pour la fonctionnalité de couverture de l'atlas actuelle. cela fonctionne bien si tout ce que vous voulez faire est d'afficher un ensemble de points différent. Je cherche maintenant à lier cela à un schéma de couleurs et à une légende réactive.


J'ai finalement résolu ce problème pour mes besoins, alors voici la solution que j'ai trouvée si cela peut aider quelqu'un :

Ecrivez un script python (le mien à la fin) qui fait essentiellement ceci :

  1. identifier les catégories uniques dans le champ d'intérêt de la couche de points
  2. pour chaque catégorie, sélectionner tous les points correspondants et établir l'étendue de cet ensemble
  3. pour chaque étendue, générer un nouveau polygone dans une couche de couverture d'atlas vierge avec un attribut clé "CategoryName"

Cela m'a donné la couche de couverture de l'atlas avec un polygone pour chaque catégorie d'intérêt ressemblant à ceci :

Configurez l'atlas et le composeur d'impression comme d'habitude - ne laissant que le problème de l'activation et de la désactivation des fonctionnalités.

Pour cela, il faut un peu d'essais et d'erreurs pour déterminer l'ensemble exact d'options :

  1. L'expression ci-dessous vous permet d'obtenir la valeur actuellement contenue dans le champ CategoryName pour l'entité actuelle de l'atlas

    attribut ($atlasfeature, 'CategoryName')
  2. Utilisez ceci pour créer un style basé sur des règles pour la couche de points le long des lignes de

    attribut ($atlasfeature, 'CategoryName') = PointCategory AND PointCategory = "RedDots"
  3. J'avais aussi une règle pour garantir que tous les autres deviennent transparents

    l'attribut ($atlasfeature, 'CategoryName') N'EST PAS PointCategory

Tester cela avec l'atlas fonctionne très bien. Enfin, utilisez simplement la même approche pour manipuler les étiquettes affichées, rendre les étiquettes dynamiques et filtrer les tables de manière appropriée. Cocher la case "filtrer la légende par contenu de la carte" est également très efficace si vous ne voulez pas que tous les éléments de la légende soient sur toutes les cartes.

Ensemble de l'atlas final :

Edit - comme cela a été demandé, voici mon script :

à partir de l'importation PyQt4.QtCore * #script principal----------------------------------------- ----- #configurez les références de couche - vous devrez changer cette targetlayer=QgsMapLayerRegistry.instance().mapLayer("AtlasExtents20150727154732521") eylayer = QgsMapLayerRegistry.instance().mapLayer("Early_Years_Providers20150727152919862") #établir l'unique categories names = getUniqueAttributes(eylayer, 'Mapping_La') #obtenir un ensemble de boîtes boxset = getBoundings(eylayer, names) #assurez-vous que la couche est vidée, puis ajoutez des cadres de délimitation deleteBoxes(targetlayer) createBoxes(targetlayer, boxset) #end main script- ---------------------------------------------- #---- --functions-------# # obtient un ensemble unique d'attributs - renvoie un ensemble () def getUniqueAttributes (couche, nom de champ) : values ​​= set () pour la fonctionnalité dans layer.getFeatures () : values.add(feature [fieldname]) renvoie des valeurs #sélectionne rapidement tous les points sur une couche, étant donné une requête def selectionQuick(layer, queryitem): layer.removeSelection () #nom de champ codé en dur expr = QgsEx pression( ""Mapping_La" = '" + queryitem +"'") it = layer.getFeatures( QgsFeatureRequest( expr ) ) ids = [i.id() for i in it] layer.setSelectedFeatures( ids ) #for un ensemble d'éléments uniques, obtenez des cadres de délimitation def getBoundings(layer, itemset): bboxes = {} pour le nom de l'élément dans l'ensemble d'éléments : selectionQuick(layer,itemname) box = layer.boundingBoxOfSelected() bboxes[itemname] = box return bboxes #for a layer crée un tas de boîtes def createBoxes(layer, boxes) : id=0 pour boxkey dans les boîtes : id = id +1 box=boxes[boxkey] feat = QgsFeature(layer.pendingFields()) geom = QgsGeometry.fromRect(box ) feat.setAttribute('id', id) #nom de champ codé en dur feat.setAttribute('CareType', boxkey) feat.setGeometry(geom) (res, outFeats) = layer.dataProvider().addFeatures([feat]) def deleteBoxes(layer): ids = [f.id() pour f dans layer.getFeatures()] layer.dataProvider().deleteFeatures( ids )