Geospatial animations with QGIS Atlas

Topi Tjukanov
Mar 14 · 8 min read

I’ve been doing a lot of animated maps during the last year or so. Seriously. A lot. I have also written a blog post on how to do them.

Most of these have been created using the QGIS Time Manager plugin, which is pretty awesome. Time Manager is great in many aspects, but somewhat limited when it comes to fine tuning the look of the output. This is mainly because your animations are limited to your QGIS screen resolution and can’t access the full power of the QGIS Print Layout.

Recently I got a new idea for a new kind of animated map. I got my first inspiration from Twitter from the following tweet, where a storm track is animated and the map moves with the storm, rather than map “camera” being focused in one place and elements moving there.

The animation above had been created using R & gganimate, but I started thinking if this could be done with QGIS. In the back of my head I had some stuff that Mr. Cartocalypse had posted to Twitter already a while ago with a similar idea.

As it turned out, QGIS can very well do this. With the help of QGIS Atlas.

What is QGIS Atlas?

Atlas is a component inside QGIS Print Layout that aims to help automating map production. This means that it can do a lot of things, but a typical use case might be a situation where you have a lot of administrative areas and you need to do a similar map for all of them. For example if I’d have to do a map about population distribution for each Finnish municipality (there are 311 of them), Atlas would definitely be my weapon of choice. You can see an example of Atlas usage and read more about in the link below.

So typically Atlas is for reports. I am pretty sure that this kind of animation with a “dynamically moving camera” wasn’t among the ideas when Atlas was initially developed. But I think quite often the most interesting and innovative things are done when a tool is used for something it wasn’t originally designed for.

One excellent source for learning more about Atlas is Alasdair Rae’s homepage, where he also has a lot of examples and tutorials on how to use it. Those helped me also here a lot.

Input data for your animation

To test this out, first you need data.

Basically you have two options in terms of “moving” data. First (+ the most logical) option is that you have points that represent some kind of tracks. The data should have timestamps or at least some kind of indication of the order of the points. This could be your own data from your fitness tracking app, vehicle locations (like I’m using later) or something completely different, like bird movement tracks from Movebank.org.

Second option is that you have a line, along which you will interpolate the points that will be the focus points of each animation frame. As an example I will use here a temporary LineString scratch layer, but this could also be e.g. storm tracks or a bus route. After creating the scratch layer, you can create points along the line (Vector processing → Points along geometry). The number of points (i.e. the distance) depends totally on your personal needs. Your animation could be anything between 2 frames and 200 000 frames (Well, this might already become a full length movie…).

Create a memory layer if you just want to try something out.

You will also need some kind of a background map, because if you your data is just moving in a void, you won’t see it moving at all 👀. Easiest option might be to use the OpenStreetMap background layer, like I am using in the image above. You can find that ready in your QGIS Browser under XYZ Tiles. Other options are some kind of an aerial image or a background map (e.g. via a WMS service) or then just some vector data that fits your purpose.

Animating frames with QGIS Atlas

Once you have your movement points and backgound data sorted, you should now open a new Print Layout under QGIS projects and add a new map to the layout. Once again the layout size and orientation may be different case by case.

Firstly in the menu on your right you should move to the Atlas tab and tick the box Generate an atlas. Then you should select your coverage layer (your points) from the drop-down menu, select an unique value for page name and tick the Sort by box and sort the features by a value that shows the correct order of the features. In the case of a point memory layer this is distance attribute, but it also could be a timestamp. Set that also as the page name.

Generate an Atlas, add your coverage layer, change Page name and sort the features accordingly

After this you should go to the Item properties tab on the right side of the screen and then click on the two things marked with yellow in the screenshot below:

  1. The box that says Controlled by Atlas
  2. The globe on top of the screen
Yellow things are they keys to success

After this if you click on the blue arrow on top of the screen to the right for a few times and if everything works as it should, you should see how the screen starts to magically move! You are now seeing the first frames of your future Oscar-winning movie!

They see me clickin’, they hatin’…

One thing that you probably want to do before advancing any further, is that you want to change the style in a way that only one dot appears on the map at a time. To achieve this, you should go back to the main QGIS window and open the properties of your Atlas layer. Then you should select Rule-based symbology and click filter. There you should open Expression String Builder and match the atlas_pagename with your own variable (in the example case it’s distance). Might sound complicated, but all steps can be encoded from the screenshot below.

It’s all there. Symbology → Rule-Based → filter → The function symbol → “your_attribute” = @atlas_pagename

Then you should click OK a few times (three, to be exact) and most of your points should disappear from the screen. But now if you go back to your layout screen and click on the blue arrow pointing right again, you should now see only one symbol per frame.

After this it’s all about your own QGIS skills and preferences what you want to do with the rest of the styling. Do you want to add multiple maps on your animation? Do you want to make the scale dynamic with a speed attribute?

Once you are happy with your results, you can export the frames from the Export Atlas button on top of the screen and then just wait for it to render.

Creating a video with FFmpeg

In the previous geogiffery blog post I described how to create a gif animation either with the help of an online service or GIMP. When you start to have more data (I’d say +200 frames) it might be good to expand your options a bit.

FFmpeg is an open-source command line tool that allows you (among many other things) to create videos from single frames and that’s what we are going to do with our exported frames.

I used the following command to create the animation. So I ran this in Powershell and of course the parameters depend on what you are doing and where your files are, but this is here to give you a rough idea.

D:\temp_pics\atlas_demo> C:\gis\software\ffmpeg\bin\ffmpeg.exe -r 25 -f image2 -i frame_%05d.png -crf 25 -c:v libx264 -pix_
fmt yuv420p D:\temp_pics\kemijarvi.mp4

The -r parameter defines the framerate. I am using here a very high framerate, bevause the animation had more than 3000 frames. -f is the input format, -i is the input file name pattern (e.g. frame_00122.png), -crf defines compression, -c:v is the codec to use and -pix_fmt defines the pixel format. These parameters were the result of a few iteration rounds and worked for me here. To see more and understand better, you can check the docs for FFmpeg here. You can take this much further and very easily add music and other things to your video.

It’s good to notice that the normal Atlas output file name format (output_1 etc.) doesn’t work with FFmpeg , but instead you have to make them fixed lenght. I wrote the following small Python script to rename them.

import osfor file in os.listdir('D:/temp_pics/atlas_demo'):
suffix = file.split('_')[1]
num = suffix.split('.')[0]
outsuffix = num.zfill(5)
newname = 'D:/temp_pics/atlas_demo/frame_' + outsuffix + '.png'
oldname = 'D:/temp_pics/atlas_demo/' + file
os.rename(oldname, newname)

Feel free to use that if you have a lot of files that need renaming.

Final products

I created a few different things. First one is a ~3000 frame animation with two maps (overview and a normal map), a WMS background layer and a dynamic zoom value. This shows a 14 hour train trip from Helsinki to Kemijärvi in 2 minutes. Data for this is from the National Land Survey and Finnish Transport Agency.

The following video is a shorter trip on the tracks with tram number 4 travelling through Helsinki. Data via Digitransit API.

I also tried something different, with shorter length and a different theme. Hurricane Rita’s tracks from 2015 in a short gif (created with GIMP). The size of the circle represents the wind speeds (trick in the styling is ‘<=’ to do it cumulatively). Also notice how I used the expression builder in the upper right corner. Background data from Natural Earth & EOX and hurricane tracks from NOAA.

Hurricane Rita advancing in the Caribbean.

Happy geogiffin’! Please share your own animations on the WORLD WIDE INTERNET for me and others to see 🤓

edit: After publishing the story I asked on Twitter for some comments and got a few good pointers from Mr. Cartocalypse:

— — — — — —

On a side note, I recently started working at Gispo, a small Finnish IT company where among other things help our customers to use open geospatial data and open source geospatial solutions . You can find more about me via Twitter or my website.

Topi Tjukanov

Written by

I mostly put lines, points and polygons on maps 🌍