如何在QGIS中使用Python脚本将画布数据填充到作曲家地图并将构图导出为png


10

我想在QGIS中创建一个Python脚本,该脚本将获取一些数据(在我的示例中为shp + tif),使用模板模板Composer(来自文件),并将创建的合成导出到png图像。

几乎没有编程经验(除了基本的Python知识),我在Google上搜索了一些代码片段,并试图使它们协同工作。我从以前回答的一个问题中提取了Map Composer代码: 使用Python将Print / Map QGIS composer视图保存为PNG / PDF(不更改可见布局中的任何内容)吗?

我设法加载了数据和Map Composer模板(已定义了一个地图和图例项目),但我的导出png图像具有一个空的地图框架(该框架内没有矢量/栅格数据)。图例项目看起来很好。

使此代码有效吗?

from qgis.core import *
import qgis.utils

from PyQt4 import QtCore, QtGui
from qgis import core, gui

# ADD VECTOR LAYER

data_folder = "D:/QGIS/dane/"
granica = "granica_SZ VI_UTM34.shp"
granica_name = granica[0:-4]
granica = data_folder + granica
granica_style = "granica_style.qml"
granica_style = data_folder + granica_style

granica = iface.addVectorLayer(granica, granica_name, "ogr")
granica.loadNamedStyle(granica_style) 
if not granica.isValid():
  print "Granica failed to load or already loaded!"

qgis.utils.iface.legendInterface().setLayerVisible(granica, True)

# ADD RASTER LAYER

landsat = "SZ_VI_LC8-190-022_2015-111_LGN00_OLI_TIRS_atm.TIF"
landsat_name = landsat[0:-4]
landsat = data_folder + landsat
landsat_style = "landsat_style.qml"
landsat_style = data_folder + landsat_style

landsat = iface.addRasterLayer(landsat, landsat_name)
landsat.loadNamedStyle(landsat_style) 
qgis.utils.iface.legendInterface().setLayerVisible(landsat, True)

iface.zoomFull()

# MOVE RASTER DOWN (change order)

canvas = qgis.utils.iface.mapCanvas()
layers = canvas.layers()

root = QgsProject.instance().layerTreeRoot()

landsat_old = root.findLayer(landsat.id())
landsat_move = landsat_old.clone()
parent = landsat_old.parent()
parent.insertChildNode(2, landsat_move)
parent.removeChildNode(landsat_old)

# USE MAP COMPOSER TEMPLATE TO EXPORT IMAGE

from qgis.gui import QgsMapCanvas, QgsLayerTreeMapCanvasBridge
from PyQt4.QtXml import QDomDocument
from PyQt4.QtGui import QImage
from PyQt4.QtGui import QPainter
from PyQt4.QtCore import QSize

template_path = data_folder + 'template.qpt'
template_file = file(template_path)

# Set output DPI
dpi = 300

canvas = QgsMapCanvas()

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(data_folder + "out3.png", "png")

QgsApplication.exitQgis()

仅仅为了代码优化,您显然可以首先添加栅格和矢量层,而不用更改顺序。立即将以正确的顺序进行。
Clement

Answers:


1
canvas = QgsMapCanvas()
layers = [QgsMapCanvasLayer(landsat),QgsMapCanvasLayer(granica)] 
canvas.setLayerSet(layers)

在导出为png之前,您必须将这些图层添加到画布中

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.