Hi Andrea,

Are you aware that QGIS already supports serial printing out of the box without scripting? I would first test if that works fine for you before bothering with scripts. QGIS 2.2 had serial printing in core, 2.4 has it improved and 2.6 has a lot more improvements. I am pretty sure that many (most?) cases can now be handled out of the box.

Andreas

On 01.10.2014 10:54, Andrea Amparore wrote:
Dear QGIS users community,

I'm a new member and I am stuck on a problem since few days, maybe someone can help me with this.

I have developed a stand-alone python script for making serial maps using PyQGIS library.

The maps should follow a specific format that is indicated by a template .qpt file.

This template file is opened and edited with lxml library in order to add information about the map (title, date, source, etc).

The modified .qpt is then loaded into a new composition, the layers are added and the map exported.

Everything was working perfectly since I’ve been using QGIS 2.2. Few days ago I have updated QGIS to the latest version 2.4 and now the output is sadly empty: map elements are displayed (frame, legend, title..), but no layer appears on the map.

The script is correct, because it still run correctly on another machine having QGIS 2.2. Is there anything that I have to modify for running it with QGIS 2.4?

This is a very basic version of the script.

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_QGIS24.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 <http://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 <http://point_layer.id>())

# Set up the map renderer that will be assigned to the composition
map_renderer = QgsMapRenderer()
#preparing the map the extent - 3 times wider than the polygon layer's extent
rect = layer.extent()
rect.scale(3)
# Set the labelling engine for the canvas
labelling_engine = QgsPalLabeling()
map_renderer.setLabelingEngine(labelling_engine)
# Enable on the fly CRS transformations
map_renderer.setProjectionsEnabled(True)
# Now set up the composition
composition = QgsComposition(map_renderer)
#set WGS84 as destination crs
map_projection = QgsCoordinateReferenceSystem(srid, QgsCoordinateReferenceSystem.PostgisCrsId)
map_projection_descr = map_projection.description()
map_renderer.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()
map_renderer.setLayerSet(layerset)

#legend
legend = QgsComposerLegend(composition)
legend.model().setLayerSet(map_renderer.layerSet())
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")

In this link you can find the 2 shapefiles and the composer template that you need for running the script, and the example of failed export: http://we.tl/8y3SrCxlGM

Thanks in advance.

Regards,

Andrea


_______________________________________________
Qgis-user mailing list
Qgis-user@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/qgis-user

_______________________________________________
Qgis-user mailing list
Qgis-user@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/qgis-user

Reply via email to