1

I am looking for an example of how to use the QgsRuleBasedRendererV2 to filter features of a layer based on an attribute value (0 or 1). Has anyone done this in Python or C++?

  • 1
    There is a QGIS Book which shows a few methods. – Joseph Mar 31 '15 at 13:06
  • Thanks, I will give that a read as well. I have already implemented a simple start thanks to the qgis IRC. – William Wilson Mar 31 '15 at 13:34
  • No problem, glad you found a solution :) – Joseph Mar 31 '15 at 13:38
  • I implemented a Python example in my answer. – xunilk Mar 31 '15 at 23:44
1

Courtesy of NathanW in the qgis IRC channel and some playing around, the solution is rather simple. An example where features with the field alt set to 1 will display differently than other features.

in generic c++ (you will need to fill in the gaps yourself):

layer->addAttribute( *new QgsField( "alt", QVariant::String ) );
feature.initAttributes(1);
feature.setAttribute(0,QVariant(QString("1")));

pRuleRender = new QgsRuleBasedRendererV2( defaultSymbol() );
pRuleRender->rootRule()->appendChild(new Rule(alternateSymbol(),0,0, "alt='1'"));
1

This is an example of Python Code:

from PyQt4.QtGui import *

# define some rules: label, expression, color name, width
my_rules = (
    ('Feature one', '"type" LIKE \'first\'', 'green', 2),
    ('Feature two', '"type" LIKE \'second\'', 'red', 2),
    ('Feature three', '"type" LIKE \'third\'', 'blue', 2),
)

layer = iface.activeLayer()

# create a new rule-based renderer
symbol = QgsSymbolV2.defaultSymbol(layer.geometryType())
renderer = QgsRuleBasedRendererV2(symbol)

# get the "root" rule
root_rule = renderer.rootRule()

for label, expression, color_name, width in my_rules:
    # create a clone (i.e. a copy) of the default rule
    rule = root_rule.children()[0].clone()
    # set the label, expression and color
    rule.setLabel(label)
    rule.setFilterExpression(expression)
    rule.symbol().setColor(QColor(color_name))
    rule.symbol().setWidth(width)
    # append the rule to the list of rules
    root_rule.appendChild(rule)

# delete the default rule
root_rule.removeChildAt(0)

# apply the renderer to the layer
layer.setRendererV2(renderer)

iface.mapCanvas().refresh()

I tested it with this line vector layer ('expression' in field 'type'):

enter image description here

After run the code in the Python Console of QGIS (line2 as Active Layer):

enter image description here

  • This is a good solution. Nice and generic which is cool. Turn it into a function and you could walk a tree to make all the rules – Nathan W Apr 24 '15 at 6:27

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.