Nathans QGIS and GIS blog

A blog about my adventures with QGIS and other GIS in general.

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 http://ideas.arcgis.com/ideaView?id=087300000008IbHAAU

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 http://hub.qgis.org/projects/quantum-gis/issues , 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.

Enjoy!

21 Responses to Expression based labeling now in QGIS.

  1. stewedthoughts October 27, 2011 at 10:01 am

    That looks really cool! I look forward to using it down the track.

    Stewart

  2. darrencope October 27, 2011 at 11:29 am

    Awesome work Nathan! I’ll give it a try tomorrow!

  3. darrencope October 27, 2011 at 11:56 am

    Ok, who am I kidding! I just tried it. Very cool, but I can’t seem to get the new line to work. Any thoughts? It’s showing as a funny character (square box).

    • Nathan October 27, 2011 at 12:15 pm

      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.

      • Darren October 27, 2011 at 10:06 pm

        Great, thanks! That does the trick :)

  4. James Stott October 27, 2011 at 6:15 pm

    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.

  5. Raymond Nijssen October 27, 2011 at 8:23 pm

    Wow, cool! I was waiting for this and I will try it soon.
    Thanks!

  6. Fish October 27, 2011 at 11:59 pm

    I too will use this a lot as its nececery for labeling our sewerpipes correctly. Thanks Nathan :-)

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

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

  9. pat ambcan October 29, 2011 at 1:57 am

    This is just awesome contribution to make qGIS a great tool.

    Thank you Nathan !

  10. Jachym November 7, 2011 at 4:29 pm

    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?

    • Nathan November 7, 2011 at 7:53 pm

      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.

  11. Andrew November 8, 2011 at 4:54 pm

    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..

    • Nathan November 8, 2011 at 5:07 pm

      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?

  12. James November 9, 2011 at 10:00 pm

    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??

  13. darrencope November 9, 2011 at 10:26 pm

    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.

    • Nathan November 9, 2011 at 10:36 pm

      Thanks Darren

      Just note, I have removed the checkbox for Multiline labels in the latest build of QGIS. QGIS now treats all labels as multiline.

      • James November 9, 2011 at 10:39 pm

        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!

  14. Brian Kelly (@spilth) January 7, 2012 at 2:13 pm

    I’m looking forward to using this. I was happy to see a String.upper function :-)

  15. Mayeul Kauffmann February 25, 2012 at 12:55 am

    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…) )?
    Namely:
    - 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.
    Examples:
    - 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.
    Cheers,
    Mayeul Kauffmann

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 497 other followers