Page 3 of 80 (1584 posts)

  • talks about »


Last update:
Tue Oct 13 21:15:10 2015

A Django site.

QGIS Planet

QGIS on the rise with journalists

If you are following QGIS on Twitter you’ve probably noticed the increasing number of tweets by journalists using QGIS.

For example this map in the Financial Times by Hannah Dormido

or this one with overview maps and three different levels of details

or this map with semi-transparent label backgrounds and nice flag images

or even Time Manager animations by raoulranoa in the Los Angeles Times

I think this is a great development and a sign of how wide-spread QGIS usage is today.

If you know of any other examples or if you are a journalist using QGIS yourself, I’d love to see more!

Customising the TimeManager time stamp

TimeManager is a fantastic plugin for QGIS which allows you to create animated maps from your data. You can read all about it here and here, and there’s a really nice demonstration of it here.

I’ve been playing with TimeManager a fair bit over the last month, and thought I’d share a quick tip on improving the appearance of TimeManager’s time stamp. TimeManager includes some basic functionality for placing a time stamp in the corner of your outputs, but it’s fairly limited. There’s only some basic appearance options, and no way to control the date or time formats displayed.

Default TimeManager time stamp

Default TimeManager time stamp

But, there’s a trick we can use to get around this: use a temporary point layer for the time stamp label. Let me elaborate:

  1. Create a throwaway point layer. It doesn’t matter what fields or format this layer has.
  2. Add a single point feature to this layer at the place you’d like the improved time stamp to appear at.

    Add a single point feature

    …add a single point feature

  3. We don’t want to see the marker, so hide the symbol for this layer by setting it to use a transparent fill and outline.

    Transparent fill and outline

    Transparent fill and outline

  4. Then, enable labels for this layer. Here’s the trick – set the label expression for the label to use “animation_datetime()” (or for QGIS 2.8, “$animation_datetime”). This is a custom function provided by the TimeManager plugin which evaluates to the current frame’s date and time.

    Setting the layer's label expression

    Setting the layer’s label expression

  5. Now, you can use all the built-in options within QGIS for styling this label. Buffers, drop shadows, background shapes… anything!

    ...tweaking the label appearance

    …tweaking the label appearance

  6. Apply and check. Much nicer!

    Formatted timestamp

    A nicely formatted time stamp

  7. To tweak the formatting of the time stamp’s date and time, you can modify the label expression using the built-in ‘format_date’, ‘year’, ‘month’, etc functions. Let’s try “format_date(animation_datetime(),’ddd dd MMM yyyy’)”:

    Tweaked expression

    Tweaked expression

Now, our final formatted time stamp looks like this:

Final, formatted time stamp

Final, formatted time stamp

…and there we go. Using this simple trick allows you to take advantage of all the possibilities which the QGIS labelling and expression engines allow!

*Bonus points for the first person to use this technique along with data defined controls for animating the label colour/size!

Video tutorial: animated heatmaps with QGIS

Do you like the QGIS heatmap functionality? Did you know that QGIS can also create animated heatmaps?

The following video tutorial shows all necessary steps. To reproduce it, you can get the sample data from my Time Manager workshop at #QGIS2015.

Second report

What do I have completed this week?

  • A new implementation was designed to take into account several algorithms running. (using bounded signals)

  • Deep analysis of the processing in order to fit this new design into the current implementation of the Processing toolbox

  • Thread/Signal debugging

  • Fix the problem that makes QGIS crash when starting the new thread


What am I going to achieve for the next week?

Continue working on the new design of the multithreading support.

Is there any blocking issue?

There is no blocking issue for now.

First report

What do I have completed this week?

  • New implementation of the AlgorithmExecutor subclassing QObject.
  • Mechanism to deal with crashing Algorithms: when there is an exception during the algorithm execution, a signal is emitted in order to allow the main thread to make the other thread quit.
  • Use signal to connect the algorithm progress signal to the setPercentage slot in the ProgressBar


In the runAlgorithm method of the Processing class I changed the code associated with the runalg in order to support multithreading. Each time that an algorithm is running through the QGIS python console, a new thread and a new instance of the algorithm executor are created. The signals of the AlgorithmExecutor are connected to the thread signal in order to quit the thread and run the algorithm when the thread starts. While the algorithm is running, the main thread waits for the algorithm to finish and then proceed to show the output (first approach)


What am I going to achieve for the next week?

Create a non-blocking version of the processing in order to the interface not wait for the algorithm to finish.

Is there any blocking issue?

QGIS seems to crash randomly when starting the new thread and, when it doesn’t crash, the output of the algorithm is None, which may indicate that the algorithm is crashing in the new thread.


The complete report about the crashing can be found here.

Fourth report

What do I have completed this week?

  • The progress signal is successfully connected to both progress bar (when running from the console) and AlgorithmDialog (When using the processing toolbox).
  • Fixed the bug that makes the algorithm return “None”.
  • Fixed the bug that makes QGIS crash (sometimes) after the first time we run the algorithm.
  • The multithreading on the AlgorithmDialog seems to work fine.
  • More general implementation that allows to test the multithreading with any algorithm.

What am I going to achieve for the next week?

  • Solve the issue with the outputs.
  • Figure out why the processAlgorithm is not being called.
  • Test the algorithms on python console and AlgorithmDialog.
  • Bug fixes.

Is there any blocking issue?

  • Problem loading the outputs from the algorithm.
  • Have some university deadlines that may affect my work time on the project.


Third report

What do I have completed this week?

  • Using signals from the GeoAlgorithm to print the progress on QGIS python console
  • Code refactoring
  • Debugging
  • Multithread when running the algorithm through the AlgorithmDialog

What am I going to achieve for the next week?

  • Finish the multithread on the AlgorithmDialog
  • Connect the progress signal to the progress bar
  • Fix a bug that makes QGIS crash (sometimes) after the first time we run the algorithm
  • Fix a bug that makes the algorithm return “None”

Is there any blocking issue?

Last week I had less time to work on the project due to my university exams and projects. I still have some university projects to finish till the end of the semester that may affect GSoC in the next week.

QGIS 2.10 symbology feature preview

With the release of 2.10 right around the corner, it’s time to have a look at the new features this version of QGIS will bring. One area which has received a lot of development attention is layer styling. In particular, I want to point out the following new features:

1. Graduated symbol size

The graduated renderer has been expanded. Formerly, only color-graduated symbols could be created automatically. Now, it is possible to choose between color and size-graduated styles:

Screenshot 2015-06-21 18.39.25

2. Symbol size assistant

On a similar note, I’m sure you’ll enjoy the size assistant for data-defined size:

Screenshot 2015-06-21 23.16.10 Screenshot 2015-06-21 23.16.01

What’s particularly great about this feature is that it also creates a proper legend for the data-defined sizes:

Screenshot 2015-06-21 23.18.46

3. Interactive class exploration and definition

Another great addition to the graduated renderer dialog is the histogram tab which visualizes the distribution of values as well as the defined class borders. Additionally, the user can interactively change the classes by moving the class borders:

Screenshot 2015-06-21 18.43.09

4. Live layer effects

Since Nyall’s crowd funding initiative for live layer effects was a resounding success, it is now possible to create amazing effects for your vector styles such as shadows, glow, and blur effects:

Screenshot 2015-06-21 18.45.22

I’m very much looking forward to seeing all the new map designs this enables on the QGIS map Flickr group.

Thanks to everyone who was involved in developing and funding these new features!

QField in the wild

QField Experimental is out, after a couple of months of requirements gathering, private early alpha testing and foremost tons of emails requesting access to the testes group we decided today to put the current BETA version in the playstore. This means that from now on you can install QField just like any other android app by using the playstore.

QField app on Google Play
See more ›

Change predefined scales plus new PDOK services

New PDOK services This post is mostly interesting for dutch readers, as our national OWS service ‘PDOK’ added some new services. And we made them (5000 layers) available via the PDOK services plugin. Change predefined scales But I also want to show that you can change the predfined scales that you see in the Scale … Continue reading Change predefined scales plus new PDOK services

Crayfish 2.1: New Features

New features keep being added to Crayfish. Now it is possible to export time variable grid as animation, add AnuGA results and visualise vectors on user-defined grids.

Here are the new features in more detail…

Export to animation

The ground works were done in Crayfish 2.0 for this feature. You can now generate animation from contours and vectors and export them as AVI. There are two methods of exporting to animation: basic and using QGIS print template (qpt).

With the basic option, you can define a title, a legend and a progress clock. Alternatively, for a smarter solution, you can set up a print composer with the benefit of all its rich features. The composer template (qpt) can be used as a frame layout for exporting your animation.

Below is an example of a multi-frame print composer template used to generate animation from a Crayfish layer.

AnuGA support

Crayfish 2.1 now supports SWW file format generated by AnuGA.

SWW files generated by AnuGA in Crayfish (Click to enlarge)

Vector on user-defined grid

With this option, users can define a grid and Crayfish will interpolate values and displays results on the custom grid. Images below show vectors on the outputted mesh and user-defined grid.

Vectors on default mesh in Crayfish (Click to enlarge)

Vectors on default mesh in Crayfish (Click to enlarge)

Vectors on a user-defined mesh in Crayfish (Click to enlarge)

Crayfish manual

With the ever-growing features in Crayfish, we have decided to dedicate a page on how to use Crayfish in QGIS. From the manual page, users can download a sample data and try the Crayfish features in QGIS.


We’d like to thank Maroondah City Council for sponsoring some of the great features in this release.

QGIS Quick WKT plugin iface edition

Some plugin core functions can now be called from a Python console:

g = QgsGeometry.fromWkt('POINT (9.9 43)')
iface.show_geometry(g.buffer(0.2, 2))
iface.show_wkt('POINT (9 45)')
iface.show_wkb(r'0103...') # cut

All functions accept a layer title as optional argument, if None is given, they are automatically added to a Quick WKT GeometryType (memory) layer, such as Quick WKT Polygon for polygons.

The man with the golden gun ( and some examples of installing and using QGIS on Windows)

I’m not Scaramanga (maybe a little bit of Nick Nack) but anyway, this article could be be a golden bullet for helping you to eliminate a lot of obstacles if you are using QGIS in some kind of class-room setup, networked environment and/or are struggling with the “new versions 3 times a year” policy of QGIS.


My interest for a hassle free and fast installation of QGIS stems from an experience last year: Some colleagues and I was giving a QGIS workshop for attendants from all over the world. We were told that QGIS was installed on all the computers in the “out-of-town” computer lab and indeed, the computers we checked had a working installation of QGIS. Next day, 15 minutes before the workshop should start, we discovered that the QGIS installations was either non-existent or badly mangled on a large portion of the rest of the computers. And no person with “local admin” rights within sight. It would be an understatement to say that the first hour of the workshop was an interesting time for us. Well, all’s well that ends well, and in the end the workshop was a success (Lucky us!)

A couple of months later I stumbled on this article “A QGIS class room setup on Windows ” – thanks to Richard Duivenvoorde – and tried the setup by copying the qgis program directory from the initial install to another “clean” computer. Alas, QGIS did work on some – but not on all of the computers, I tried it on. The QGIS installation had some dependencies to dll’s in the windows/system32 directory. If they already were present, the “copy” installation would work but otherwise it would fail. I discovered a somewhat complicated solution to the problem and publicized it in the article “How to make a ‘QGIS on a stick’ implementation

Then, some weeks ago at the “QGIS 2015 conference at Nødebo“, I had a chat with QGIS core developer Jürgen E. Fischer about my installation problems and viola! Two days after the chat, the OSGEO4W network installation contained the missing dll’s, Thanks Jürgen.

So now we have two bits of information:

  • By using the “–configpath” qualifier we can redirect where QGIS is looking for plugins, user selected values for options, values and files normally saved in the .qgis2 directory or in the registry.
  • The OSGeo4W network installation creates QGIS without any dependencies to external dll’s outside the installation directory. You could make an installation by simply copy an existing QGIS program directory to another computer.

This gives us some interesting possibilities:

  • Use case I : “QGIS on a stick”
    You can make a QGIS installation located on a memory stick and completely self contained; simply plug in the stick into a Windows computer and start QGIS by double clicking on the QGIS startup file.
  • Use case II: “Simple ‘xcopy’ installation of QGIS”
    Make an installation procedure for QGIS that consists of a simple copy of the QGIS program directory to a new computer. Like the answer to: “How the heck am I going to install QGIS on 24 computers in half an hour ?”
  • Use case III: “Network install of QGIS with floating profiles”
    Install QGIS on a network file share and put the QGIS setup information into the “Floating profile”. A large part of a user profile including will be cached on a central server in the windows domain. If the user logs on to another computer than the usual, his/her profile will automatically be copied to the new computer, giving the user his “normal” desktop and setups.
  • Use case IV: “QGIS on Citrix”
    Normally it ain’t my cup of tea to install any kind of program on a Citrix server where the program has a “canvas” area with fast changing images/pixels. For example: A GIS program like QGIS showing a map with an orthofoto background with millions of pixels – all with a slightly different hues of greens or browns.
    However, many IT departments swears by Citrix, so….
  • Use Case V: “Smart installation and update of a large amount of QGIS installations”
    If you have to install QGIS on dozens or hundreds of computers and keep the installation up-to-date, this is the use-case for you.

Step 1: Creating the common template..

First you have to create a common template for your future installation(s) whatever use case you implement afterwards. I use the 32-bit edition of the network installation as a basis for this although it’s perfectly possible to use the 64 bit version.

  1. Browse to and click on OSGeo4W Network installer (32 bit) . This will download the installer.
  2. Start the installer and choose “Express Desktop Install”.
  3. Check “QGIS” and uncheck everything else.
  4. Check “I agree yadda yadda…” to every license message.This will install a default QGIS installation in directory C:\OSGeo4W and create a QGIS user directory in C:\Users\<my username>\.qgis2, i.e. the directory .qgis2 in your home directory. These 2 directories is the basis for the template. You can check the installation by starting QGIS from the “OSGeo4W” program group in “Start” –> “All Programs”. It should work without problems.
  5. Copy the C:\Users\<my username>\.qgis2 directory with contents to C:\OSGeo4W, so you’ll have a C:\OSGeo4W\.qgis2 directory.
  6. Copy the startup file for QGIS: C:\OSGeo4W\bin\QGIS.bat to C:\OSGeo4W\bin\QGIS.ref. This is insurance ! If you utterly mangle QGIS.bat in the next steps you have this file as a backup. Otherwise you are not going to use it for anything.
  7. Edit the file: C:\OSGeo4W\bin\QGIS.bat with a simple text editor like notepad.
    Insert 2 lines between line 2 and 3 in the bat file:

    call “%~dp0\o4w_env.bat”
    call “%OSGEO4W_ROOT%”\apps\grass\grass-6.4.4\etc\env.bat

    so it looks like this:

    call “%~dp0\o4w_env.bat”
    set QGIS_OAS=”%OSGEO4W_ROOT%”\.qgis2
    if exist “%OSGEO4W_ROOT%”\bin\QGIS_OAS.bat call “%OSGEO4W_ROOT%”\bin\QGIS_OAS.bat
    call “%OSGEO4W_ROOT%”\apps\grass\grass-6.4.4\etc\env.bat

    and replace the last line in the bat file:

    start “QGIS” /B “%OSGEO4W_ROOT%”\bin\qgis-bin.exe %*

    with this line:

    start “QGIS” /B “%OSGEO4W_ROOT%”\bin\qgis-bin.exe –configpath %QGIS_OAS% %*

    and save the result.

    What the edits mean:

    • Create an environment variable %QGIS_OAS% which works as a pointer to the location of the .qgis2 directory. Initially it points to the .qgis2 directory inside the OSGeo4W installation directory we created in (5).
    • Execute a command-file “QGIS_OAS.bat” if it exists. This command-file is the basis for all our different use-cases. There will be a different version for each use-case. Initially we don’t use this file.
    • Add the “–configpath %QGIS_OAS% qualifier to the actual start of QGIS. This means, that QGIS will look for all setup information, user-defined options, plugins and whatnot in the directory specified by the %QGIS_OAS% environment variable. And QGIS will not use any settings in the registry.
  8. Start QGIS by double clicking the revised C:\OSGeo4W\bin\QGIS.bat file and make all the changes to the initial setup of QGIS that should be included in your future QGIS installation(s). This could be change of language, default projection, extra plugins, snap options, yadda yadda yadda. Come on, make you dream QGIS setup !!

Thanks to the –configpath qualifier now on the start line for QGIS all these changes will be saved in the C:\OSGeo4W\.qgis2 directory. After this, you have a complete setup of QGIS – with your own changes – all located in the C:\OSGeo4W directory. This is the common template for all use cases.

Step 2: Do one of the use cases…

Use case I : “QGIS on a stick “

You have already done this use case. The template made in step 1 is a ready made “QGIS on a stick” installation:

  1. Copy the entire C:\OSGeo4W template directory from your computer to the root of your memory stick.
  2. Insert the memory stick into any Windows computer and start QGIS by double clicking on \OSGeo4W\bin\qgis.bat on the memory stick.
    QGIS will use \OSGeo4W\.qgis2 on the memory stick as the QGIS user directory.

Use case II : “Simple ‘xcopy’ installation of QGIS “

In this use case we will have to extend the template by creating the QGIS_OAS.bat file. This example will put the QGIS user directory “.qgis2” in the users home directory, just like the normal installation does – with one exception: This installation will not use the registry but save all user options in a ini-file placed in the QGIS user directory.

  1. Create the file C:\OSGeo4W\bin\QGIS_OAS.bat with the following content:
    set QGIS_OAS=”%USERPROFILE%”\.qgis2
    if exist %QGIS_OAS% exit /B
    xcopy “%OSGEO4W_ROOT%”\.qgis2 %QGIS_OAS% /e /i
    nircmd shortcut “””%OSGEO4W_ROOT%””\bin\qgis.bat” “~$folder.desktop$” “Start QGIS” “” “””%OSGEO4W_ROOT%””\bin\qgis-bin.exe” “0” “min” “””%OSGEO4W_ROOT%””\bin” “”

    (First the pointer to the QGIS user directory is changed to the “users home directory”\.qgis2. Secondly, The command file will check if the QGIS user directory exists in the users home directory. If it doesn’t exist, the command file will create a copy of the QGIS user directory template into the users home directory; create a shortcut to start QGIS and place this shortcut on the user’s desktop.)

  2. You can now install QGIS on a new PC by copying the entire C:\OSGeo4W directory to the new pc (using a memory-bird, network drive, zip-copy-unzip, whatever). The directory can be copied to any directory location on the new PC. Please note that some locations will require “local admin” rights for creating the new directory, for example if you copy it to “C:\Program Files”. I usually try the avoid this.

First time use on the new pc:

  • Start QGIS by double clicking on C:\OSGeo4W\bin\qgis.bat (or wherever you placed the OSGeo4W directory). When QGIS starts, the combined command files QGIS.BAT and QGIS_OAS.BAT will automatically create the QGIS user directory on the new pc; create a shortcut to QGIS on the user desktop and start QGIS.

After that you can start QGIS by double clicking on the shortcut placed on the desktop.


Use case III: “Network install of QGIS with floating profiles

This usage scenario will have the QGIS installation located in a directory on a common network file-share. A normal user need only to have read and execute rights to this directory. The QGIS user directory will be placed in the users “roaming profile” on the client PC, a special region which is cached to a central server.

The computers and users are members of a AD domain. If the user logs on to another pc in the domain, the “roaming profile”, including the desktop and the QGIS user directory, will automatically be copied the new computer and the user will see the usual desktop and applications.

With this setup, there is no dependencies to any particular client pc after the first start of QGIS by the user. If the user logs on any other client PC in the domain it will be possible for her to start QGIS simply by double clicking on the QGIS shortcut on desktop.

There is some requirements: The user has to have access to the common file share (!) and the network connection has to be stable and relatively fast.

In this use case we will do the following:

  1. Copy the QGIS directory C:\OSGeo4W to the common share: X:\QGIS\Current (The drive letter X: is arbitrary; it could be any drive letter). I will explain the naming scheme of the directory later.
  2. Create the file X:\QGIS\Current\bin\QGIS_OAS.bat with the following content
    set QGIS_OAS=”%APPDATA%”\.qgis2
    if exist %QGIS_OAS% exit /B
    xcopy “%OSGEO4W_ROOT%”\.qgis2 %QGIS_OAS% /e /i
    nircmd shortcut “””%OSGEO4W_ROOT%””\bin\qgis.bat” “~$folder.desktop$” “Start QGIS” “” “””%OSGEO4W_ROOT%””\bin\qgis-bin.exe” “0” “min” “””%OSGEO4W_ROOT%””\bin” “”

    (First, The QGIS_OAS environment variable points to the qgis user directory in the roaming profile. Secondly, the command file will check if the QGIS user directory exists. If it doesn’t, the command file will copy the QGIS user directory template to the users roaming profile; create a shortcut to start QGIS and place this shortcut on the user desktop.)

First time use on the new pc:

  • Start QGIS by double clicking on X:\QGIS\Current\bin\qgis.bat. When QGIS starts, the combined command files QGIS.BAT and QGIS_OAS.bat will automatically create the QGIS user directory on the new pc, create a shortcut on the user desktop and start QGIS.
  • After the first time you start QGIS by double clicking on the shortcut placed on the desktop.

Oh .. and why did I use this particular naming scheme for the directory ? It is used to make it easy to update QGIS:

When you have a new version of QGIS, do the following:

  1. Make a template of the new qgis version as described in step 1 and use case III, but in another directory: X:\QGIS\Testing and leave the X:\QGIS\Current unchanged.
  2. Test the new installation. You might even let some of your users test it!! You can start the “testing” version of QGIS by double clicking on X:\QGIS\Testing\bin\qgis.bat
  3. When you are satisfied with the new installation:
    • Rename the directory X:\QGIS\Current to X:\QGIS\Deprecated
    • Rename the directory X:\QGIS\Testing to X:\QGIS\Current 

After the last rename operation all the networked users will execute the new version using their existing shortcut. This method will probably work with all minor updates (2.8 -> 2.10), but probably not with a major update (2.10 -> 3.0)

Use case IV : “QGIS on Citrix “

If you have a Citrix environment you probably have a personal network-based share for each an every user on the domain. For this use case I call this directory M:\Personal. But the naming convention can be anything.

The idea is to place the QGIS user directory on the personal network share, so there won’t be anything saved or registered on the Citrix server that’s user related:

Do the following:

  1. Create a working installation of QGIS on the Citrix sever using the techniques described in Step 1.
  2. Create the file C:\OSGeo4W\bin\QGIS_OAS.bat on the Citrix server with the following content:
    set QGIS_OAS=M:\Personal\.qgis2
    if exist %QGIS_OAS% exit /B
    xcopy “%OSGEO4W_ROOT%”\.qgis2 %QGIS_OAS% /e /i

    (First, The QGIS_OAS environment variable points to the qgis user directory placed on the users personal network share. In this case “M:\Personal”. Secondly, the command file will check if the QGIS user directory exists. If it doesn’t, the command file will copy the QGIS user directory template to the users personal network share.)

  3. Create the usual application startup definition for Citrix pointing to C:\OSGeo4W\bin\QGIS.bat on the Citrix server.

Bingo ! That’s it. I’ll leave the last use case “Smart installation and update of a large amount of QGIS installations” to a separate article, because it is more complicated than any of the previous use cases. I’ll try to publish that article in a week or so, so stay tuned !!

This article has a zip file “” attached. It contains the revised QGIS.BAT file plus all the different types of QGIS_OAS bat files described in the article. The suffix is renamed to “.usecase_1”, “.usecase_2” and so on. Download the zip file and rename the suffix to “.bat” on the files you’re going to use.

A final note: I’ve used QGIS 2.8.2 in my tests. So the use cases works for this version of QGIS and will probably work for other QGIS 2.x versions.


Bo Victor Thomsen

How to Use Function Editor in QGIS Field Calculator

In QGIS 2.8, there is a new option for users to add their own python function in the Field calculator. This is an extremely useful feature enabling users to populate data within the attribute table using customised python function.

Nathan wrote a blog post about the feature and how to write a python with arguments. But in QGIS 2.8, the function editor does not correctly support functions without arguments.

In the example below, we are going to calculate proportion of area for each SAC (Special Areas of Conservation) in Great Britain to the total area of the layer.

Add GB_SAC_20130918_Dissolved.shp layer to QGIS, right-click on the layer and open attribute table. Make the layer editable and click on the Field calculator. We are now going to create a new column (propArea) and populate proportionate area of each SAC to the total area of the layer.

Under Function Editor tab, click on New file and type area for the name and save the file. For the content, copy and paste the following lines:

A custom function to calculate total area of the GIS layer.
This function has no arguments.

from qgis.core import *
from qgis.gui import *
from qgis.utils import iface

@qgsfunction(args='auto', group='Custom')
def total_area(x, feature, parent):
    return sum( f.geometry().area() for f in iface.activeLayer().getFeatures() )

Click on Run Script to add total_area function to your Custom function list.

Now, click on Expression tab and type:

$area / total_area(0)

As you can see, we have passed 0 as an argument. If you click OK, your QGIS will freeze! As there are many features in the layer, the expression, calculates total area for each row.

Lets make the script a bit more elegant. Firstly, we need to add caching, so that area will be calculated only once and cached for the rest of operation. Secondly, we can make the script a bit more generic, so that we can use it to get the area of other loaded layers in QGIS:

from qgis.core import *
from qgis.gui import *
from qgis.utils import iface

cache = {}
def _layer_area(layer):
    """ Internal method """
    if not in cache:
        area = sum( f.geometry().area() for f in layer.getFeatures() )
        cache[] = area
    return cache[]

@qgsfunction(args='auto', group='Custom')
def total_area(layer_name, feature, parent):
    for layer in iface.mapCanvas().layers():
        if == layer_name:
            return _layer_area(layer)
    return 0

Now, click on Expression tab and type:

$area / total_area('GB_SAC_20130918_Dissolved')

This time, it should be quicker!

QGIS Quality and Testing

I promised that I will write a bit about what I’ve been up to at the last QGIS developer meeting – apart from the social part we also got some work done there. So let me start with something that

QGIS 3.0 future plans

If you follow the QGIS developer mailing list, you’ve probably seen threads about the next major release: 3.0. The topic has been one of the many points we talked about at the latest QGIS developer meeting and Tim Sutton sums up the discussed plan in a post published today:

One hot topic was ‘when will QGIS 3.0 be released’. The short answer to that question is that ‘we don’t know’ – Jürgen Fischer and Matthias Kuhn are still investigating our options and once they have had enough time to understand the implications of upgrading to Qt5, Python 3 etc. they will make some recommendations. I can tell you that we agreed to announce clearly and long in advance (e.g. 1 year) the roadmap to moving to QGIS 3.0 so that plugin builders and others who are using QGIS libraries for building third party apps will have enough time to be ready for the transition. At the moment it is still uncertain if there even is a pressing need to make the transition, so we are going to hang back and wait for Jürgen & Matthias’ feedback.

The take-away message here is that the QGIS team is aware of the current developments around Python and Qt and will keep the community updated about the further development path well before any move.


Report back on the first QGIS User Conference in Nødebo, Denmark

I finally have some time to sit down and write up some thoughts on the QGIS User Conference and Developer Meeting (aka Hackfest) that we just held in Nødebo, Denmark. First up I need to thank Lene Fischer, who was the organiser and wowed us all with her relaxed and competent organisational approach to the conference. Thanks also to the University of Copenhagen School of Forestry – they sponsored the event by providing the venue and accommodation – and the venue was absolutely awesome with little cottages in the forest and all sorts of interesting diversions scattered around the forest. Lene gave me a list of names of people who helped to organise the event – I am sorry I have only got your first names but a very big thank you to you all!


Students: Runner, Shuttlebus, Kitchenaid, Cleaner, Info, Coordinator, Parking, Inn-keeper, Keyholder
Mikkel M
Mikkel N
Employees at University of CopenhagenCoordination, Accomodation, Bed&Linnen, Computer, Kitchen, Network, Tent/chairs/, Cookiebaker, Supporter, Cheerleader, Lifgt, Microphones/projector, Webpage, DTP,




On the first day of the user conference, I got to present a session on ‘the future of QGIS’ (video feed here and continued here) which held more as a town hall style meeting with a few themes (desktop, server, mobile etc.) I think the participants enjoyed the format and it was equally novel for the general user community (who got to have their questions answered directly by developers) and the developers (who got to see what real users look like).

The QGIS User Conference had many interesting talks (you can see the complete programme here – along with links to the video stream for each talk). For me the most interesting things happening at the meetup (both user conference and hackfest parts were:

  • the fact that we had our first ever general users conference (with around 150 attendees)
  • the geometry checking tools developed by Sandro Mani from Sourcepole
  • the huge amount of effort and thought being put into the processing framework – if you haven’t already tried out the QGIS processing tools, do go and try them!
  • The server side plugin framework that Alessandro Pasotti is working on – see his blog post here too
  • The amount of polish being applied to QGIS – there are probably less ‘gee whizz’ new features and a lot more fixes and improvements – just take a look at the incoming pull requests to get a flavour of the kind of activity going on.
  • The new geometry system by Marco Hugentobler (also from Sourcepole) which will support curves and 3D geometries (z / m). The graphical user interface for working with the new geometries won’t come until a later release, but 2.10 will get the underlying support added (along with shims to provide backwards compatibility to the old geometry classes).
  • There were some interesting talks on using QGIS in a server side / headless / command line context – again check out the talks and video streams in the programme to watch talks by Martin Dobias, Dražen Odobašić.
  • QGIS on mobile is coming – Matthias Kuhn showed off the current state of QField – the Android native interface for field work based on QGIS he has been working on. See his blog post here too for his take on the week. While the Android work shows lots of promise, there are still lots of problems to be resolved – for example missing support for ‘Lollipop’ devices. Please consider sponsoring Matthias’ efforts if you can.
  • There is a heap of interesting stuff coming down the pipeline from Nyall Dawson for the production of print maps and rendering effects for map renderers. Nyall also showed off some other very interesting ideas for context based variables that can be used in expressions – it’s hard to explain it in  a sentance or two – suffice to know that power users are going to have even more awesome tools at their fingertips for producing great maps.

One hot topic was ‘when will QGIS 3.0 be released’. The short answer to that question is that ‘we don’t know’ – Jürgen Fischer and Matthias Kuhn are still investigating our options and once they have had enough time to understand the implications of upgrading to Qt5, Python 3 etc. they will make some recommendations. I can tell you that we agreed to announce clearly and long in advance (e.g. 1 year) the roadmap to moving to QGIS 3.0 so that plugin builders and others who are using QGIS libraries for building third party apps will have enough time to be ready for the transition. At the moment it is still uncertain if there even is a pressing need to make the transition, so we are going to hang back and wait for Jürgen & Matthias’ feedback.

I apologise for not reporting on many of other interesting talks and birds of a feather meetings here – there was so much going on including work on documentation, translations, bug fixing, bug triaging that it is quite difficult to list it all here.

Two initiatives I was involved in at the meetup: the user certification programme and the formation of a QGIS legal entity. I am not going to post details here because things are not finalised yet (watch the mailing lists for details on the legal entity), but if you are interested in the certification programme, please get into contact – we have started drafting a roadmap for the roll out of our official curriculum. The QGIS project also got a huge boost from the QGIS Academy folks who will be contributing all their training resources right into the core of the QGIS documentation project (see Kurte Menke’s presentation notes on the programme).

We (Paolo Cavallini, Alessandre Pasotti, Nyall Dawson and myself) had a little roundtable discussion on the last day of the hackfest where we ran through some of the highlights from the week. You can listen to it here – or subscribe to the podcast at (I will try to get back into the swing of making more regular episodes).

Well that wraps up my feedback for the event – I really encourage everyone to come along and join us on the next QGIS User Conference – it was fun, informal and informative!

QGIS developer meeting in Nødebo

During the hackfest I’ve been working on the refactoring of the server component, aimed to wrap the server into a class and create python bindings for the new classes. This work is now in the PR queue and brings a first working python test for the server itself.

The server can now be invoked directly from python, like in the example below:


#!/usr/bin/env python
Super simple QgsServer.

from qgis.server import *
from BaseHTTPServer import *

class handler (BaseHTTPRequestHandler):

    server = QgsServer()

    def _doHeaders(self, response):
        l = response.pop(0)
        while l:
            h = l.split(':')
            self.send_header(h[0], ':'.join(h[1:]))
            self.log_message( "send_header %s - %s" % (h[0], ':'.join(h[1:])))
            l = response.pop(0)

    def do_HEAD(self):
        response = str(handler.server.handleRequestGetHeaders(self.path[2:])).split('\n')

    def do_GET(self):
        response = str(handler.server.handleRequest(self.path[2:])).split('\n')
        i = 0

    def do_OPTIONS(s):

httpd = HTTPServer( ('', 8000), handler)

while True:

The python bindings capture the server output instead of printing it on FCGI stdout and allow to pass the request parameters QUERY_STRING directly to the request handler as a string, this makes writing python tests very easy.

Python SIP C++ bindings tutorial

Since QGIS uses QT libraries, SIP is the natural choice for creating the bindings.

Here are some random notes about this journey into SIP and Python bindings, I hope you’ll find them useful!
We will create a sample C++ library, a simple C++ program to test it and finally, the SIP configuration file and the python module plus a short program to test it.

Create the example library

FIrst we need a C++ library, following  the tutorial on the official SIP website  I created a simple library named hellosip:


$ mkdir hellosip
$ cd hellosip
$ touch hellosip.h hellosip.cpp Makefile.lib

This is the content of the header file hellosip.h:

#include <string>

using namespace std;

class HelloSip {
    const string the_word;
    // ctor
    HelloSip(const string w);
    string reverse() const;

This is the implementation in file hellosip.cpp , the library just reverse a string, nothing really useful.

#include "hellosip.h"
#include <string>

HelloSip::HelloSip(const string w): the_word(w)

string HelloSip::reverse() const
    string tmp;
    for (string::const_reverse_iterator rit=the_word.rbegin(); rit!=the_word.rend(); ++rit)
        tmp += *rit;
    return tmp;


Compiling and linking the shared library

Now, its time to compile the library, g++ must be invoked with -fPIC option in order to generate Position Independent Code, -g tells the compiler to generate debug symbols and it is not strictly necessary if you don’t need to debug the library:

g++ -c -g -fPIC hellosip.cpp -o hellosip.o

The linker needs a few options to create a dynamically linked Shared Object (.so) library, first -shared which tells gcc to create a shared library, then the -soname which is the library version name, last -export_dynamic that is also not strictly necessary but can be useful for debugging in case the library is dynamically opened (with dlopen) :

g++ -shared -Wl,-soname,  -g -export-dynamic -o  hellosip.o

At the end of this process, we should have a brand new sitting in the current directory.

For more informations on shared libraries under linux you can read TLDP chapter on this topic.


Using the library with C++

Before starting the binding creation with SIP, we want to test the new library with a simple C++ program stored in a new cpp file: hellosiptest.cpp:

#include "hellosip.h"
#include <string>
using namespace std;
// Prints True if the string is correctly reversed
int main(int argc, char* argv[]) {
  HelloSip hs("ciao");
  cout << ("oaic" == hs.reverse() ? "True" : "False") << endl;
  return 0;

To compile the program we use the simple command:

g++ hellosiptest.cpp -g -L.  -lhellosip -o hellosiptest

which fails with the following error:

/usr/bin/ld: cannot find -lhellosip
collect2: error: ld returned 1 exit status

For this tutorial, we are skipping the installation part, that would have created proper links from the base soname, we are doing it now with:

ln -s

The compiler should now be happy and produce an hellosiptest executable, that can be tested with:

$ ./hellosiptest

If we launch the program we might see a new error:

./hellosiptest: error while loading shared libraries: cannot open shared object file: No such file or directory

This is due to the fact that we have not installed our test library system-wide and the operating system is not able to locate and dynamically load the library, we can fix it in the current shell by adding the current path to the LD_LIBRARY_PATH environment variable which tells the operating system which directories have to be searched for shared libraries. The following commands will do just that:

export LD_LIBRARY_PATH=`pwd`

Note that this environment variable setting is “temporary” and will be lost when you exit the current shell.



SIP bindings

Now that we know that the library works we can start with the bindings, SIP needs an interface header file with the instructions to create the bindings, its syntax resembles that of a standard C header file with the addition of a few directives, it contains (among other bits) the name of the module and the classes and methods to export.

The SIP header file hellosip.sip contains two blocks of instructions: the class definition that ends around line 15 and an additional %MappedType block that specifies how the std::string type can be translated from/to Python objects, this block is not normally necessary until you stick standard C types. You will notice that the class definition part is quite similar to the C++ header file hellosip.h:

// Define the SIP wrapper to the hellosip library.

%Module hellosip

class HelloSip {

#include <hellosip.h>

    HelloSip(const std::string w);
    std::string reverse() const;

// Creates the mapping for std::string
// From:

%MappedType std::string

    // convert an std::string to a Python (unicode) string
    PyObject* newstring;
    newstring = PyUnicode_DecodeUTF8(sipCpp->c_str(), sipCpp->length(), NULL);
    if(newstring == NULL) {
        newstring = PyString_FromString(sipCpp->c_str());
    return newstring;

    // Allow a Python string (or a unicode string) whenever a string is
    // expected.
    // If argument is a Unicode string, just decode it to UTF-8
    // If argument is a Python string, assume it's UTF-8
    if (sipIsErr == NULL)
        return (PyString_Check(sipPy) || PyUnicode_Check(sipPy));
    if (sipPy == Py_None) {
        *sipCppPtr = new std::string;
        return 1;
    if (PyUnicode_Check(sipPy)) {
        PyObject* s = PyUnicode_AsEncodedString(sipPy, "UTF-8", "");
        *sipCppPtr = new std::string(PyString_AS_STRING(s));
        return 1;
    if (PyString_Check(sipPy)) {
        *sipCppPtr = new std::string(PyString_AS_STRING(sipPy));
        return 1;
    return 0;

At this point we could have run the sip command by hand but the documentation suggests to use the python module sipconfig that, given a few of configuration variables, automatically creates the Makefile for us, the file is by convention named

import os
import sipconfig

basename = "hellosip"

# The name of the SIP build file generated by SIP and used by the build
# system.
build_file = basename + ".sbf"

# Get the SIP configuration information.
config = sipconfig.Configuration()

# Run SIP to generate the code.
os.system(" ".join([config.sip_bin, "-c", ".", "-b", build_file, basename + ".sip"]))

# Create the Makefile.
makefile = sipconfig.SIPModuleMakefile(config, build_file)

# Add the library we are wrapping.  The name doesn't include any platform
# specific prefixes or extensions (e.g. the "lib" prefix on UNIX, or the
# ".dll" extension on Windows).
makefile.extra_libs = [basename]

# Search libraries in current directory
makefile.extra_lflags= ['-L.']

# Generate the Makefile itself.

We now have a Makefile ready to build the bindings, just run make to build the library. If everything goes right you will find a new library which is the python module. To test it, we can use the following simple program (always make sure that LD_LIBRARY_PATH contains the directory where is found).

import hellosip
print hellosip.HelloSip('ciao').reverse() == 'oaic'


The full source code of this tutorial can be downloaded from this link.

QGIS Server Python Plugins Ubuntu Setup


I assume that you are working on a fresh install with Apache and FCGI module installed with:

$ sudo apt-get install apache2 libapache2-mod-fcgid
$ # Enable FCGI daemon apache module
$ sudo a2enmod fcgid

Package installation

First step is to add debian gis repository, add the following repository:

$ cat /etc/apt/sources.list.d/debian-gis.list
deb trusty main
deb-src trusty main

$ # Add keys
$ sudo gpg --recv-key DD45F6C3
$ sudo gpg --export --armor DD45F6C3 | sudo apt-key add -

$ # Update package list
$ sudo apt-get update && sudo apt-get upgrade

Now install qgis server:

$ sudo apt-get install qgis-server python-qgis

Install the HelloWorld example plugin

This is an example plugin and should not be used in production!
Create a directory to hold server plugins, you can choose whatever path you want, it will be specified in the virtual host configuration and passed on to the server through an environment variable:

$ sudo mkdir -p /opt/qgis-server/plugins
$ cd /opt/qgis-server/plugins
$ sudo wget
$ # In case unzip was not installed before:
$ sudo apt-get install unzip
$ sudo unzip 
$ sudo mv qgis-helloserver-master HelloServer

Apache virtual host configuration

We are installing the server in a separate virtual host listening on port 81.
Rewrite module can be optionally enabled to pass HTTP BASIC auth headers (only needed by the HelloServer example plugin).

$ sudo a2enmod rewrite

Let Apache listen to port 81:

$ cat /etc/apache2/conf-available/qgis-server-port.conf
Listen 81
$ sudo a2enconf qgis-server-port

The virtual host configuration, stored in /etc/apache2/sites-available/001-qgis-server.conf:

<VirtualHost *:81>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html

    ErrorLog ${APACHE_LOG_DIR}/qgis-server-error.log
    CustomLog ${APACHE_LOG_DIR}/qgis-server-access.log combined

    # Longer timeout for WPS... default = 40
    FcgidIOTimeout 120 
    FcgidInitialEnv LC_ALL "en_US.UTF-8"
    FcgidInitialEnv LANG "en_US.UTF-8"
    FcgidInitialEnv QGIS_DEBUG 1
    FcgidInitialEnv QGIS_SERVER_LOG_FILE /tmp/qgis-000.log
    FcgidInitialEnv QGIS_SERVER_LOG_LEVEL 0
    FcgidInitialEnv QGIS_PLUGINPATH "/opt/qgis-server/plugins"

    # ABP: needed for QGIS HelloServer plugin HTTP BASIC auth
    <IfModule mod_fcgid.c>
        RewriteEngine on
        RewriteCond %{HTTP:Authorization} .
        RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
    <Directory "/usr/lib/cgi-bin">
        AllowOverride All
        Options +ExecCGI -MultiViews +FollowSymLinks
        Require all granted
        #Allow from all

Enable the virtual host and restart Apache:

$ sudo a2ensite 001-qgis-server
$ sudo service apache2 restart


$ wget -q -O - "http://localhost:81/cgi-bin/qgis_mapserv.fcgi?SERVICE=HELLO"

See all QGIS Server related posts

  • <<
  • Page 3 of 80 ( 1584 posts )
  • >>

Back to Top