Expression based labeling now in QGIS.

QGIS finally has expression based labels! (Although you must be running latest dev build)

What does that mean? Well QGIS used to be only able to label with a field from the layer, very limiting if you need to make a nice looking label string. Now you can use expressions (eg ‘Up ‘ || US_Invert || ‘some more text’ ) to label the feature, just like this.

Example of expression based labels

This is something that I missed a lot when moving from MapInfo to QGIS.  After opening a ticket on the QGIS bug list and nothing happening with it for a couple of months (not that I expected anything to, everyone is busy enough as is.  I don’t expect the devs to just jump at all my requests) so I decided I should at least attempt adding it myself.  The joys of open source!

Turns out adding the expression labeling was the easy part, however there was no good generic expression string builder that I could use to build the expression string.  QGIS already had the expression builder for the query window and the field calculator, however the code was very tied down to only work for those implementations, plus they didn’t scale with the increasing function list.  I’m not going to go and make yet another dialog just for the labeling.  Uniformity is the key to good user experience.

After searching around to see what other GIS systems did to get some inspiration it seemed that every example that I came across was, in my opinion, poor.    Although there was one ArcGIS idea ticket that gave me a few ideas

So with that I started working on a generic expression builder that could be used to build an expression string anywhere, replacing the query window and field calculator in due time. One ring widget to rule them all, one ring widget to bind the, etc.

The result

Generic expression builder

Key features of the new expression builder:

  • Live validation of expression
  • Real time searching
  • Live output preview
  • Help on selected item.
  • Easier to add new functions without changing the UI.  Function list is read right from the expression parser.  No more hidden functions.
  • Reusable widget

If the expression hits an error while you type you will be shown an “Expression is invalid” warning (yes I know it’s wrong in the screen shot). Clicking (more info) or hovering over the expression area will show you the error.

Expression has error

Searching can done by using the search box at the top. The function list will reduce to show only functions or fields containing that string (Note: it is case sensitive at the current time) .

Searching for a function or field name.

Still to do

As with all programming it is never bug free so I expect, now that it is open to wider testing, that there might be a few that need to be addressed .   There is also very limited function help written for the functions, although if anyone is willing to have a go at it I’m more than happy.

If you do find any bugs will the widget/dialog you can open a ticket at , assign it to me and I’ll see what I can do.

In the works

  • Simple Syntax highlighting
  • Recent expression used list
  • Saved expressions
  • Auto bracketing (maybe)
  • UI tweaking

I would like to thank Martin from the QGIS team for reviewing my code all though the project and helping me improve the code and idea.  Also thanks to all the other people who gave ideas for the widget/dialog.


30 thoughts on “Expression based labeling now in QGIS.

  1. Great stuff. This is a great feature addition. Taking a feature that you missed from MapInfo and making it better than the original. We will be using this a lot. Would be nice to see this make the QGIS 1.8 release.

  2. Pingback: Expression based labeling now in QGIS and the new expression builder. | CEREGeo - Geomática |

  3. Pingback: Expression-based Labeling for QGIS | Free and Open Source GIS Ramblings

  4. How can I test it ? I have compiled qgis 1.8 (rev 8a98069), but can not find it? Could you point me to the right place to the vector label dialog?

    • If you are using the labeling (ABC icon on the toolbar) you can add an expression label by using the “…” button next to the drop down for the field name.

      I plan on doing a make over of that dialog to make it more user friendly.

  5. Hi Nathan,
    You have removed one of the big differences between QGIS and the commercial products but there is another really significant limitation to labelling in QGIS. I loaded the Qld easements layer and many easements are very short and run into immediately adjacent easments. Unfortunately when this happens the labels that run along the easements touch and it becomes impossible to tell where one label stops and the next begins. What is needed if for each label to have an exclusion zone around it that prevents labels from being so close togehter that the look like one label. QGIS already has white space which other GIS products call halos but I am suggesting that it could do with a ‘clear space’ option as well. The code would already exist in QGIS as labels with white space have bigger boxes that labels without white space. Could the same code be used to set the exclusion box to an even larger area to create clear space..

    • As a work around for now you could pad the string using the expression builder using whitespace at the start and end. ‘ ‘ || {your label stuff} || ‘ ‘. Would that work?

  6. Great tool but having problems getting labels to display on multi lines. Earlier someone else asked this and the response was ‘Make sure you tick “Multiline labels” in the Advanced tab for the label properties. I might even write a patch to make that the default setting.’

    I can’t find this tick box in the advanced tab??

  7. James: In the “Layer labeling settings” window, click the “Advanced” tab, then scroll down to the “Options” setting–you’ll then see a checkbox for “Multiline labels” which you can enable.

      • Thanks guys…no wonder I couldn’t find the checkbox..thought I was going mad!
        I’ve fiddled with the label setting again and somehow I’ve managed to get all the labels on multi-line…looks very nice indeed!

  8. Hi,
    That’s very cool, thanks!
    Could it be possible to add in the “function list” some variables related to the map canvas (in addition to the existing variables related to the record ($x, $rownnum…) )?
    - current scale (probably most useful)
    (- current map bounding box)
    (- current projection)

    Knowing the current scale would be tremendously useful to adapt the labelling based on scale.
    - display short label at overview scale, long label at detailed scale
    - display label or not depending on scale, with different scale rules depending on attributes (like in the rule based renderer). For instance you may want to show airports at scales below 1:1,000,000 but label them at scales below 1:500,000.
    I’m not sure about the use of the other two (map bounding box, projection) but I can vaguely imagine some case uses.
    e.g. if label size is in map units, then projection matters;
    bounding box could be used to tweak labels near the map border. A variant of these might work: do not display labels close to border, or add space character before labels that are on the left and after labels that are near the right border of the map.
    Mayeul Kauffmann

  9. Pingback: Conditional Labels in QGIS « Indicatrix

  10. Pingback: GIS-Lab Blog» Архив блога » QGIS 1.8.0 «Lisboa»

  11. Pingback: Better date and time support in QGIS expressions and styles « Nathans QGIS and GIS blog

  12. Hello, Thanks so much for building this. I am having some trouble adding text. What I want to display is the following:

    Text: (value from att. table)
    Text: (value from att. table)
    Volunteers: 45
    Active: 32

    Could you give me a hint? I tried using the features from the screenshot but as you said it creates an error message and I am not sure how to resolve it.

  13. Pingback: User defined expression functions for QGIS « Nathans QGIS and GIS blog

  14. Pingback: New Labeling in Quantum GIS « Scratching Surfaces

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s