10

I'd like to create a Python script in QGIS that will take some data (shp + tif, in my example), use tamplate Map Composer (from a file) and export created composition to a png image.

With almost no experience in programming (less than basic Python knowledge) I google some code snippets and try to make them work together. I took the Map Composer code from some previously answered question: Save Print/Map QGIS composer view as PNG/PDF using Python (without changing anything in visible layout)?

I managed to load the data and Map Composer template (with a single map and legend items defined) but my export png image has an empty map frame (no vector/raster data within the frame). The legend item looks fine however.

Any help with making this code work?

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() 
1
  • Just for code optimization, you could apparently first add raster and the vector layer instead of changing the order. It would be in the right order immediately. Commented Dec 1, 2017 at 13:44

1 Answer 1

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

You would have to add these layers to the canvas before exporting as png

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.