6

I'm trying to automate map export from a QGIS project in a standalone Python script, without interface.

Many of the scripts founds are for QGIS 2. For example the script written by @TimSutton here.

Here the code:

# coding=utf-8

A simple demonstration of to generate a PDF using a QGIS project

and a QGIS layout template.

This code is public domain, use if for any purpose you see fit.

Tim Sutton 2015

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'

def make_pdf(): 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)
composition = QgsComposition(canvas.mapSettings())
# You can use this to replace any string like this [key]
# in the template with a new value. e.g. to replace
# [date] pass a map like this {'date': '1 Jan 2012'}
substitution_map = {
    'DATE_TIME_START': 'foo',
    'DATE_TIME_END': 'bar'}
composition.loadFromTemplate(document, substitution_map)
# 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()
composition.exportAsPDF('report.pdf')
QgsProject.instance().clear()


make_pdf()

QGIS 3 is now based on Python 3 and Qt 5 and I try to simply export a layout with a script without load / show the QGIS GUI.

Which script to use under QGIS 3?

Taras
  • 32,823
  • 4
  • 66
  • 137
J. Monticolo
  • 15,695
  • 1
  • 29
  • 64

1 Answers1

11

Here is the solution working for me. The python file must be in the same directory as the QGIS 3 project file :

#!/usr/bin/env python3
import os
from qgis.core import (QgsProject, QgsLayoutExporter, QgsApplication)

QgsApplication.setPrefixPath("/usr", True)

gui_flag = False
app = QgsApplication([], gui_flag)

app.initQgis()

project_path = os.getcwd() + '/project.qgz'

project_instance = QgsProject.instance()
project_instance.setFileName(project_path)
project_instance.read()

manager = QgsProject.instance().layoutManager()
layout = manager.layoutByName("my_layout") # name of the layout
# or layout = manager.layouts()[0] # first layout

exporter = QgsLayoutExporter(layout)
exporter.exportToPdf(project_instance.absolutePath() + "/layout.pdf",
                     QgsLayoutExporter.PdfExportSettings())

app.exitQgis()
J. Monticolo
  • 15,695
  • 1
  • 29
  • 64