[Qgis-user] Serial map from template composer. Working with QGIS 2.2, problems with QGIS 2.4

Andrea Amparore andrea.amparore at gmail.com
Fri Oct 3 07:44:15 PDT 2014


On Wed, Oct 1, 2014 at 10:12 PM, Nyall Dawson <nyall.dawson at gmail.com> wrote:
>
>
> On 02/10/2014 2:55 am, "Andrea Amparore" <andrea.amparore at gmail.com> wrote:
> >
> > Thanks Andreas!
> >
> > Actually I need to do it with a script, because the serial printing is a part of a much more complex script.
> >
> > It works on QGIS 2.2, but on QGIS 2.4 it drives me crazy…
>
> Two things:
> - QgsMapRenderer is deprecated in 2.4 and above. You should update your code to use the new replacement QgsMapSettings object.
>
> - Why don't you try saving the XML templates from your script to qpt files and then try loading them manually into QGIS? That might give you a better idea where your script is breaking.
>
> Nyall




Thanks to Nyall's suggestions now the script is adapted for QGIS 2.4.

In fact, the problem was generated by the object QgsMapRenderer, that
is deprecated in 2.4 and above. To make the script work it’s necessary
to replace it by the object QgsMapSettings.

Consequently, also some function names need to be slightly changed
(e.g. from setProjectionsEnabled() to setCrsTransformEnabled(), from
setLayerSet() to setLayers())

But there's still a minor problem: the two shapefiles on the map have
different CRS (UTM zone 15N and WGS84), and I would like to assign to
the map one of the two. It works only if I choose WGS84 (srid = 4326),
but if I assign the UTM projection to the map no layer is displayed.

The attribute “on the fly CRS transformations” is enabled, so I don’t
see the reason.

This is the new corrected script, now working also with QGIS 2.4

import os

from qgis.core import *

from qgis.gui import *

from PyQt4.QtCore import *

from PyQt4.QtGui import *

from PyQt4.QtXml import *

import lxml.etree as etree



print "setting prefix"

QgsApplication.setPrefixPath("/usr", True)

print "initiating qgis"

QgsApplication.initQgis()

print 'creating new app'

app = QgsApplication([], True)

#removing old layers

QgsMapLayerRegistry.instance().removeAllMapLayers()



script_folder = os.path.dirname(__file__)

project_folder = os.path.dirname(script_folder)

output_folder = os.path.join(project_folder, 'map_outputs')

xml_folder = os.path.join(project_folder, 'project_outputs')

shapefile_folder = os.path.join(project_folder, 'shapefile_folder')



template_composer = os.path.join(project_folder, 'basic_composer_template.qpt')

polyg_shapefile = os.path.join(shapefile_folder, 'polygon.shp') # crs
EPSG:4326 - WGS 84

point_shapefile = os.path.join(shapefile_folder, 'point.shp') # crs
EPSG:32615 - WGS 84 / UTM zone 15N



mapname = "Test Map"

srid = 4326

provider_name = 'ogr'

layerset = []



#add layer 1

vlayer_name= 'polygon layer'

vdata_source = polyg_shapefile

print "Loading EQ buffers"

layer = QgsVectorLayer(vdata_source, vlayer_name, provider_name)

print "Buffers loaded"

QgsMapLayerRegistry.instance().addMapLayer(layer)

layerset.append(layer.id())



#add layer 2

point_layer_name= 'point layer'

point_data_source = point_shapefile

point_layer = QgsVectorLayer(point_data_source, point_layer_name, provider_name)

QgsMapLayerRegistry.instance().addMapLayer(point_layer)

layerset.append(point_layer.id())



# Set up the MapSetting object that will be assigned to the composition

ms = QgsMapSettings()

#preparing the map the extent - 3 times wider than the polygon layer's extent

rect = layer.extent()

rect.scale(3)



# Enable on the fly CRS transformations

ms.setCrsTransformEnabled(True)



composition = QgsComposition(ms)

#set WGS84 as destination crs

map_projection = QgsCoordinateReferenceSystem(srid,
QgsCoordinateReferenceSystem.PostgisCrsId)

map_projection_descr = map_projection.description()

ms.setDestinationCrs(map_projection)



#open the composer template and edit it

with open(template_composer, 'r') as f:

    tree  = etree.parse(f)

    #setting extent

    for elem in tree.iter(tag = 'Extent'):

        elem.attrib['xmax'] = str(rect.xMaximum())

        elem.attrib['xmin'] = str(rect.xMinimum())

        elem.attrib['ymax'] = str(rect.yMaximum())

        elem.attrib['ymin'] = str(rect.yMinimum())

    #editing the title

    for elem in tree.iter(tag = 'ComposerLabel'):

            for child in elem:

                if child.tag == 'ComposerItem':

                    if child.attrib['id'] == "__maintitle__":

                        elem.attrib['labelText'] = mapname

    #save the edited composer as a new file

    new_composer = os.path.join(xml_folder, mapname + "_composer.qpt")

    tree.write(new_composer)



#open the newly created composer

new_composerfile = file(new_composer, 'rt')

new_composer_content = new_composerfile.read()

new_composerfile.close()

document = QDomDocument()

document.setContent(new_composer_content)

result =composition.loadFromTemplate(document)



# Get the main map canvas on the composition and set the layers

composerMap = composition.getComposerMapById(0)

composerMap.renderModeUpdateCachedImage()

ms.setLayers(layerset)



#legend

legend =QgsComposerLegend(composition)

legend.model().setLayerSet(ms.layers())

legend.model().setLayerSet

composition.addItem(legend)

legend.setItemPosition (25,122)

legend.setFrameEnabled(True)

legend.setScale(.7)



#save image

print 'saving image'

image = composition.printPageAsRaster(0)

image.save(os.path.join(output_folder,mapname) + ".png")



Thanks to everybody for the support!

Andrea



More information about the Qgis-user mailing list