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

2014-10-03 Thread Andrea Amparore
On Wed, Oct 1, 2014 at 10:12 PM, Nyall Dawson nyall.daw...@gmail.com wrote:


 On 02/10/2014 2:55 am, Andrea Amparore andrea.ampar...@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 

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

2014-10-01 Thread Andrea Amparore
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())

#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 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 

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

2014-10-01 Thread Andreas Neumann

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 = 

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

2014-10-01 Thread Andrea Amparore
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…

Should I go back to the previous version and forget about the new releases?

Regards,

Andrea

On Wed, Oct 1, 2014 at 12:43 PM, Andreas Neumann a.neum...@carto.net
wrote:

  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())

  #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 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 = 

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

2014-10-01 Thread Nyall Dawson
On 02/10/2014 2:55 am, Andrea Amparore andrea.ampar...@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
___
Qgis-user mailing list
Qgis-user@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/qgis-user

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

2014-10-01 Thread Andrea Amparore
Thanks Nyall!
I did what you have suggested: in fact opening manually the new XML as a
.qpt file into QGIS everything works perfectly, and I can manually export a
map.
But it doesn't work in the stand-alone script, which is what I need.
I didn't know that QgsMapRenderer is deprecated in 2.4, this is probably
causing the problem.
I will try to use the QgsMapSettings object instead of it!
Thanks for the hints!
Andrea

On Wed, Oct 1, 2014 at 10:12 PM, Nyall Dawson nyall.daw...@gmail.com
wrote:


 On 02/10/2014 2:55 am, Andrea Amparore andrea.ampar...@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

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