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++?
-
1There is a QGIS Book which shows a few methods.– JosephMar 31, 2015 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 WilsonMar 31, 2015 at 13:34
-
No problem, glad you found a solution :)– JosephMar 31, 2015 at 13:38
-
I implemented a Python example in my answer.– xunilkMar 31, 2015 at 23:44
2 Answers
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'):
After run the code in the Python Console of QGIS (line2 as Active Layer):
-
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 WApr 24, 2015 at 6:27
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'"));