Computed symbology with QGIS geometry generator
In the process of working to optimise the QGIS cartographic templates over at Outdooractive, I have been developing custom geometry manipulation functions to aid better automatic map labelling. Inflexibility in the QGIS labelling engine when it comes to complex data-dependent symbology and interactions between layers means sometimes the best available solution is to just export all the labels and do the work manually. Looking for alternatives with the aim to minimise post-processing in Illustrator, I tried bypassing the default labelling QGIS engine options. Instead, I opted for resolving difficult label collision situations using Python in the QGIS geometry generator. Here are two example layers where this was used.
In mountain peak symbology, labels and symbols are inseparable and the priority depends on the prominence of mountains. At the same time, when mountains are isolated, they are usually shown irrespective of height. This makes it hard to use both symbology and labelling interdependently, as well as setting more complex priority criteria. This is why I went for a pure symbology approach that creates a buffer (paper units at scale) around each mountain and tests for intersections with surrounding features. On collision, the lower mountain is hidden. This leads to local chains the end at the tallest mountain that remains visible. This function is run at each render, so the prioritisation is completely responsive. Labels are rendered as Font Markers in the layer symbology, so they act concurrently with the mountain peak symbols.
Another interesting case is contours. As of early 2021, QGIS had no capability to label contours in sensible cartographic ladders (like is found in Maplex). This is a fairly complex computational problem because contour features often do not share as much as it looks, and it becomes hard to assosciate labelling lines with them. This is a good use case for using the geometry generator to transform features before they are labelled. My function uses the current map view to create four global focal points. Each contour linestring is cropped to four segments that are closest to these points. This forms candidate labelling positions for each contour that preserve the original linestring orientation and align nicely with each other. When two segments intersect, they merge to avoid double labels. The images show a default QGIS label placement versus the function results (cropped segments in light green). This is not the perfect laddered labelling solution, but it takes a lot of weight off the cartographer's shoulders.