Можливо, також погляньте на мою іншу відповідь, оскільки нові новітні інструменти з'явилися з цього часу.
Я прийшов до коду, який, на жаль, не є повністю функціональним. Це ґрунтується на вищезазначеному рішенні та на цих інших питаннях:
Як програмно експортувати композицію як зображення?
Як я можу прочитати налаштування для QgsPaperItem з XML?
Збереження карти Canvas як PNG з прозорим фоном програмно за допомогою QGIS?
Мій код може витягнути .qpt з .qgs-файлу та успішно завантажити композитор із шаблону. Він також друкує композитора до .png-файлу та відображає правильно мітки та форми, що зберігаються у композиторі.
Однак він не може завантажити всі елементи, пов'язані з фактичною картою та шарами (мітка, що містить вираз із шару, також не намальована). Я думаю, що я трохи пропустив, як проект повинен бути завантажений і пов'язаний з композитором.
Деякі люди в коментарі до початкової статті від Тіма Саттона згадували, що вони застрягли на тому ж етапі під Windows (це мій випадок). Це насправді засмучує, бо я відчуваю, що відповідь насправді поруч. Шановний Інтернет, будь ласка, допоможіть!
Також це мої перші спроби пітона, тому я сподіваюся, що ви будете добрі;)
#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 : https://gis.stackexchange.com/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()