Rendu et étiquetage de fichiers de formes avec PyQGIS

8

J'ai rencontré quelques problèmes avec l'API QGIS pour python. Je suis devenu plus à l'aise de travailler dans la console python dans QGIS mais je rencontre des problèmes lorsque j'essaie d'exécuter le code en dehors de QGIS.

Fondamentalement, je veux prendre un fichier de formes, l'étiqueter en fonction du nom d'attribut spécifié et rendre une image. Le code fonctionne dans QGIS, mais ne fonctionne pas en dehors de QGIS. D'où vient mon problème?

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")

Je suis capable de faire l'exemple de rendu simple dans le livre de recettes python, donc je pense que mes chemins sont correctement configurés.

"Good Shape File" doit être remplacé par un bon emplacement de chemin si vous souhaitez l'exécuter. Et palyr.fieldName = 'Attribute' doit être défini sur un nom de champ valide pour ce fichier de formes.

Edit: je me suis débarrassé de iface et inséré du code pour l'étendue entre l'initialisation de mapRenderer et la lst déclaration.

mapRenderer = QgsMapRenderer()

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

Edit: j'ai ajouté

app = QgsApplication([], True)

après

QgsApplication.initQgis()

et le code a fonctionné.

milieu de terrain99
la source
1
Pour commencer, vous ne pouvez pas utiliser en ifacedehors de QGIS. Cela doit êtremapRenderer = QgsMapRenderer()
Nathan W
D'accord, il semble que je n'ai pas initialisé mapRenderer avec suffisamment d'informations. La console se fige à c = QgsComposition (mapRenderer) après avoir ajouté les informations sur l'étendue de la couche et le moteur d'étiquetage. Cependant, le code fonctionne toujours dans QGIS, il doit juste être redimensionné.
midfield99
1
Il semble que l'initialisation de QgsApplication était le problème. Et il semble que ce problème ait été traité dans gis.stackexchange.com/questions/69626/… . Donc, déclarer une variable d'application et ajouter un app.exitQgis () a fonctionné.
midfield99
Je rencontre des problèmes lors de la création de pngs avec la méthode susmentionnée. Mon fichier de formes est correctement lu, une image est créée, mais elle reste toujours complètement blanche. Comme vous pouvez le voir dans les impressions, les valeurs mapRenderer.extent () sont toujours nulles. Est-ce normal ou dois-je approfondir cela? Les vérifications suivantes avec dpi, largeur et hauteur de QgsComposition fournissent certaines valeurs, bien que je ne sache pas si elles sont correctes ou non. J'ai également essayé un certain nombre d'options d'impression / de rendu différentes, comme c.render (), ou en donnant des trucs en pdfs. Je n'ai jamais d'erreur, mais mon pag
Bob3k
Hé modérateur qui a supprimé mon dernier message sur le même sujet, veuillez laisser celui-ci en place. C'est tout à fait pertinent car je ne pense pas que les réponses ci-dessus fonctionnent toujours et je ne suis pas le seul à avoir du mal ici. Soit je suis fou, soit les deux morceaux de code ne fonctionnent plus. Je les ai copiés et modifiés pour mon usage et pour la vie de moi, je ne peux pas obtenir un tif du fichier de formes avec autre chose qu'une toile blanche qui dit "Legend: Contours" dans le coin supérieur gauche. Mon objectif est pour prendre un shapefile (shp) et le convertir en tif avec les courbes de niveau marquées en élévation. Je suis capable d'ouvrir le s
Marc

Réponses:

2

La combinaison de la suppression de l'iface et de la déclaration de la variable d'application semble avoir fonctionné. Je reçois maintenant une image rendue à partir du fichier de formes avec chaque fonctionnalité étiquetée avec l'attribut basé sur «Attribut».

milieu de terrain99
la source