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ó.
iface
fuera de QGIS. Eso tiene que sermapRenderer = QgsMapRenderer()
Respuestas:
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'.
fuente