[Qgis-user] Maps generation with Python (or Atlas ?)

Benoît Laurent blaurent at heurisis.eu
Wed May 20 07:38:03 PDT 2015



Le 20/05/2015 15:55, Bernd Vogelgesang a écrit :
> Hi Benoît,
>
> would you mind sharing your hole script as reference for others?
"As reference"... Hum... It would be very presumptuous of me :-).

> I think you touched a common problem which isn't covered with built-in 
> functions yet, and not everyone is gifted with profound coding 
> abilities in python (like me ;) )
"gifted with profound coding abilities in python". Same comment... :-)

However, I simplified the code a little and translated my comments in 
English. By the way, the picture inclusion does not work. If someone can 
help me on that point, it would be nice. If it helps, here is my code:


*#!/usr/bin/env Python
# encoding: utf-8
"""
         Generate pdf maps
         Assumptions :
                 - the QGis project contains a set of groups of 2 
layers, the first one just containting a linear feature, the second 
containing points along the track.
                 - the last group contains raster layers.

"""
from glob import glob
from os import *
from os.path import splitext

from qgis import core

from qgis.core import (QgsComposition,
                        QgsComposerMap,
                        QgsComposerLabel,
                        QgsComposerScaleBar,
                        QgsComposerPicture,
                        QgsMapLayer,
                        QgsRectangle,
                         QgsComposerArrow,
                        QGis)


from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import *
from PyQt4.QtGui import *

import os
import sys
import re
import time

def run_script(iface):
         ## Generator
         genCartes = GenCartes(iface)


         ## Generates the maps
         genCartes.generer()


class GenCartes:
         """
***************************************************************************************************************************************************
                 Constructeur
***************************************************************************************************************************************************
         """
         def __init__(self, iface):
                 ### Initialization using qgis.utils.iface
                 self.iface = iface

                 # Attribute of the class
                 self.composerMap = None

         """Compute an extent of geometry, with given margin (in %)
         to be able to show it in the selected map item
         Deal with non-square geometries to keep same ratio"""
         def getNewExtent(self, geom, margin = None):
                 # compute coordinates and ratio
                 new_extent = None
                 x1, y1, x2, y2 = (0, 0, 0, 0)
                 geom_rect = geom
                 geom_ratio = geom_rect.width() / geom_rect.height()
                 xa1 = geom_rect.xMinimum()
                 xa2 = geom_rect.xMaximum()
                 ya1 = geom_rect.yMinimum()
                 ya2 = geom_rect.yMaximum()

                 map_rect = self.composerMap.boundingRect()
                 map_ratio = map_rect.width() / map_rect.height()
                 # geometry height is too big
                 if geom_ratio < map_ratio:
                     y1 = ya1
                     y2 = ya2
                     x1 = (xa1 + xa2 + map_ratio * (ya1 - ya2)) / 2.0
                     x2 = x1 + map_ratio * (ya2 - ya1)
                     new_extent = core.QgsRectangle(x1, y1, x2, y2)
                 # geometry width is too big
                 elif geom_ratio > map_ratio:
                     x1 = xa1
                     x2 = xa2
                     y1 = (ya1 + ya2 + (xa1 - xa2) / map_ratio) / 2.0
                     y2 = y1 + (xa2 - xa1) / map_ratio
                     new_extent = core.QgsRectangle(x1, y1, x2, y2)
                 # same ratio: send geom bounding box
                 else:
                     new_extent = geom_rect
                 # add margin to computed extent
                 if margin:
                     new_extent.scale(1 + margin / 100.0)

                 return new_extent

         """
***************************************************************************************************************************************************
                 Generate the maps
***************************************************************************************************************************************************
         """
         def generer(self):
                 ## Makes the vector layer transparent except raster layers
                 ## Hide labels
                 layers = self.iface.legendInterface().layers()
                 for layer in layers:
                         if layer.type() <> QgsMapLayer.RasterLayer:
layer.rendererV2().symbol().setAlpha(0.3)
layer.setCustomProperty("labeling/enabled", "False")


                 ## Creation of QgsComposition
                 mapRenderer = self.iface.mapCanvas().mapRenderer()
                 c = QgsComposition(mapRenderer)

                 ## Format of the maps
                 c.setPaperSize(420, 297)
                 c.setPlotStyle(QgsComposition.Print)

                 ## Margins
                 margeBas       = 5
                 margeHaut      = 5
                 margeGauche    = 5
                 margeDroite    = 5
                 margeHautCarte = 0
                 margeBasCarte  = 50
                 margeSsCarte   = 5

                 ## Composer map
                 x, y = margeGauche, margeHaut
                 w, h = c.paperWidth()-margeGauche-margeDroite, 
c.paperHeight()-margeBasCarte-margeHaut
                 self.composerMap = QgsComposerMap(c,x,y,w,h)
self.composerMap.setPreviewMode(QgsComposerMap.Cache)
                 c.addItem(self.composerMap)

                 ## Title
                 clTitre = QgsComposerLabel(c)
                 clTitre.setItemPosition(margeGauche, c.paperHeight() - 
margeBasCarte + margeSsCarte)
                 clTitre.setFont(QFont( "Helvetica", 24, QFont.Bold ))
                 c.addItem(clTitre)

                 ## Logo file
                 ## Does not appear !! I don't know why
                 nomFichierLogo = 
QtGui.QFileDialog.getOpenFileName(None, u"Choose a logo :", 'C:/', 
"Image Files (*.png *.jpg *.bmp)")
                 if nomFichierLogo:
                         itemLogo = QgsComposerPicture(c)
                         itemLogo.setItemPosition(c.paperWidth() - 
margeDroite - 30, c.paperHeight() + margeSsCarte + 20, 30, 30)
                         itemLogo.setPicturePath(nomFichierLogo)
                         itemLogo.updateItem()
                         c.addItem(itemLogo)

                 ## Output folder
                 nomRep = QtGui.QFileDialog.getExistingDirectory(None, 
u"Choose an output folder :", 'C:/', QtGui.QFileDialog.ShowDirsOnly)


                 # Printer
                 printer = QtGui.QPrinter()
printer.setOutputFormat(QtGui.QPrinter.PdfFormat)
                 printer.setPaperSize(QSizeF(c.paperWidth(), 
c.paperHeight()), QtGui.QPrinter.Millimeter)
                 printer.setFullPage(True)
                 printer.setColorMode(QtGui.QPrinter.Color)
                 printer.setResolution(c.printResolution())


                 ## Iterate over groups
                 legend = self.iface.legendInterface()
                 groups = legend.groupLayerRelationship()
                 layers = legend.layers()

                 nbGroups = len(groups)
                 nbLayers = len(layers)

                 if nbLayers > 0 and len(nomRep) > 0 :

                         # Last group containts rasters => nbGroups - 1
                         g = 0
                         #for g in range(0,nbGroups-1):
                         for g in range(0,2):

                                 # File name
                                 nomCircuit = groups[g][0]
                                 nomCircuit = re.sub("[A-Za-z._\-]", '', 
nomCircuit)
                                 print nomCircuit

                                 nomFichier = nomRep + "\\" + nomCircuit 
+ ".pdf"

                                 if not os.path.isfile(nomFichier):

                                         ## Update title
                                         clTitre.setText("Track " + 
nomCircuit)
clTitre.adjustSizeToText()


                                         # Update transparency and labels
                                         # NB : do not use 
setLayerTransparency, problem with it I don't know why
layers[2*g].rendererV2().symbol().setWidth(2)
layers[2*g].rendererV2().symbol().setAlpha(1)
layers[2*g+1].setCustomProperty("labeling/enabled", "True")
layers[2*g+1].rendererV2().symbol().setAlpha(1)

                                         rectTrajet = 
layers[2*g].extent() # linear
                                         rectPtsArr = 
layers[2*g+1].extent() # points

                                        # extent definition
                                         rectGlb = QgsRectangle
                                         xMin = 
min(rectTrajet.xMinimum(), rectPtsArr.xMinimum())
                                         xMax = 
max(rectTrajet.xMaximum(), rectPtsArr.xMaximum())
                                         yMin = 
min(rectTrajet.yMinimum(), rectPtsArr.yMinimum())
                                         yMax = 
max(rectTrajet.yMaximum(), rectPtsArr.yMaximum())
                                         rectGlb = QgsRectangle(xMin, 
yMin, xMax, yMax)

self.composerMap.setNewExtent(self.getNewExtent(rectGlb, 10))
                                         self.composerMap.cache()


                                         # Filename
printer.setOutputFileName(nomFichier)

                                         # Launch printer
                                         pdfPainter = QPainter(printer)
                                         paperRectMM = 
printer.pageRect(QtGui.QPrinter.Millimeter)
                                         paperRectPixel = 
printer.pageRect(QtGui.QPrinter.DevicePixel)
                                         c.render(pdfPainter, 
paperRectPixel, paperRectMM)
                                         pdfPainter.end()


                                         # Layers back to their initial 
state
layers[2*g].rendererV2().symbol().setWidth(1)
layers[2*g].rendererV2().symbol().setAlpha(0.3)
layers[2*g+1].rendererV2().symbol().setAlpha(0.3)
layers[2*g+1].setCustomProperty("labeling/enabled", "False")

*



---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast.
http://www.avast.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/qgis-user/attachments/20150520/be804633/attachment.html>


More information about the Qgis-user mailing list