10. Rendu cartographique et Impression

Indication

Les extraits de code sur cette page nécessitent les importations suivantes :

 1import os
 2
 3from qgis.core import (
 4    QgsGeometry,
 5    QgsMapSettings,
 6    QgsPrintLayout,
 7    QgsMapSettings,
 8    QgsMapRendererParallelJob,
 9    QgsLayoutItemLabel,
10    QgsLayoutItemLegend,
11    QgsLayoutItemMap,
12    QgsLayoutItemPolygon,
13    QgsLayoutItemScaleBar,
14    QgsLayoutExporter,
15    QgsLayoutItem,
16    QgsLayoutPoint,
17    QgsLayoutSize,
18    QgsUnitTypes,
19    QgsProject,
20    QgsFillSymbol,
21)
22
23from qgis.PyQt.QtGui import (
24    QPolygonF,
25    QColor,
26)
27
28from qgis.PyQt.QtCore import (
29    QPointF,
30    QRectF,
31    QSize,
32)

Il y a généralement deux approches lorsque les données d’entrée doivent être rendues sous forme de carte : soit le faire rapidement en utilisant QgsMapRendererJob, soit produire une sortie plus fine en composant la carte avec la classe QgsLayout.

10.1. Rendu simple

Le rendu est effectué en créant un objet QgsMapSettings pour définir les paramètres de rendu, puis en construisant un objet QgsMapRendererJob avec ces paramètres. Ce dernier est ensuite utilisé pour créer l’image résultante.

Voici un exemple:

 1image_location = os.path.join(QgsProject.instance().homePath(), "render.png")
 2
 3vlayer = iface.activeLayer()
 4settings = QgsMapSettings()
 5settings.setLayers([vlayer])
 6settings.setBackgroundColor(QColor(255, 255, 255))
 7settings.setOutputSize(QSize(800, 600))
 8settings.setExtent(vlayer.extent())
 9
10render = QgsMapRendererParallelJob(settings)
11
12def finished():
13    img = render.renderedImage()
14    # save the image; e.g. img.save("/Users/myuser/render.png","png")
15    img.save(image_location, "png")
16
17render.finished.connect(finished)
18
19# Start the rendering
20render.start()
21
22# The following loop is not normally required, we
23# are using it here because this is a standalone example.
24from qgis.PyQt.QtCore import QEventLoop
25loop = QEventLoop()
26render.finished.connect(loop.quit)
27loop.exec_()

10.2. Rendu des couches ayant différents SCR

Si vous avez plus d’une couche et qu’elles ont un CRS différent, l’exemple simple ci-dessus ne fonctionnera probablement pas : pour obtenir les bonnes valeurs à partir des calculs d’étendue, vous devez définir explicitement le CRS de destination

layers = [iface.activeLayer()]
settings = QgsMapSettings()
settings.setLayers(layers)
settings.setDestinationCrs(layers[0].crs())

10.3. Sortie en utilisant la mise en page

La mise en page est un outil très pratique si vous souhaitez obtenir un résultat plus sophistiqué que le simple rendu présenté ci-dessus. Il est possible de créer des mises en page complexes composées de vues de cartes, d’étiquettes, de légendes, de tableaux et d’autres éléments qui sont généralement présents sur les cartes papier. Les mises en page peuvent ensuite être exportées au format PDF, en images raster ou directement imprimées sur une imprimante.

La mise en page consiste en un ensemble de classes. Elles appartiennent toutes à la bibliothèque centrale. L’application QGIS dispose d’une interface graphique pratique pour le placement des éléments, bien qu’elle ne soit pas disponible dans la bibliothèque GUI. Si vous n’êtes pas familiés avec le Qt Graphics View framework, alors vous êtes encouragé à consulter la documentation dès maintenant, car la mise en page est basée sur celui-ci.

La classe centrale de la mise en page est la classe QgsLayout, qui est dérivée de la classe Qt QGraphicsScene. Créons une instance de celle-ci :

project = QgsProject.instance()
layout = QgsPrintLayout(project)
layout.initializeDefaults()

Cette méthode initialise la mise en page avec certains paramètres par défaut, spécifiquement en ajoutant une page A4 vide à la mise en page. Vous pouvez créer des mises en page sans appeler la méthode initializeDefaults(), mais vous devrez vous charger vous-même d’ajouter des pages à la mise en page.

Le code précédent crée une mise en page « temporaire » qui n’est pas visible dans l’interface graphique. Cela peut être pratique pour, par exemple, ajouter rapidement quelques éléments et exporter sans modifier le projet lui-même ni exposer ces changements à l’utilisateur. Si vous voulez que la mise en page soit sauvegardée/restaurée avec le projet et disponible dans le gestionnaire de mise en page, alors ajoutez :

layout.setName("MyLayout")
project.layoutManager().addLayout(layout)

Nous pouvons maintenant ajouter divers éléments (carte, étiquette, …) à la mise en page. Tous ces objets sont représentés par des classes qui héritent de la classe de base QgsLayoutItem.

Voici une description de certains des principaux éléments qui peuvent être ajoutés à une mise en page.

  • map — Ici nous créons une carte d’une taille personnalisée et rendons le canevas de la carte actuelle

    1map = QgsLayoutItemMap(layout)
    2# Set map item position and size (by default, it is a 0 width/0 height item placed at 0,0)
    3map.attemptMove(QgsLayoutPoint(5,5, QgsUnitTypes.LayoutMillimeters))
    4map.attemptResize(QgsLayoutSize(200,200, QgsUnitTypes.LayoutMillimeters))
    5# Provide an extent to render
    6map.zoomToExtent(iface.mapCanvas().extent())
    7layout.addLayoutItem(map)
    
  • étiquette — permet d’afficher des étiquettes. Il est possible d’en modifier la police, la couleur, l’alignement et les marges:

    label = QgsLayoutItemLabel(layout)
    label.setText("Hello world")
    label.adjustSizeToText()
    layout.addLayoutItem(label)
    
  • légende

    legend = QgsLayoutItemLegend(layout)
    legend.setLinkedMap(map) # map is an instance of QgsLayoutItemMap
    layout.addLayoutItem(legend)
    
  • Échelle graphique

    1item = QgsLayoutItemScaleBar(layout)
    2item.setStyle('Numeric') # optionally modify the style
    3item.setLinkedMap(map) # map is an instance of QgsLayoutItemMap
    4item.applyDefaultSize()
    5layout.addLayoutItem(item)
    
  • flèche

  • image

  • Forme simple

  • Forme basée sur les nœuds

     1polygon = QPolygonF()
     2polygon.append(QPointF(0.0, 0.0))
     3polygon.append(QPointF(100.0, 0.0))
     4polygon.append(QPointF(200.0, 100.0))
     5polygon.append(QPointF(100.0, 200.0))
     6
     7polygonItem = QgsLayoutItemPolygon(polygon, layout)
     8layout.addLayoutItem(polygonItem)
     9
    10props = {}
    11props["color"] = "green"
    12props["style"] = "solid"
    13props["style_border"] = "solid"
    14props["color_border"] = "black"
    15props["width_border"] = "10.0"
    16props["joinstyle"] = "miter"
    17
    18symbol = QgsFillSymbol.createSimple(props)
    19polygonItem.setSymbol(symbol)
    
  • table

Une fois qu’un élément est ajouté à la mise en page, il peut être déplacé et redimensionné :

item.attemptMove(QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters))
item.attemptResize(QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters))

Par défaut, un cadre est dessiné autour de chaque élément. Vous pouvez le supprimer comme suit

# for a composer label
label.setFrameEnabled(False)

Outre la création manuelle des éléments de mise en page, QGIS prend en charge les modèles de mise en page qui sont essentiellement des compositions dont tous les éléments sont enregistrés dans un fichier .qpt (avec une syntaxe XML).

Une fois que la composition est prête (les éléments de mise en page ont été créés et ajoutés à la composition), nous pouvons procéder à la production d’une sortie raster et/ou vecteur.

10.3.1. Exporter la mise en page

Pour exporter une mise en page, la classe QgsLayoutExporter doit être utilisée.

1base_path = os.path.join(QgsProject.instance().homePath())
2pdf_path = os.path.join(base_path, "output.pdf")
3
4exporter = QgsLayoutExporter(layout)
5exporter.exportToPdf(pdf_path, QgsLayoutExporter.PdfExportSettings())

Utilisez la méthode exportToImage() au cas où vous voudriez exporter vers une image au lieu d’un fichier PDF.

10.3.2. Exporter un atlas

Si vous souhaitez exporter toutes les pages d’une mise en page pour laquelle l’option atlas est configurée et activée, vous devez utiliser la méthode atlas() dans l’exportateur (QgsLayoutExporter) avec de petits ajustements. Dans l’exemple suivant, les pages sont exportées en image PNG :

exporter.exportToImage(layout.atlas(), base_path, 'png', QgsLayoutExporter.ImageExportSettings())

Notez que les sorties seront enregistrées dans le dossier du chemin de base, en utilisant l’expression du nom de fichier de sortie configurée sur l’atlas.