[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