Comment remplir la carte du compositeur avec des données de canevas et exporter la composition au format PNG à l'aide du script Python dans QGIS

10

Je voudrais créer un script Python dans QGIS qui prendra certaines données (shp + tif, dans mon exemple), utiliser Tamplate Map Composer (à partir d'un fichier) et exporter la composition créée vers une image png.

Avec presque aucune expérience en programmation (moins que la connaissance de base de Python), je recherche sur Google quelques extraits de code et essaie de les faire fonctionner ensemble. J'ai pris le code de Map Composer à partir d'une question précédemment répondue: Enregistrer la vue Print / Map QGIS composer en PNG / PDF en utilisant Python (sans rien changer dans la disposition visible)?

J'ai réussi à charger les données et le modèle Map Composer (avec une seule carte et des éléments de légende définis) mais mon image png d'exportation a un cadre de carte vide (pas de données vectorielles / raster dans le cadre). L'élément de légende semble bien cependant.

Une aide pour faire fonctionner ce code?

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()
hans80
la source
Juste pour l'optimisation du code, vous pouvez apparemment d'abord ajouter le raster et la couche vectorielle au lieu de changer l'ordre. Ce serait dans le bon ordre immédiatement.
Clement

Réponses:

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

Vous devez ajouter ces calques au canevas avant d'exporter en png

Krishna
la source