W końcu rozwiązałem to dla moich celów, więc oto rozwiązanie, które wymyśliłem, jeśli pomaga komukolwiek:
Napisz skrypt Pythona (mój na końcu tego), który zasadniczo robi to:
- zidentyfikować unikalne kategorie w polu zainteresowania warstwy punktowej
- dla każdej kategorii wybierz wszystkie pasujące punkty i ustal zasięg tego zestawu
- dla każdego zakresu wygeneruj nowy wielokąt w warstwie pokrycia pustego atlasu z kluczowym atrybutem „CategoryName”
To dało mi warstwę pokrycia atlasu z jednym wielokątem dla każdej kategorii zainteresowań wyglądającej tak:
Skonfiguruj atlas i drukuj kompozytora jak zwykle - pozostawiając jedynie problem z wyłączaniem i włączaniem funkcji.
W tym celu jest trochę prób i błędów, aby opracować dokładny zestaw opcji:
Poniższe wyrażenie pozwala uzyskać wartość aktualnie przechowywaną w polu CategoryName dla bieżącej funkcji atlasu
attribute ($atlasfeature, 'CategoryName')
Służy do tworzenia stylów opartych na regułach dla warstwy punktowej wzdłuż linii
attribute ($atlasfeature, 'CategoryName') = PointCategory AND PointCategory = "RedDots"
Miałem również zasadę gwarantującą, że wszystkie pozostałe stały się przejrzyste
attribute ($atlasfeature, 'CategoryName') IS NOT PointCategory
Testowanie tego za pomocą atlasu działa naprawdę dobrze. Na koniec zastosuj to samo podejście, aby manipulować wyświetlanymi etykietami, spraw, aby etykiety były dynamiczne i odpowiednio filtruj tabele. Zaznaczenie „filtruj legendę według zawartości mapy” jest również bardzo skuteczne, jeśli nie chcesz wszystkich elementów legendy na wszystkich mapach.
Ostateczny zestaw atlasów:
Edytuj - zgodnie z prośbą, oto mój skrypt:
from PyQt4.QtCore import *
#main script----------------------------------------------
#set up the layer references - you will need to change this
targetlayer=QgsMapLayerRegistry.instance().mapLayer("AtlasExtents20150727154732521")
eylayer = QgsMapLayerRegistry.instance().mapLayer("Early_Years_Providers20150727152919862")
#establish the unique categories
names = getUniqueAttributes(eylayer, 'Mapping_La')
#get a set of boxes
boxset = getBoundings(eylayer, names)
#ensure layer is emptied, then add bounding boxes
deleteBoxes(targetlayer)
createBoxes(targetlayer, boxset)
#end main script----------------------------------------------
#------functions-------#
#gets unique set of attributes - returns a set()
def getUniqueAttributes(layer, fieldname):
values = set()
for feature in layer.getFeatures():
values.add(feature[fieldname])
return values
#quickly selects all points on a layer, given a query
def selectionQuick(layer, queryitem):
layer.removeSelection ()
#hardcoded field name
expr = QgsExpression( "\"Mapping_La\" = '" + queryitem +"'")
it = layer.getFeatures( QgsFeatureRequest( expr ) )
ids = [i.id() for i in it]
layer.setSelectedFeatures( ids )
#for a set of unique items, get bounding boxes
def getBoundings(layer, itemset):
bboxes = {}
for itemname in itemset:
selectionQuick(layer,itemname)
box = layer.boundingBoxOfSelected()
bboxes[itemname] = box
return bboxes
#for a layer create a bunch of boxes
def createBoxes(layer, boxes):
id=0
for boxkey in boxes:
id = id +1
box=boxes[boxkey]
feat = QgsFeature(layer.pendingFields())
geom = QgsGeometry.fromRect(box)
feat.setAttribute('id', id)
#hardcoded field name
feat.setAttribute('CareType', boxkey)
feat.setGeometry(geom)
(res, outFeats) = layer.dataProvider().addFeatures([feat])
def deleteBoxes(layer):
ids = [f.id() for f in layer.getFeatures()]
layer.dataProvider().deleteFeatures( ids )