The code snippets on this page need the following imports:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import os

from qgis.core import (
    QgsGeometry,
    QgsMapSettings,
    QgsPrintLayout,
    QgsMapSettings,
    QgsMapRendererParallelJob,
    QgsLayoutItemLabel,
    QgsLayoutItemLegend,
    QgsLayoutItemMap,
    QgsLayoutItemPolygon,
    QgsLayoutItemScaleBar,
    QgsLayoutExporter,
    QgsLayoutItem,
    QgsLayoutPoint,
    QgsLayoutSize,
    QgsUnitTypes,
    QgsProject,
    QgsFillSymbol,
)

from qgis.PyQt.QtGui import (
    QPolygonF,
    QColor,
)

from qgis.PyQt.QtCore import (
    QPointF,
    QRectF,
    QSize,
)

10. Randarea hărților și imprimarea

There are generally two approaches when input data should be rendered as a map: either do it quick way using QgsMapRendererJob or produce more fine-tuned output by composing the map with the QgsLayout class.

10.1. Randarea simplă

The rendering is done creating a QgsMapSettings object to define the rendering settings, and then constructing a QgsMapRendererJob with those settings. The latter is then used to create the resulting image.

Iată un exemplu:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
image_location = os.path.join(QgsProject.instance().homePath(), "render.png")

vlayer = iface.activeLayer()
settings = QgsMapSettings()
settings.setLayers([vlayer])
settings.setBackgroundColor(QColor(255, 255, 255))
settings.setOutputSize(QSize(800, 600))
settings.setExtent(vlayer.extent())

render = QgsMapRendererParallelJob(settings)

def finished():
    img = render.renderedImage()
    # save the image; e.g. img.save("/Users/myuser/render.png","png")
    img.save(image_location, "png")

render.finished.connect(finished)

render.start()

10.2. Randarea straturilor cu diferite CRS-uri

If you have more than one layer and they have a different CRS, the simple example above will probably not work: to get the right values from the extent calculations you have to explicitly set the destination CRS

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

10.3. Output using print layout

Print layout is a very handy tool if you would like to do a more sophisticated output than the simple rendering shown above. It is possible to create complex map layouts consisting of map views, labels, legend, tables and other elements that are usually present on paper maps. The layouts can be then exported to PDF, raster images or directly printed on a printer.

The layout consists of a bunch of classes. They all belong to the core library. QGIS application has a convenient GUI for placement of the elements, though it is not available in the GUI library. If you are not familiar with Qt Graphics View framework, then you are encouraged to check the documentation now, because the layout is based on it.

The central class of the layout is the QgsLayout class, which is derived from the Qt QGraphicsScene class. Let us create an instance of it:

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

Now we can add various elements (map, label, …) to the layout. All these objects are represented by classes that inherit from the base QgsLayoutItem class.

Here’s a description of some of the main layout items that can be added to a layout.

  • harta — acest element indică bibliotecilor unde să pună harta. Vom crea o hartă și o vom întinde peste întreaga dimensiune a hârtiei

    map = QgsLayoutItemMap(layout)
    layout.addItem(map)
    
  • eticheta — permite afișarea textelor. Este posibilă modificarea fontului, culoarea, alinierea și marginea

    label = QgsLayoutItemLabel(layout)
    label.setText("Hello world")
    label.adjustSizeToText()
    layout.addItem(label)
    
  • legenda

    legend = QgsLayoutItemLegend(layout)
    legend.setLinkedMap(map) # map is an instance of QgsLayoutItemMap
    layout.addItem(legend)
    
  • scara grafică

    1
    2
    3
    4
    5
    item = QgsLayoutItemScaleBar(layout)
    item.setStyle('Numeric') # optionally modify the style
    item.setLinkedMap(map) # map is an instance of QgsLayoutItemMap
    item.applyDefaultSize()
    layout.addItem(item)
    
  • săgeată

  • imagine

  • basic shape

  • nodes based shape

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

Once an item is added to the layout, it can be moved and resized:

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

A frame is drawn around each item by default. You can remove it as follows:

# for a composer label
label.setFrameEnabled(False)

Besides creating the layout items by hand, QGIS has support for layout templates which are essentially compositions with all their items saved to a .qpt file (with XML syntax).

Once the composition is ready (the layout items have been created and added to the composition), we can proceed to produce a raster and/or vector output.

10.3.1. Exporting the layout

To export a layout, the QgsLayoutExporter class must be used.

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

exporter = QgsLayoutExporter(layout)
exporter.exportToPdf(pdf_path, QgsLayoutExporter.PdfExportSettings())

Use the exportToImage() in case you want to export to an image instead of a PDF file.

10.3.2. Exporting a layout atlas

If you want to export all pages from a layout that has the atlas option configured and enabled, you need to use the atlas() method in the exporter (QgsLayoutExporter) with small adjustments. In the following example, the pages are exported to PNG images:

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

Notice that the outputs will be saved in the base path folder, using the output filename expression configured on atlas.