Tengo algunas capas con símbolos muy complejos definidos por datos. Si uso una leyenda en el compositor de impresión, estos símbolos no se dibujan correctamente.
¿Hay alguna manera de cambiar los símbolos de leyenda con pyqgis, para que pueda usar imágenes PNG o SVG personalizadas en lugar del símbolo de leyenda predeterminado para estas capas?
Sé cómo agregar un botón al compositor de impresión y cómo conectarlo con una función. Quiero agregar un botón a la configuración de leyenda para permitirme reemplazar el icono de leyenda generado automáticamente con una imagen personalizada. Entonces, lo que aún necesito es la información de cómo puedo acceder a los símbolos de leyenda con pyqgis / pyqt, y cómo reemplazarlos con una QImage en un QLabel o algo así.
Maqueta muy básica del botón utilizado para cambiar el símbolo:
Leyenda generada automáticamente:
Leyenda con símbolo de leyenda personalizado:
Ya descubrí cómo acceder a los elementos de la leyenda en el compositor de impresión, pero aún no cómo acceder al símbolo en sí:
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:
También descubrí cómo acceder a los objetos QIcon del árbol de leyendas, pero todavía no puedo intercambiarlos:
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()
Aquí hay un ejemplo de la vida real donde puede ver una simbología combinada de muchas capas de símbolos: Esto terminará en la leyenda de esta manera:
Como necesito el símbolo apropiado en la leyenda, me gustaría hacer una captura de pantalla de mi símbolo, recortarlo y usarlo como una imagen en mi leyenda.
Sé que podría superponer una imagen separada en la parte superior de mi leyenda que cubre el símbolo generado automáticamente, pero me gustaría tener una solución "más limpia" que me permita reemplazar los símbolos en la leyenda con imágenes personalizadas.
Edición 2:
Mientras tanto, he encontrado otra forma de obtener acceso a las entradas de la leyenda:
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)
Esto me permite acceder a los objetos QgsLayerTreeLayer y puedo cambiar el estilo de la leyenda (Grupo, Subgrupo, Oculto). Pero todavía no tengo idea de cómo acceder al símbolo de la leyenda. ¿Algunas ideas?
Respuestas:
Como este tema cubre muchos argumentos, solo me enfocaré en las capas de símbolos SVG, esperando haber entendido bien lo que está buscando (no me di cuenta de la longitud de la respuesta mientras escribía, así que lo siento por eso, pero espero que agregue más claridad, sin embargo).
Contexto
1) Clases de capa de símbolo
Las siguientes clases de capa de símbolo están disponibles para el formato SVG:
Un enfoque común para crear una capa de símbolo es inicializarla con un diccionario de propiedades.
Puede inicializar una nueva capa de símbolo y ver sus propiedades predeterminadas de esta manera:
Obtendrá todas las propiedades que están almacenadas en él:
Si desea editar las propiedades, puede usar métodos, que pueden llamarse desde la ayuda de la clase (por ejemplo, ejecutar
help(QgsSvgMarkerSymbolLayerV2)
en la Consola Python). Verá más adelante un ejemplo de cómo usar métodos.En aras de la exhaustividad, también puede inicializar una capa de símbolo con un diccionario de propiedades (por ejemplo, ver aquí ), pero sinceramente prefiero el primer enfoque y lo usaré.
2) Crear un renderizador
Para usar la capa de símbolo una vez que la ha creado (y finalmente editado), debe crear un renderizador apropiado y luego asignar ese renderizador a su capa de mapa.
Para acceder al renderizador existente de una capa:
Para obtener una lista de los tipos de renderizadores disponibles, use:
Para su caso, debemos tratar con un renderizador de símbolos categorizados . Como dije antes, necesitas crear un renderizador y luego asignarlo a la capa:
3) Cambiar la capa de símbolo
Los varios símbolos del renderizador de símbolos categorizados se pueden llamar
symbols()
(devuelve una lista):Si desea reemplazar una capa de símbolo dada dentro de la
symbol
definida anteriormente, solo necesita conocer su índice y luego decirle al procesador de esta manera:donde
[0]
indica el primer elemento del grupo categorizado.Solución
Finalmente, ¡apliquemos lo que acabamos de aprender!
Asumiendo trabajar en esta capa de polígono, que almacena los usos del suelo que hemos definido antes:
Si desea cambiar el patrón predeterminado para los usos de la tierra agrícola (tienen la posición No. 1 en el grupo 'landuse') con una imagen SVG específica, puede ejecutar este código (lea aquí para saber cómo agregar un SVG personalizado) camino):
Este será el resultado:
El código anterior es muy aproximado, pero como no sabía si deseaba una solución específica para su ejemplo o una explicación más general, preferí centrar la atención en las herramientas disponibles en lugar de refinar el código en sí (estoy seguro ¡puede editarlo ligeramente de acuerdo con sus necesidades específicas!).
fuente
Alternativamente, y sin la codificación de Python, resolví esto creando un nuevo grupo de capas dedicado a la creación de leyendas, donde puedo poner lo que quiera, con los tamaños y colores que quiero. Así en el compositor de impresión, acabo de eliminar de los elementos de la leyenda las capas de datos reales y conservé solo el grupo de capas de la leyenda.
Es específicamente práctico cuando se necesita hacer una leyenda que pueda representar casos que no suceden en el mapa impreso real.
EDITAR: y sobre su segunda edición, con los símbolos compuestos que no se muestran correctamente, ¿tiene algunas variables que definan sus símbolos, como "C" o "G" en realidad es relativo a un campo o la orientación? Si es así, QGIS no puede adivinar qué desea que se muestre, por lo que muestra todo sin ningún valor para estos parámetros. Una solución alternativa puede ser guardar de manera simple el símbolo con algunos valores fijos en lugar de las variables. Esta manera me permitió reemplazar este elemento de leyenda de visualización predeterminado: por este que se ajusta a mi necesidad
fuente