Eu tenho algumas camadas com símbolos definidos por dados muito complexos. Se eu usar uma legenda no compositor de impressão, esses símbolos não serão desenhados corretamente.
Existe uma maneira de alterar os símbolos de legenda com pyqgis, para que eu possa usar imagens PNG ou SVG personalizadas em vez do símbolo de legenda padrão para essas camadas?
Sei como adicionar um botão ao compositor de impressão e como conectá-lo a uma função. Desejo adicionar um botão às Configurações da legenda para permitir a substituição do ícone da legenda gerada automaticamente por uma imagem personalizada. Então, o que eu ainda preciso são as informações de como posso acessar os símbolos de legenda com pyqgis / pyqt e como substituí-los por uma QImage em um QLabel ou algo assim?
Maquete muito básica do botão usado para alterar o símbolo:
Legenda gerada automaticamente:
Legenda com o símbolo de legenda personalizada:
Já descobri como acessar os itens da legenda no compositor de impressão, mas ainda não como acessar o próprio símbolo:
import qgis
from PyQt4.QtCore import *
from PyQt4.QtGui import *
activeComposer = iface.activeComposers()
for item in activeComposer:
if item.composerWindow().windowTitle()=='test':
for i in item.items():
if isinstance(i,QgsComposerLegend):
#print i
#print i.model()
legend = i
for i in xrange(legend.modelV2().rowCount()):
posteleg=legend.modelV2().index(i, 0)
print posteleg.data()
Editar 1:
Eu também descobri como acessar objetos QIcon da árvore de legendas, mas ainda não posso trocá-los:
def run(self):
activeComposer = self.iface.activeComposers()
#print(self.resolve('icon.png'))
for item in activeComposer:
if item.composerWindow().windowTitle()=='test':
for i in item.items():
if isinstance(i,QgsComposerLegend):
legend = i
layerIcon = QIcon(os.path.join(os.path.dirname(__file__), "icon.png"))
for i in xrange(legend.modelV2().rowCount()):
posteleg=legend.modelV2().index(i, 0)
posteleg.model().iconGroup().swap(layerIcon)
print posteleg.data()
Aqui está um exemplo da vida real em que você pode ver uma simbologia combinada de várias camadas de símbolos: Isso terminará na legenda assim:
Como preciso do símbolo apropriado na legenda, gostaria de fazer uma captura de tela do meu símbolo, recortá-lo e usá-lo como uma imagem na legenda.
Sei que poderia sobrepor uma imagem separada em cima da minha legenda, que cubra o símbolo gerado automaticamente, mas gostaria de ter uma solução "mais limpa" que me permita substituir os símbolos na legenda por imagens personalizadas.
Edição 2:
Enquanto isso, eu encontrei outra maneira de obter acesso às entradas da legenda:
from qgis.core import QgsLegendRenderer, QgsComposerLegendStyle
compDict = {}
for comp in iface.activeComposers():
# workaround to get name: read it from window title
compDict[comp.composerWindow().windowTitle()] = comp.composition()
if "mycomposername" in compDict:
itemLlegend = compDict["mycomposername"].getComposerItemById("mylegend_id")
if itemLlegend:
print itemLlegend
tree_layer_layer = itemLlegend.modelV2().rootGroup().children()
for item in tree_layer_layer:
if item.layerName()=="MyLayername":
print "match"
QgsLegendRenderer.setNodeLegendStyle(item, QgsComposerLegendStyle.Group)
Isso me permite acessar os objetos QgsLayerTreeLayer e posso alternar a legenda Estilo (Grupo, Subgrupo, Oculto). Mas ainda não tenho ideia de como acessar o símbolo da legenda. Alguma ideia?
Respostas:
Como este tópico aborda muitos argumentos, vou me concentrar apenas nas camadas de símbolos SVG, na esperança de entender bem o que você está procurando (não percebi a duração da resposta enquanto escrevia, então, desculpe-me por mas espero que isso adicione mais clareza).
Contexto
1) Classes da camada de símbolo
As seguintes classes de camada de símbolo estão disponíveis para o formato SVG:
Uma abordagem comum para criar uma camada de símbolo é inicializá-la com um dicionário de propriedades.
Você pode inicializar uma nova camada de símbolo e ver suas propriedades padrão desta maneira:
Você obterá todas as propriedades armazenadas nele:
Se você deseja editar as propriedades, poderá usar métodos que podem ser chamados da ajuda da classe (por exemplo, executados
help(QgsSvgMarkerSymbolLayerV2)
no Python Console). Você verá mais adiante um exemplo de como usar métodos.Por uma questão de integridade, você também pode inicializar uma camada de símbolo com um dicionário de propriedades (por exemplo, veja aqui ), mas eu sinceramente prefiro a primeira abordagem e a utilizarei.
2) Criando um renderizador
Para usar a camada de símbolo depois de criá-la (e eventualmente editá-la), você precisa criar um representante apropriado e depois atribuí-lo à sua camada de mapa.
Para acessar o renderizador existente de uma camada:
Para obter uma lista dos tipos de renderizadores disponíveis, use:
Para o seu caso, devemos lidar com um representante de símbolo categorizado . Como eu disse antes, você precisa criar um renderizador e atribuí-lo à camada:
3) Mudando a camada do símbolo
Os vários símbolos do representante de símbolos categorizados podem ser chamados
symbols()
(ele retorna uma lista):Se você deseja substituir uma determinada camada de símbolo dentro da
symbol
definida anteriormente, você só precisa conhecer seu índice e, em seguida, informar ao renderizador da seguinte maneira:onde
[0]
indica o primeiro item do grupo categorizado.Solução
Finalmente, vamos aplicar o que acabamos de aprender!
Assumindo trabalhar nesta camada de polígono, que armazena os usos da terra que definimos anteriormente:
Se você deseja alterar o padrão padrão para os usos da terra agrícola (eles têm a posição número 1 no grupo 'uso da terra') com uma imagem SVG específica, você pode executar este código (leia aqui para saber como adicionar um SVG personalizado caminho):
Este será o resultado:
O código acima é muito difícil, mas como eu não sabia se você queria uma solução específica para o seu exemplo ou uma explicação mais geral, preferi concentrar a atenção nas ferramentas disponíveis em vez de refinar o próprio código (tenho certeza você pode editá-lo levemente de acordo com suas necessidades específicas!).
fonte
Como alternativa, e sem a codificação Python, resolvi isso criando um novo grupo de camadas dedicado à criação da legenda, onde posso colocar o que quiser, com os tamanhos e cores que desejar. Assim no compositor de impressão, acabei de excluir dos itens de legenda as camadas de dados reais e mantive apenas o grupo de camadas de legenda.
É especificamente prático quando é necessário criar uma legenda que possa representar casos que não estão acontecendo no mapa impresso real.
EDIT: e na sua segunda edição, com os símbolos compostos não exibidos corretamente, você tem algumas variáveis que definem seus símbolos, como o "C" ou "G" é de fato relativo a um campo ou à orientação? Se for esse o caso, o QGIS não pode adivinhar o que você deseja exibir, exibindo tudo sem nenhum valor para esses parâmetros. Uma solução alternativa pode ser salvar simplesmente o símbolo com alguns valores fixos no lugar das variáveis. Dessa maneira, eu substituí esse item de legenda padrão: por este, atendendo minha necessidade
fonte