Jetez peut-être aussi un œil à mon autre réponse, car de nouveaux outils plus récents sont apparus depuis celui-ci.
Je suis arrivé au code ci-dessous qui n'est malheureusement pas entièrement fonctionnel. Ceci est basé sur la solution ci-dessus et sur ces autres questions:
Comment exporter par programmation une composition sous forme d'image?
Comment puis-je lire les paramètres de QgsPaperItem à partir de XML?
Enregistrer le canevas de carte au format PNG avec un fond transparent par programmation avec QGIS?
Mon code est capable d'extraire le fichier .qpt d'un fichier .qgs et de charger avec succès un compositeur à partir d'un modèle. Il imprime également un compositeur dans un fichier .png et affiche correctement les étiquettes et les formes stockées dans le compositeur.
Cependant, il ne parvient pas à charger tous les éléments liés à la carte et aux couches réelles (les étiquettes contenant l'expression de la couche ne sont pas dessinées non plus). Je pense que j'ai manqué un peu de savoir comment le projet doit être chargé et lié au compositeur.
Certaines personnes dans le commentaire de l' article original de Tim Sutton ont mentionné qu'elles étaient coincées au même stade sous Windows (c'est mon cas). C'est vraiment frustrant car j'ai l'impression que la réponse est vraiment très proche. Cher Internet, aidez-moi!
C'est aussi mes premières tentatives de python donc j'espère que vous serez gentil;)
#This python code aim to programmatically export the first composer stored in a qgs file using PyQgis API v 2.10
#Version 0.4 (non functional) WTFPL MarHoff 2015 - This code is mostly a "frankenstein" stub made with a lot of other snippets. Feel welcome to improve!
#Credits to gis.stackexchange community : drnextgis,ndawson,patdevelop,dakcarto,ahoi, underdark & Tim Sutton from kartoza
#More informations and feedback can be found at /gis/144792/
#This script assume your environement is setup for PyGis as a stand-alone script. Some nice hints for windows users : /gis//a/130102/17548
import sys
from PyQt4.QtCore import *
from PyQt4.QtXml import *
from qgis.core import *
from qgis.gui import *
gui_flag = True
app = QgsApplication(sys.argv, gui_flag)
# Make sure QGIS_PREFIX_PATH is set in your env if needed!
app.initQgis()
# Name of the .qgs file without extension
project_name = 'myproject'
#Important : The code is assuming that the .py file is in the same folder as the project
folderPath = QString(sys.path[0])+'/'
projectPath = QString(folderPath+project_name+'.qgs')
templatePath = QString(folderPath+project_name+'_firstcomposer.qpt')
imagePath = QString(folderPath+project_name+'.png')
#Getting project as Qfile and the first composer of the project as a QDomElement from the .qgs
projectAsFile = QFile(projectPath)
projectAsDocument = QDomDocument()
projectAsDocument.setContent(projectAsFile)
composerAsElement = projectAsDocument.elementsByTagName("Composer").at(0).toElement()
#This block store the composer into a template file
templateFile = QFile(templatePath)
templateFile.open(QIODevice.WriteOnly)
out = QTextStream(templateFile)
#I need next line cause UTF-8 is somewhat tricky in my setup, comment out if needed
out.setCodec("UTF-8")
param = QString
composerAsElement.save(out,2)
templateFile.close()
#And this block load back the composer into a QDomDocument
#Nb: This is ugly as hell, i guess there is a way to convert a QDomElement to a QDomDocument but every attemps failed on my side...
composerAsDocument = QDomDocument()
composerAsDocument.setContent(templateFile)
#Now that we got all we can open our project
canvas = QgsMapCanvas()
QgsProject.instance().read(QFileInfo(projectAsFile))
bridge = QgsLayerTreeMapCanvasBridge(
QgsProject.instance().layerTreeRoot(), canvas)
bridge.setCanvasLayers()
#Lets try load that composer template we just extracted
composition = QgsComposition(canvas.mapSettings())
composition.loadFromTemplate(composerAsDocument, {})
#And lets print in our .png
image = composition.printPageAsRaster(0)
image.save(imagePath,'png')
#Some cleanup maybe?
QgsProject.instance().clear()
QgsApplication.exitQgis()
J'ai supprimé ces lignes du code précédent car elles semblaient ne rien faire du tout. Ils n'ont engendré aucune erreur mais n'ont pas fait mieux.
# You must set the id in the template
map_item = composition.getComposerItemById('map')
map_item.setMapCanvas(canvas)
map_item.zoomToExtent(canvas.extent())
# You must set the id in the template
legend_item = composition.getComposerItemById('legend')
legend_item.updateLegend()
composition.refreshItems()
et ceux-ci sont également supprimés car ils semblaient inutiles lors de l'utilisation de printPageAsRaster ()
dpmm = dpi / 25.4
width = int(dpmm * composition.paperWidth())
height = int(dpmm * composition.paperHeight())
# create output image and initialize it
image = QImage(QSize(width, height), QImage.Format_ARGB32)
image.setDotsPerMeterX(dpmm * 1000)
image.setDotsPerMeterY(dpmm * 1000)
image.fill(0)
# render the composition
imagePainter = QPainter(image)
composition.renderPage(imagePainter, 0)
imagePainter.end()