Finalmente resolvi isso para meus propósitos, então aqui está a solução que encontrei, se isso ajuda alguém:
Escreva um script python (o meu no final disso) que essencialmente faz isso:
- identifique as categorias exclusivas no campo de interesse da camada de pontos
- para cada categoria, selecione todos os pontos correspondentes e estabeleça a extensão desse conjunto
- para cada extensão, gere um novo polígono em uma camada de cobertura de atlas em branco com um atributo-chave "CategoryName"
Isso me deu a camada de cobertura do atlas com um polígono para cada categoria de interesse parecida com esta:
Configure o atlas e o compositor de impressão normalmente, deixando apenas a questão de desativar e ativar os recursos.
Para isso, é necessário um pouco de tentativa e erro para definir o conjunto exato de opções:
A expressão abaixo permite que você obtenha o valor atualmente mantido no campo CategoryName para o recurso de atlas atual
attribute ($atlasfeature, 'CategoryName')
Use isso para criar um estilo baseado em regras para a camada de pontos ao longo das linhas de
attribute ($atlasfeature, 'CategoryName') = PointCategory AND PointCategory = "RedDots"
Eu também tinha uma regra para garantir que todos os outros se tornassem transparentes
attribute ($atlasfeature, 'CategoryName') IS NOT PointCategory
Testar isso com o atlas funciona muito bem. Finalmente, basta usar a mesma abordagem para manipular os rótulos mostrados, tornar os rótulos dinâmicos e filtrar as tabelas adequadamente. Marcar a 'legenda de filtro pelo conteúdo do mapa' também é muito eficaz se você não quiser todos os itens de legenda em todos os mapas.
Conjunto final de atlas:
Editar - como foi solicitado, aqui está o meu script:
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 )