5

I think this used to be more straightforward in earlier QGIS versions, but with more powerful rule-based styling (great development) I am now a little confused as to how to apply a rule to multiple categories at once in the Style dialogue.

In the example below, I've styled my data using categories. I want to apply the $id = $atlasfeatureid rule to all categories because I'm working on an Atlas.

I'm guessing I'm missing something simple, but can't think what. It's not a problem to apply rule separately to a few categories but when working with 50+ it would be very time consuming.

enter image description here

7

You could add the main rule $id = $atlasfeatureid, without adding symbols:

enter image description here

enter image description here

Then select and drag all the other rules over it (over the label part). They should then become dependent of this first rule:

enter image description here

  • Thanks Victor - you mean apply $id = $atlasfeatureid when it's on Single Symbol and then drag all rules over it? If so, I'm not sure what is meant by 'drag the other rules over it' - I'm probably just not thinking straight, sorry! – Alasdair Rae Dec 8 '16 at 10:41
  • 1
    No. Create an additional new rule, without giving it any symbol. Then select all the other rules and drop and drag them over this new rule. It will make them dependent of this one. – Victor Dec 8 '16 at 10:46
  • Ah, right - I get you now. Thanks a lot for helping. – Alasdair Rae Dec 8 '16 at 10:53
  • 1
    I've edited my answer to make it clearer. – Victor Dec 8 '16 at 10:55
3

You could also use the following in the Python Console to change all expressions of each rule to $id = $atlasfeatureid:

layer = qgis.utils.iface.activeLayer()
renderer = layer.rendererV2()
for rule in renderer.rootRule().children():
    rule.setFilterExpression('$id = $atlasfeatureid')

Edit:

The above code replaces all expressions entirely. However, if you want to add another expression to an existing one, you can use:

layer = qgis.utils.iface.activeLayer()
renderer = layer.rendererV2()
for rule in renderer.rootRule().children():
    rule.setFilterExpression('({}) AND $id = $atlasfeatureid'.format(rule.filterExpression()))
  • 1
    Aha - great tip! Thanks for this one, I'll try that too. – Alasdair Rae Dec 8 '16 at 11:28
  • @AlasdairRae - Most welcome =) – Joseph Dec 8 '16 at 11:29
  • @Joseph Great to know. However, shouldn't the script add AND $id = $atlasfeatureid to each of the rules rather than replacing them entirely? – Victor Dec 8 '16 at 11:51
  • 1
    @Victor - Thanks, edited post to include adding a new expression to the existing ones. Hope this helps! – Joseph Dec 8 '16 at 11:56
  • @ndawson - Thanks for the edit, that makes sense :) – Joseph Dec 9 '16 at 10:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.