어쩌면 이 도구 이후로 최신의 최신 도구가 생겼으므로 다른 대답 을 살펴볼 수도 있습니다 .
불행히도 완전히 작동하지 않는 아래 코드를 보았습니다. 이것은 위의 솔루션과 다른 질문에 근거합니다.
컴포지션을 프로그래밍 방식으로 이미지로 내보내는 방법은 무엇입니까?
XML에서 QgsPaperItem의 설정을 읽으려면 어떻게해야합니까?
QGIS를 사용하여 프로그래밍 방식으로 투명한 배경의 맵 캔버스를 PNG로 저장 하시겠습니까?
내 코드는 .qgs 파일에서 .qpt를 추출하고 템플릿에서 작곡가를 성공적으로로드 할 수 있습니다. 또한 작곡가를 .png 파일로 인쇄하고 작곡가에 저장된 레이블과 모양을 올바르게 표시합니다.
그러나 실제 맵 및 레이어와 관련된 모든 요소를로드하지 못합니다 (레이어의 표현식을 포함하는 레이블도 그려지지 않음). 프로젝트를로드하고 작곡가에게 어떻게 연결 해야하는지에 대해 조금 놓쳤다 고 생각합니다.
Tim Sutton 의 원본 기사 에 대한 일부 사람들은 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()