Answers:
我建议使用蒂姆·萨顿(Tim Sutton)的以下脚本作为基础,它对我来说效果很好:-http : //kartoza.com/how-to-create-a-qgis-pdf-report-with-a-few-lines-的python /
只需将空字典传递给composition.loadFromTemplate()函数而不是他使用的“替换图”,因为您对该功能不感兴趣。
另外,由于您询问的是“导出为图像”而不是“导出为PDF”,因此您必须比使用exportAsPDF()成员函数做更多的工作。
以下是Tim的代码的修改版本,应该可以使用外部Python脚本来解决问题。根据需要设置DPI和project + composer文件变量。
(如果您在QGIS中使用Python控制台而不是作为外部脚本来执行此操作,则可以使用qgis.iface获取当前的地图画布,而无需使用所有项目加载等代码)。
import sys
from qgis.core import (
QgsProject, QgsComposition, QgsApplication, QgsProviderRegistry)
from qgis.gui import QgsMapCanvas, QgsLayerTreeMapCanvasBridge
from PyQt4.QtCore import QFileInfo
from PyQt4.QtXml import QDomDocument
gui_flag = True
app = QgsApplication(sys.argv, gui_flag)
# Make sure QGIS_PREFIX_PATH is set in your env if needed!
app.initQgis()
# Probably you want to tweak this
project_path = 'project.qgs'
# and this
template_path = 'template.qpt'
# Set output DPI
dpi = 300
canvas = QgsMapCanvas()
# Load our project
QgsProject.instance().read(QFileInfo(project_path))
bridge = QgsLayerTreeMapCanvasBridge(
QgsProject.instance().layerTreeRoot(), canvas)
bridge.setCanvasLayers()
template_file = file(template_path)
template_content = template_file.read()
template_file.close()
document = QDomDocument()
document.setContent(template_content)
ms = canvas.mapSettings())
composition = QgsComposition(ms)
composition.loadFromTemplate(document, {})
# 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()
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()
image.save("out.png", "png")
QgsProject.instance().clear()
QgsApplication.exitQgis()
python generate_pdf.py
您可以自己编程,也可以重用Maps Printer
插件中的方法。我将描述第二个选项,因为它更简单。
您需要Maps Printer
安装插件,使用配置的作曲家打开QGIS项目,打开QGIS Python控制台并运行此代码段(您需要在本Your settings
节中使用自己的设置进行调整)。
# Your settings
composerTitle = 'my composer' # Name of the composer you want to export
folder = '/path/to/export_folder/'
extension = '.png' # Any extension supported by the plugin
mp = qgis.utils.plugins['MapsPrinter']
for composer in iface.activeComposers():
title = composer.composerWindow().windowTitle()
if title == composerTitle:
mp.exportCompo( composer, folder, title, extension )
break
运行之后,您将在中获得一个新文件/path/to/export_folder/my composer.png
。您也可以使用'.pdf'
扩展名将作曲家导出为PDF。
也许也可以看看我的其他答案,因为自从这个工具出现以来,出现了更多新的最新工具。
我来了下面的代码,不幸的是它并没有完全起作用。这是基于上述解决方案以及以下其他问题的:
如何以编程方式将构图导出为图像?
如何从XML读取QgsPaperItem的设置?
使用QGIS以编程方式将Map Canvas保存为具有透明背景的PNG吗?
我的代码能够从.qgs文件中提取.qpt并从模板成功加载作曲家。它还将作曲家打印到.png文件,并正确显示存储在作曲家中的标签和形状。
但是,它无法加载与实际“地图和图层”相关的所有元素(也不会绘制包含来自图层的表达式的标签)。我想我错过了一些关于项目如何加载并链接到作曲家的想法。
有人在评论蒂姆·萨顿(Tim Sutton)的原始文章时提到,他们在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()
另一个更新的选择是查看QGIS社区开发的这2套工具。由于积极支持Map-sprinter,因此您应该期望脚本将随即将发布的QGIS版本进行更新。
两种工具都提供GUI,但是底层脚本是用Python编写的
将作曲家导出到文件中-https://github.com/DelazJ/MapsPrinter
从多个项目中导出作曲家-https: //github.com/gacarrillor/QGIS-Resources