Shapefile mit PyQGIS rendern und beschriften

8

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.

Mittelfeld99
quelle
1
Zunächst einmal können Sie nicht ifaceaußerhalb von QGIS verwenden. Das muss seinmapRenderer = QgsMapRenderer()
Nathan W
Okay, anscheinend habe ich mapRenderer nicht mit genügend Informationen initialisiert. Die Konsole friert bei c = QgsComposition (mapRenderer) ein, nachdem ich die Informationen zum Umfang des Layers und der Beschriftungs-Engine hinzugefügt habe. Der Code funktioniert jedoch weiterhin in QGIS. Die Größe muss nur geändert werden.
Mittelfeld99
1
Es scheint, dass die Initialisierung von QgsApplication das Problem war. Und es scheint, dass dieses Problem in gis.stackexchange.com/questions/69626/… behandelt wurde . Das Deklarieren einer App-Variablen und das Hinzufügen einer app.exitQgis () hat also funktioniert.
Mittelfeld99
Ich habe Probleme beim Erstellen von PNGs mit der oben genannten Methode. Mein Shapefile wird korrekt gelesen, ein Bild wird erstellt, aber es bleibt immer vollständig weiß. Wie Sie in den Ausdrucken sehen können, sind die Werte für mapRenderer.extent () immer Null. Ist das normal oder muss ich mich eingehender damit befassen? Die nachfolgenden Überprüfungen mit dpi, Breite und Höhe der QgsComposition liefern einige Werte, obwohl ich keine Ahnung habe, ob sie korrekt sind oder nicht. Ich habe auch eine Reihe verschiedener Druck- / Rendering-Optionen ausprobiert, wie c.render () oder das Zeug als pdfs ausgegeben. Ich bekomme nie Fehler, aber meine Seite
Bob3k
Hey Moderator, der meinen letzten Beitrag zum selben Thema gelöscht hat, bitte lass diesen hier. Dies ist völlig relevant, da ich nicht glaube, dass die obigen Antworten noch funktionieren und ich nicht der einzige bin, der hier Probleme hat. Entweder bin ich verrückt oder die beiden Codebits funktionieren nicht mehr. Ich habe diese kopiert und für meinen Gebrauch optimiert und für mein Leben kann ich kein TIF aus dem Shapefile mit etwas anderem als einer weißen Leinwand mit der Aufschrift "Legend: Contours" in der oberen linken Ecke erhalten. Mein Ziel ist um ein Shapefile (shp) zu nehmen und es in ein TIF mit den in der Höhe beschrifteten Konturlinien umzuwandeln. Ich kann das s
Marc

Antworten:

2

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.

Mittelfeld99
quelle