How to manage two map items in a QGIS composition with python?

I need to manage two different map items in the same map composition, with a stand alone python script.

Each composer map has been referenced like this:

composerMap1 = composition.getComposerMapById(0)
composerMap2 = composition.getComposerMapById(1)


Then, I suppose that I should alternatively set to True and False the keepLayerSet variable, using the function setKeepLayerSet(), and each time I should add a new layerset to the Map Renderer, with the function setLayerSet(layerlist).

At least, that's what I think... seen that this is the procedure for the desktop QGIS software. But it does not work properly: in the exported image there is always an empty map, while the other display the same set of layers. Has anybody tried to do the same thing, and has some hint to share? Thanks!

• Can you post your whole current script? – ndawson Sep 18 '14 at 21:55

not sure if you're still having trouble with this, but I have indeed got a setup going of producing maps using the QGIS composer functionality via the Python API.

My general strategy is:-

1) Create a shared map canvas used by the composer, and all maps etc. Code to first create the QgsComposition looks like:

ms = canvas.mapSettings()
comp = QgsComposition(ms)


2) My composition does indeed have 2 separate maps. After reading in my composer template XML I refer to them similarly to you, e.g. using

comp.getComposerItemById(map_name)


3) Following instructions from John Sutton's blog post linked below:- before creating actual maps, I make sure the maps are linked properly to the canvas, by calling:-

map_item.setMapCanvas(canvas)
map_item.zoomToExtent(canvas.extent())


4) Before creating the output PDF, call

composition.refreshItems()


In my case, I'd already set the layers I wanted to use for each map in the XML file, so I didn't need to modify these further in the Python script. Indeed I had them each locked in 'lock layer-set mode'. But I did also test modifying them in Python by changing the array of map layers, and it worked. E.g. here is an example of replacing the 2nd (hence index #1) layer of one of the maps:

layerSet = map_item.layerSet()
layerSet[1] = ptua_iso_layer_id
map_item.setLayerSet(layerSet)


Note:- in general I was having a lot of issues with blank maps being generated when loading layers from projects until I worked out the various 'best practices' for creating a QGIS script to run externally to QGIS, including making sure to set the QGIS path, call QgsApplication.initQgis(), etc. Creating a shared canvas and linking it to the loaded project via a QgsLayerTreeMapCanvasBridge seems a good approach, see this handy blog post and code sample from Richard Sutton:- http://kartoza.com/how-to-create-a-qgis-pdf-report-with-a-few-lines-of-python/

Hope this helps!

• What QGIS version does this work on? – raphael Jan 10 '17 at 20:45