Возможно также посмотрите на мой другой ответ, поскольку новые более современные инструменты появились после этого.
Я пришел к приведенному ниже коду, который, к сожалению, не полностью функционален. Это основано на решении выше и на этих других вопросах:
Как программно экспортировать композицию как изображение?
Как я могу прочитать настройки для QgsPaperItem из XML?
Сохранить Map Canvas в формате PNG с прозрачным фоном программно с помощью QGIS?
Мой код может извлечь .qpt из файла .qgs и успешно загрузить композитор из шаблона. Он также печатает композитор в файл .png и правильно отображает метки и формы, хранящиеся в композиторе.
Однако не удается загрузить все элементы, связанные с фактической картой и слоями (метка, содержащая выражение из слоя, также не рисуется). Я думаю, что я немного упустил, как проект должен быть загружен и связан с композитором.
Некоторые люди в комментарии к оригинальной статье Тима Саттона упоминали, что они застряли на одной и той же стадии под Windows (это мой случай). Это действительно расстраивает, потому что я чувствую, что ответ действительно очень близок. Уважаемый интернет, помогите пожалуйста!
Также это мои первые попытки на Python, поэтому я надеюсь, что вы будете добрыми;)
#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()
Я удалил эти строки из предыдущего кода, так как они, казалось, ничего не делали. Они не породили ошибок, но не сделали ничего лучше.
# 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()
и те тоже удалены, потому что они казались ненужными при использовании 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()