One of my favorite features of QGIS – Rule based styling.


One of my favorite features of QGIS is the rule based rendering.

QGIS rule based rendering dialog
QGIS rule based rendering dialog

If you’re using MapInfo think of thematics + queries but on steroids. Rule based rendering allows you to you set, well, rules on what gets rendered and how.  The rules are based on a simple SQL style query language that’s built into QGIS.

Take for example the above screen shot.   The screen shot is from a current project I am doing in QGIS to clean up our current stormwater/drainage layer.  The layer is a in a bit of a mess at the moment so I needed a way to visualize what I have cleaned up and what I haven’t, so enter QGIS rule based styling.

For example: A pipe that has an upstream and downstream invert and is part of the trunk (main) network is then considered valid (for this situation anyway), so I created the following rule:

network_type = 'Trunk' AND Description != 'Drainage Imaginary Pipe' AND (US_Invert > 0 AND DS_Invert > 0)

We also have little connecting pipes that I don’t want to include in valid trunk  as they are only used to connect pits to pipes and are just cosmetic, I have excluded them by adding “Description !=’Drainage Imaginary Pipe’” to the above filter.

Next I wanted to show invalid trunk network pipes (ones without an up or downstream invert), so we just invert the last condition and swap the last AND for a OR:

network_type = 'Trunk' AND Description != 'Drainage Imaginary Pipe' AND (NOT US_Invert > 0 OR NOT DS_Invert > 0)

I also need to show but no highlight the non trunk pipes and the connecting pipes, so I made the next two rules and set their styles to a light gray:

NOT network_type = 'Trunk' AND NOT Description = 'Drainage Imaginary Pipe'
Description = 'Drainage Imaginary Pipe'

Finally I want to show pipe direction on all pipes but not the connecting pipes, again as they are just cosmetic:

Description != 'Drainage Imaginary Pipe'

You will also note in the screenshot above that I have a max zoom scales set on the last three rules, this is because when I zoom out all that info becomes overwhelming at that scale and distracts from showing the invalid parts of the main trunk line.

So after all that, the results:

Screenshot of rules applied
Map rendered using rules

and if I zoom out pass 5,000:

Screenshot of rules applied, zoomed past 5,000
Map rendered when zoomed out pass 5,000

I think you can see how this rule based rendering could be very powerful, in fact I have about four different rule sets I use with the drainage layer to show different things to different people.

The rules I have shown above are pretty simple, you can go pretty crazy and use them to render OpenStreetMap data: http://www.youtube.com/watch?v=NBBYtH2svw0

The worst part about the rule based rendering is that I have gotten so used to their power that I feel crippled when I go back to MapInfo and try to do styling :)

Happy mapping.

What is your favorite QGIS feature?

20 thoughts on “One of my favorite features of QGIS – Rule based styling.

  1. […] One of my favorite features of QGIS – Rule based styling … The worst part about the rule based rendering is that I have gotten so used to their power that I feel crippled when I go back to MapInfo and try to do styling :). Happy mapping. Bonus: What is your favorite QGIS feature […]

  2. Nathan, I appreciated your posting, it opens up a new realm of uses for QGIS for me. Is there any way of wildcarding strings in the SQL-like queries? For example I would like to be able to distinguish between horizontal and vertical benchmarks in a survey benchmark data file that I have. The Survey benchmarks are designated by a two digit number followed by a R character followed by a three digit number, e.g. 84R006 . Would there be a way to symbolize these points differently than the others?

    thanks,
    Bob Bruce

    1. Thanks for the comment.

      You can do string wildcards using %, so you would do something like ‘%R%’ and that should work, although that would also pick up stuff like 5464R1641654 also. I’m not sure if you can say must be two digits at the front then so many after like you could with a regex. I’ll check and get back to you.

  3. Nathan, I tried the query STN_NO = ’84R206′ and it returned 1 feature. Then I tried using wildcards with this query STN_NO = ‘%R%’ and it returned 0 features. I also tried the query STN_NO = ’84R%’ and it returned 0 features. Have you personally tried using wildcards?

    Bob Bruce

    1. The trick is to use the LIKE keyword instead of =. So try: STN_NO LIKE ‘%R%’

      The expressions also have support for regex which I only found out today by looking in the code, so something like this would work: STN_NO ~ ‘\\d{2}R\\d{3}’

      Note the ~ in the expression above that tells QGIS that the following string is a regex, you also have to use \\ in front of any regex keywords. The docs for QGIS style regex can be found here: http://doc.qt.nokia.com/latest/qregexp.html

      If you haven’t done regex before ‘\\d{2,}R\\d{3,}’ can be broken down to:
      \\d{2} = Any digit exactly 2 times
      R = R
      \\d{3} = Any digit exactly 3 times.

      Although I would use regex sparingly as I would say they would have a performance hit. Every time the map renders the objects in view are checked against the rules; so design them as light as possible.

      Of course one or two should be fine, I didn’t see any slow down on my machine, but 10 regex rules and all at different zoom levels may take a bit of a hit.

    2. Hi,
      Nice post! I am the one went “pretty crazy” with OSM and rule base rendering as I made the video mentioned in the post: “you can go pretty crazy and use them to render OpenStreetMap data: http://www.youtube.com/watch?v=NBBYtH2svw0 “.
      I also went “crazy” with wildcards as I used them intesively to workaround some discrepancies among OSM coders, or just to save a few processing steps. You’ll view some of those tricks in the video.
      Mayeul

  4. Nathan,

    What version of QGIS are you using and with what OS? I am using 1.6.0 Capiapo with Windows XP and my Layers Properties dialog looks nothing like your screenshots above. I do not have the tabs for Symbology, Labels, etc. I have those as icons in a scroll area on the left. I also can’t find anything that refers to Renderer or Rule-based symbology in the Layers Properties.

    After reading you posting I am interested in giving the rule-based symbology a shot.

    Thanks,
    Paul

    1. Pual,

      You will need to be running version 1.7+. 1.7 is being packaged for release now so it should be out in the next week or two.

      Or you can get the latest dev build using the OSGeo4W installer and selecting qgis-dev.

  5. Nathan,

    Thanks for the response!

    That is what I had assumed so found the listing on the QGIS page of the trunk version being available with OSGeo4W. I downloaded that and had started to download and install the newest version of QGIS. I am looking forward to giving the rule-based symbology a try. By the way, it looks like QGIS has really come a long way. I am interested in taking a look at their map creation process which seems to be the only area where ESRI products have the advantage anymore.

    Paul

    1. Good stuff.

      Yeah QGIS has come a long way, even since 1.6. There are some good development in the works which should be ready before the next major 2.0 QGIS release in year or so, hopefully they will give QGIS a bit more a edge.

  6. Thanks for this, I use QGIS at home and ArcMap at work, the two approaches ARE very different – “horses for courses” / to each task their tool (I live near the Newmarket racecourse in East Anglia) – I have yet to find Esri Model Builder elsewhere in mapping – Safe Software uses similar object mapping for data transformation for but not inside mapping – do you know of anyone who does that? For details see my top two postings on http://bit.ly/j10G2w

    1. There is a QGIS Processing Framework in the works (https://github.com/polymeris/qgis/wiki) which once done will pave the way to have a Model builder kind of thing in QGIS. The idea would be any tool that uses the Processing Framework could be chained together, so you could do: QGIS->GRASS->SAGA GIS->GRASS->QGIS This would be a big feature for QGIS I think.

      1. Thx look forward to that! Does it not seem, however, to be a tool to concatenate tasks _among_ apps, rather than a Model-builder that concatenating tasks _within_ esri? Again, ‘horse for courses’…

  7. @Andrew Well all the apps will be interfaced though QGIS and hopefully this framework will mean that you can move between the apps functionality all though QGIS without even knowing you are using GRASS or SAGA. The internal QGIS tools will also be wrapped in the interfaces so they can be linked together (well that is my idea anyway). The general feel from the team is it is better to use the tools that other people have done and integrate them into QGIS rather then build them into QGIS again and have yet another implementation of the same stuff that everyone else does.

    Only time will tell with the framework, it’s a GSoC project so it should be done by the end of the year.

    1. Thx for the detailed info, agree on all points, just looking to link processes _within_ Qgis. But I guess the proof of the pudding is in the making – download Wroclaw and perhaps await that year-end release… over&out

  8. Thanks Nathan, the regex expression worked well. Using your rule I was able to separate the geodetic reference points and symbolize them nicely. Is there a way to use that rule to separately label the points so that I could just show the station names for those points? I would be happy to supply you with a screenshot of the effects of the rule if you would like.

    I really like the ability to mash together different symbols into one so that for the geodetic reference point I was able to add a cross on top of a filled square to show the reference points and the centers.

    1. There are no rules for labels at the moment, something I have considered adding. I am currently working on expression based labeling which I think will fit your needs to some extent, I’ll blog about it once it is done. You should, although I haven’t tested it, be able to use a regex as the expression for a label and cut out the bits of the string you need.

      Yeah the stacked layer symbols in QGIS are pretty cool. I don’t use them a lot but they have come in handy at times.

      If you could share a screen shot of the rules and results that would be sweet. I’ll throw it up on the blog post as a example of what can be done.

Leave a reply to To My Favorite Cancel reply