I am trying to code a standalone QGIS application that is able to print a composed map that zooms in the same layer every time I call it. The feature that have to be zoomed in change its location when is regenerated so my map application has to zoom in to a different place when I call it. I have been preparing an Atlas composer but when I call the print Python function it keeps the same area, it does not zoom to the chosen Atlas Layer. Another possibility is to zoom in to my layer every time I call the mapper, but I can't achieve it. I am adapting a code I found in the following Git repo without success: https://github.com/rjspiers/qgis-standalone-map-export
from qgis.core import *
import sys
print 'Hello from QGIS'
from qgis.core import (QgsProject, QgsComposition, QgsApplication, QgsProviderRegistry)
from qgis.gui import QgsMapCanvas, QgsLayerTreeMapCanvasBridge
from PyQt4.QtCore import QFileInfo, QObject
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()
# project.qgs
project_path = r'D:\Fmesalessimulation\Simulator\qgis-standalone-map-export-master\smartfee_map.qgs' # absolute filepath example: 'C:/folder/subfolder/project.qgs'
# template.qpt
template_path = r'D:\Fmesalessimulation\Simulator\qgis-standalone-map-export-master\smartfee_maptemplate.qpt'
#LayerIds
unused = 'BOUGHT_PAYS_DIFF20170130111140143'
sailedthrough = 'BOUGHT_UNITS20170130111140159'
optimalunits = 'PAYS_UNITS20170130111140165'
boundingbox = 'BOUNDING_BOX20170130111140161'
def make_pdf():
canvas = QgsMapCanvas()
# Load our project
QgsProject.instance().read(QFileInfo(project_path))
# Set canvas extent
# canvas.setExtent(QgsRectangle(xmin, ymin, xmax, ymax))
# Load layers here if they are not already in the project
for layer in QgsMapLayerRegistry.instance().mapLayers().values():
if layer.name() == 'BOUNDING_BOX':
lyr = layer
break
# lyr.setSubsetString(filter_expression)
#################
list_layers = []
for f in lyr.getFeatures():
if f['unit_name'] != '':
list_layers.append(f.id())
print list_layers
lyr.setSelectedFeatures(list_layers)
box = lyr.boundingBoxOfSelected()
lyr.setSelectedFeatures([])
canvas.setExtent(box)
canvas.refresh()
canvas.show()
#################
# bridge used in standalone script: http://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/loadproject.html
bridge = QgsLayerTreeMapCanvasBridge(
QgsProject.instance().layerTreeRoot(), canvas)
bridge.setCanvasLayers()
# Check data providers load ok
print('Provider List')
print(QgsProviderRegistry.instance().providerList())
# Print layer validity - I've had some trouble with some wms layers
for layer in QgsMapLayerRegistry.instance().mapLayers().values():
print(layer.name())
print(layer.isValid())
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 = {'title': 'PyQGIS test'}
# substitution_map = ''
composition.loadFromTemplate(document, substitution_map)
# You must set the id in the template
map_item = composition.getComposerItemById('Main 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(r'D:\Fmesalessimulation\Simulator\OUTPUT\JPG\PaysComparison.pdf')
QgsProject.instance().clear()
make_pdf()