Using Qgis Python Scripting in the NZ Rail Maps Project: 3 – Volumes Formatting

The third area of Qgis scripting for the NZ Rail Maps project is specifically focused on formatting the Volumes layout images and is used to generate a subtitle displayed in the title bar of each Volumes image. This subtitle informs the user of the year of each aerial image view that is part of the particular web map image.

This is implemented directly in the Composer by creating a label field to display the required text and making its source a couple of custom Python functions to process the content of the Filename field. In the 2nd part of this series we explained how the Filename field is used to automate Volumes images creation by automatically selecting the source layers as well as specifying the physical name of the image as saved to disk. The Filename field is displayed in the lower left footer bar of each image and makes it easy to correlate a particular web map image to a physical location.

The Subtitle field was first added to Volumes maps on 2021-08-05 and the code used to create it is fairly straightforward. There are two very simple Python functions to achieve this. The actual field’s source expression is as follows:

[% nzrmGetSubtitle(nzrmGetFilename(‘Landscape 16:9 Header Nav Copyright Filename 2021’, ‘Filename’))%]

The square brackets and percent signs tell the Composer that this is a custom expression instead of static text. The expression calls a function called nzrmGetSubtitle that takes as input, the results of calling a second function, nzrmGetFilename, which takes as its input, the name of the composer layout and the Filename field within it.

The Qgis composer’s Expression Editor includes a section called “Function Editor”. This enables the creation of custom functions that can be used alongside the built in functions. These custom functions are written in Python and saved in the user’s profile folders. A custom function is needed to obtain input from a Composer field because the built in functions all assume the user needs to read data from source layers, rather than a specific field on the layout itself. The custom function works by calling the QGIS API directly and in that respect is similar to the code in part 2 of this series that performed the same type of processing of the Filename field to select source fields. In this case the objective is to specify the text to be displayed in the Subtitle field.


Firstly here is the function nzrmGetFilename. It is virtually identical to part of the scripting used in the Qgis map GUI to create Volumes images as shown in Part 2 of this article series, specifically the part that reads the value of the Filename field from the layout. There are only small differences associated with the specific formatting of functions to work in the slighty different Composer expressions environment.

from qgis.core import *
from qgis.gui import *

@qgsfunction(args=’auto’, group=’Custom’)
def nzrmGetFilename(layoutTitle, itemId, feature, parent):
project = QgsProject.instance()
projectLayoutManager = project.layoutManager()
layout = projectLayoutManager.layoutByName(layoutTitle)
fileNameLabel = layout.itemById(itemId)
fileNameText = fileNameLabel.text()
return fileNameText


And here is the function nzrmGetSubtitle. This one takes the Filename and interprets it to generate the Subtitle text. Again part of the code is copied from the Volumes creation script to extract the year as the last 4 characters of the filename. The resulting text is generated by interpreting the extracted year value.

from qgis.core import *
from qgis.gui import *

@qgsfunction(args=’auto’, group=’Custom’)
def nzrmGetSubtitle(fileName, feature, parent):
fileNameParts = fileName.split(‘-‘)
yearStr = fileNameParts[-1]
yearVal = int(yearStr)
if yearVal == 0:
return ‘Combined Diagram’
else:
return ‘Aerial ‘ + yearStr