Renderizado y etiquetado de archivos de forma con PyQGIS

8

Me he encontrado con algunos problemas al trabajar con la API QGIS para python. Me he vuelto más cómodo trabajando en la consola de Python en QGIS, pero me encuentro con problemas cuando intento ejecutar el código fuera de QGIS.

Básicamente, quiero tomar un shapefile, etiquetarlo según el nombre del atributo especificado y renderizar una imagen. El código funciona en QGIS, pero no funciona fuera de QGIS. Entonces, ¿de dónde viene mi problema?

import sys
import qgis
import PyQt4

from qgis.core import *
from qgis.utils import *
from qgis.gui import *


from PyQt4.QtCore import *
from PyQt4.QtGui import *

#initialize QGIS
QgsApplication.setPrefixPath( r"C:\OSGeo4W64\apps\qgis", True )

QgsApplication.initQgis()

#Add layer to instance
file = QgsVectorLayer("Good Shape File", "BMAS", "ogr")
QgsMapLayerRegistry.instance().addMapLayer(file)


#Adjust layer Settings
#Code sample from http://gis.stackexchange.com/questions/77870/how-to-label-vector-features-programmatically
palyr = QgsPalLayerSettings() 
palyr.enabled = True 
palyr.fieldName = 'Attribute' 
palyr.placement= QgsPalLayerSettings.OverPoint 
palyr.setDataDefinedProperty(QgsPalLayerSettings.Size,True,True,'8','') 
palyr.writeToLayer(file)

if file.isValid():
  print "File is valid."


mapRenderer = iface.mapCanvas().mapRenderer()

lst = [file.id()]
mapRenderer.setLayerSet(lst)

mapRenderer.setLayerSet( lst )
c = QgsComposition(mapRenderer)
c.setPlotStyle(QgsComposition.Print)
x, y = 0, 0
w, h = c.paperWidth(), c.paperHeight()
composerMap = QgsComposerMap(c, x,y,w,h)
c.addItem(composerMap)
composerLabel = QgsComposerLabel(c)

composerLabel.adjustSizeToText()
c.addItem(composerLabel)
composerLabel.setItemPosition(20,10)
composerLabel.setItemPosition(20,10, 100, 30)

legend = QgsComposerLegend(c)
legend.model().setLayerSet(mapRenderer.layerSet())
c.addItem(legend)

#set image sizing
dpi = c.printResolution()
dpmm = dpi / 25.4
width = int(dpmm * c.paperWidth())
height = int(dpmm * c.paperHeight())
img = QImage(QSize(width, height), QImage.Format_ARGB32)
img.setDotsPerMeterX(dpmm * 1000)
img.setDotsPerMeterY(dpmm * 1000)
img.fill(0)
imagePainter = QPainter(img)
sourceArea = QRectF(0, 0, c.paperWidth(), c.paperHeight())
targetArea = QRectF(0, 0, width, height)

#renders image
c.render(imagePainter, targetArea, sourceArea)
imagePainter.end()
img.save("E:/QGisTestImages/out.png", "png")

Puedo hacer el ejemplo de representación simple en el libro de cocina de Python, así que creo que mis rutas están configuradas correctamente.

"Good Shape File" debe reemplazarse por una buena ubicación de ruta si desea ejecutar esto. Y palyr.fieldName = 'Atributo' debe establecerse en un nombre de campo válido para ese shapefile.

Editar: me he deshecho de iface e inserté código por la extensión entre la inicialización de mapRenderer y la declaración lst.

mapRenderer = QgsMapRenderer()

rect = file.extent()
mapRenderer.setExtent(rect)
mapRenderer.setLabelingEngine(QgsPalLabeling())
lst = [file.id()]

Editar: agregué

app = QgsApplication([], True)

después

QgsApplication.initQgis()

y el código funcionó.

mediocampo99
fuente
1
Para empezar, no se puede usar ifacefuera de QGIS. Eso tiene que sermapRenderer = QgsMapRenderer()
Nathan W
Muy bien, parece que no he inicializado mapRenderer con suficiente información. La consola se congela en c = QgsComposition (mapRenderer) después de agregar la información sobre la extensión de la capa y el motor de etiquetado. Sin embargo, el código aún funciona en QGIS, solo necesita cambiar su tamaño.
midfield99
1
Parece que la inicialización de QgsApplication fue el problema. Y parece que este problema estaba cubierto en gis.stackexchange.com/questions/69626/… . Por lo tanto, declarar una variable de aplicación y agregar una app.exitQgis () funcionó.
midfield99
Estoy experimentando problemas al crear pngs con el método mencionado anteriormente. Mi archivo de forma se lee correctamente, se crea una imagen, pero siempre permanece completamente blanca. Como puede ver en las impresiones, los valores de mapRenderer.extent () son siempre cero. ¿Es esto normal o necesito profundizar más en esto? Las comprobaciones posteriores con dpi, ancho y alto de QgsComposition ofrecen algunos valores, aunque no tengo idea de si son correctos o no. También probé varias opciones diferentes de impresión / renderizado, como c.render (), o distribuyendo las cosas como archivos PDF. Nunca recibo errores, pero mi pag
Bob3k
Hola, moderador que eliminó mi última publicación sobre el mismo tema, por favor deje esta. Esto es completamente relevante porque no creo que las respuestas anteriores sigan funcionando y no soy el único que está luchando aquí. O estoy loco, o los dos bits de código ya no funcionan. He copiado estos y los modifiqué para mi uso y por mi vida no puedo obtener un tif del archivo de formas con nada más que un lienzo blanco que dice "Leyenda: Contornos" en la esquina superior izquierda. Mi objetivo es tomar un shapefile (shp) y convertirlo a tif con las líneas de contorno etiquetadas en elevación. Puedo abrir el s
Marc

Respuestas:

2

La combinación de eliminar iface y declarar la variable de la aplicación parece haber funcionado. Ahora obtengo una imagen renderizada del archivo de forma con cada característica etiquetada con el atributo basado en 'Atributo'.

mediocampo99
fuente