Bei der Arbeit mit der QGIS-API für Python sind einige Probleme aufgetreten. Ich habe es mir in QGIS bequemer gemacht, in der Python-Konsole zu arbeiten, aber ich habe Probleme, wenn ich versuche, den Code außerhalb von QGIS auszuführen.
Grundsätzlich möchte ich ein Shapefile nehmen, es basierend auf dem angegebenen Attributnamen beschriften und ein Bild rendern. Der Code funktioniert in QGIS, jedoch nicht außerhalb von QGIS. Woher kommt mein Problem?
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")
Ich kann das einfache Rendering-Beispiel im Python-Kochbuch ausführen, daher denke ich, dass meine Pfade korrekt eingerichtet sind.
"Good Shape File" sollte durch einen guten Pfad ersetzt werden, wenn Sie dies ausführen möchten. Und palyr.fieldName = 'Attribute' sollte auf einen gültigen Feldnamen für dieses Shapefile gesetzt werden.
Bearbeiten: Ich habe iface entfernt und Code für den Umfang zwischen der mapRenderer-Initialisierung und der ersten Deklaration eingefügt.
mapRenderer = QgsMapRenderer()
rect = file.extent()
mapRenderer.setExtent(rect)
mapRenderer.setLabelingEngine(QgsPalLabeling())
lst = [file.id()]
Edit: Ich habe hinzugefügt
app = QgsApplication([], True)
nach
QgsApplication.initQgis()
und der Code funktionierte.
iface
außerhalb von QGIS verwenden. Das muss seinmapRenderer = QgsMapRenderer()
Antworten:
Die Kombination aus Entfernen von iface und Deklarieren der App-Variablen scheint funktioniert zu haben. Ich erhalte jetzt ein Bild aus dem Shapefile, wobei jedes Feature mit dem Attribut "Attribut" gekennzeichnet ist.
quelle