QGIS Map Design – Free Christmas DLC

It’s that time of the year again. When it’s dark and cold on the northern hemisphere, let’s grab a warm beverage of your choice and get mapping.

Inspired by the latest QGIS Open Day Freestyle Mapping Challenge, I set out to explore the Quantarctica project dataset. Today, I want to share with you the resulting map series. Like all recipes in QGIS Map Design, this blog post walks you through the process of creating these maps and provides all the resources to reproduce them yourself.

The historic Antarctic expedition of Roald Amundsen is one of five expedition routes mapped by the Quantarctica project which provides the data for our Christmas DLC maps.

This recipe assumes familiarity with QGIS styling, labeling, and layout creating basics, so we can focus on exciting new tips and tricks.

Base Map

Our map uses six layers of the Quantarctica dataset. The geographic context is provided by the ADD Simple basemap and Overview place name layers together with the South pole and Antarctic circle layers.

The two fonts used on this map are Arial and Steelfish.

The historic context is provided by the Five historic expedition routes and Historic stations layers. To show the travel direction of the expedition routes, we can create a trail of small arrow symbols by combining a simple line with custom dash pattern and a marker line:

So far, the map is pretty crowded because we see all five expeditions at once.

Let’s set up the Atlas map series, so we can create a dedicated map for each expedition.

Atlas Map Series

The historic expeditions have been digitized as ten line features in order to be able to distinguish between sections of the routes traveled by sea, land, and even air:

Counting the distinct leader values, there are actually six expeditions in this layer, however only five of them include sea routes.

Focusing on the five earliest expeditions, all of them contain sea routes. We can therefore set up the Atlas by filtering the route features to get only the five sea routes:

This setup will ensure that our Atlas will generate a map series with one map per expedition leader.

Make sure to activate the Altas preview mode now.

Filtering Routes & Stations

Back in the main QGIS window, we now can access the @atlas_feature to filter the routes layer accordingly. We want to show the sea route feature, as well as any other route feature that belongs to the same expedition leader:

Fun With Labels

So far, our map only shows basic labels for geographic features. In the following steps, we will add labels to the expedition routes and historical stations. Finally, we’ll use a rule-based labeling hack to put the finishing touches on our map.

Smooth Route Labels

Many of the expedition routes are anything but straight. They twist and turn and so do the letters of any labels we try to put on them. This effect becomes particularly prominent, when using large label fonts.

To create smoother looking labels, we can use the Geometry Generator (in the Label Placement tab) to create a smoother base line for labeling using an expression like:

smooth(simplify($geometry, 100000), 2)
The map in the background shows the generated simplified line geometry for illustration purposes.

Multi-color Labels

To show the station names and operating years in different colors, we can use HTML label formatting. To do so, we need to enable “Allow HTML formatting” (in the Label Text tab). Then we can build our label expression.

For this label, we combine three column (name, year_start, and year_end). Since year_end is empty (NULL) for some stations, it is important that we use the concat function (instead of the || operator). Otherwise, stations with a NULL value would not be labeled at all:

concat("name",
       '? <span style="color:#307f7f">(',
          "year_start", '-', "year_end",
       ')</span>' )

The ? character is used to insert a line break using the “Wrap on character” setting (in the Label Formatting tab).

Snowflakes *❆❅*

Last, but not least, for some (completely optional) Christmas spirit: let’s make it snow!

The snowflake styling trick used in this map is based solely on Unicode snowflake symbols and rule-based labeling.

As shown in this screenshot, the preview label color is red but it is over-ruled by the project variable flake_color.

By creating multiple rules that all apply to the same (land) polygons in our base map, we can create a random snowflake pattern. Randomness is introduced on different levels:

  • The label font size is randomized, e.g. rand(15, 60).
  • The label rotation is randomized by using the “free (angled)” placement mode.

Different rules have different priorities, with higher priority values assigned to label rules with larger font sizes.

The snowflake color can be adjusted by changing the project variable flake_color (in Project Properties | Variables). This way, we can change the color of all snow flakes at once, without having to edit every individual rule.

So Much More

There’s much more to discover in this project. For example, the label substitutions used to shorten the island labels or the decorations added in the layout:

So go grab the project and happy mapping!

Please ensure that you acknowledge or cite Quantarctica and the Norwegian Polar Institute if you use their dataset in your work.

Setting up PyQGIS3 with VSCode & Python3 on Windows

ModuleNotFoundError: No module named 'qgis'

This error got you down? Here’s how I solved it in my vscode and Python and QGIS environment on Windows.


This blog post by Gary is excellent for building a development environment for PyQGIS on Windows: Quick Guide to Getting Started with PyQGIS3 On Windows (Spatialgalaxy.net).

In this post we put a slight twist on it, just to be different, and to learn to use Visual Studio Code, on Windows, and without external setup scripts. There were multiple issues that held me back on it this but ultimately it was just my knowledge of vscode that needed an upgrade.

In a nutshell, for a minimal working example, you need four components: a QGIS install, a vscode workspace file, a .env file, and a Python script in the same folder.

QGIS install

In this case, I use a standard release installer from QGIS.org to get set up on Windows (not OSGeo4W). The install location is on a secondary drive, not the long file name with a couple of spaces – that is not a concern with this approach.

Note that the Python modules for both PyQGIS, PyQT5 are included in this install! More below on that.

D:\Program Files\QGIS 3.12\

vscode workspace

I’ve worked on various development projects with vscode before and never worried much about this workspace concept with them.

If you create a file by hand, it will then allow you to open the folder as a workspace. I suggest creating all the files below first, then opening it in vscode (File-> Open Folder).

If you do not have one of these JSON format files already, it will prompt you to create/save one. The one it created for me wasn’t very helpful as it had the wrong paths in it and it messed me up further.

Here is my workspace definition file, saved in:

c:\users\tyler\source\repos\diy-gis\workspace.code-workspace
{
	"folders": [
		{
			"name": "app",
			"path": "C:\\Users\\tyler\\source\\repos\\diy-gis"
		}
	]
}

All the file does is define the path for the rest of the project. This seems important when you go to launch the Python script,we didn’t worry about any other settings in this file when doing my testing. But it doesn’t mean it’s good enough for further uses especially build/deploy scenarios.

vscode .env file

The .env file is used to set environment variables before running a Python project in a vscode. It appears to require a workspace to be defined as well, see above.

Common system-wide/global Windows environment settings should work but I wanted this to all be self-contained in a single project workspace.

In the .env file, we simply put two lines, one for the PATH and one for the PYTHONPATH to point to our QGIS installation. Adjust for your version and path.

PATH=$PATH;"D:\Program Files\QGIS 3.18\bin\";"D:\Program Files\QGIS 3.18\apps\qgis\bin"
PYTHONPATH="D:\Program Files\QGIS 3.12\apps\qgis\python"

Basic Python app with QGIS module loaded

As we were early in this project let’s ensure that PyQT5 and QGIS modules would load into the Python project.

In the QGIS apps\qgis\python folder are the modules that Python will use, per the .env file above.

Some places will tell you to install PyQT5 with pip and that is not necessary if you have things set up this way. Plus you’ll know that your versions of QT and PyQGIS will be compatible if you use the same location for the modules.

This code uses both those modules and builds a very basic Hello World app. The file is app1.py in my workspace.

import sys
import qgis

from PyQt5.QtWidgets import QApplication, QWidget, QLabel

def window():
   app = QApplication(sys.argv)
   widget = QWidget()

   textLabel = QLabel(widget)
   textLabel.setText("Hello World!")
   textLabel.move(110,85)

   widget.setGeometry(50,50,320,200)
   widget.setWindowTitle("PyQt5 Example")
   widget.show()
   sys.exit(app.exec_())

if __name__ == '__main__':
   window()

Next, with the app1.py open in vscode, I run the app script from the Run -> Run Without Debugging tool and see the application window pop up!

If things go wrong, check the terminal/console for any errors, here is my terminal output from vscode:

PS C:\Users\tyler\source\repos\diy-gis>  c:; cd 'c:\Users\tyler\source\repos\diy-gis'; & 'C:\python38\python.exe' 'c:\Users\tyler\.vscode\extensions\ms-python.python-2021.10.1365161279\pythonFiles\lib\python\debugpy\launcher' '54781' '--' 'c:\Users\tyler\source\repos\diy-gis\app1.py' 

If I comment out the PYTHONPATH from the .env file, I get my errors finding the PyQGIS module: qgis. Note that I do not get errors for PyQt because I also had them installed by pip in my main Python installation.

Traceback (most recent call last):
  File "c:\Users\tyler\source\repos\diy-gis\app1.py", line 2, in <module>
    import qgis
ModuleNotFoundError: No module named 'qgis'
PS C:\Users\tyler\source\repos\diy-gis>

Resources

The PyQGIS Programmer's Guide 3 - Extending QGIS 3 with Python 3 by Gary Sherman

%d bloggers like this: