This is my first project in QGIS and I'm also quite new to Python. PyQGIS is more than a challenge for me!
I found code in How to programmatically set a rule-based renderer in QGIS? to set a rule based renderer which is exactly what I need for my project! I Already slightly modified it (only the rule expressions), so that it would fit into my project.
I got all my "sub points" listed with the correct color in my layer window. But the actual points on the canvas are gone!
Here is my function so far:
def change_color2():
try:
inputlayer = QgsMapLayerRegistry.instance().mapLayersByName('points')[0]
print ('points-layer found')
idx = inputlayer.fieldNameIndex('amenity')
if not idx:
print ('"amenity" does not exist')
else:
print ('"amenity" does exist')
# define some rules: label, expression, color name, (min scale, max scale)
poi_rules = (
('restaurant', '"type" LIKE \'restaurant\'', 'red', None),
('school', '"type" LIKE \'school\'', 'green', None),
('pub', '"type" LIKE \'pub\'', 'orange', (10.0, 10000.0,)),)
# create a new rule-based renderer
symbol = QgsSymbolV2.defaultSymbol(inputlayer.geometryType())
renderer = QgsRuleBasedRendererV2(symbol)
# get the "root" rule
root_rule = renderer.rootRule()
for label, expression, color_name, scale in poi_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))
# set the scale limits if they have been specified
if scale is not None:
rule.setScaleMinDenom(scale[0])
rule.setScaleMaxDenom(scale[1])
# 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
inputlayer.setRendererV2(renderer)
except IndexError:
print ('points does not exist')
...do I have do take all possibilities of "amenity" into the renderer rules? Because I just picked those of interest by now... And isn't it necessary to iterate through the features to update them and also important the refresh map canvas? If so, I unfortunately don't have a clue how/where to implement in the existing code.
inputlayer.triggerRepaint()
at the end to refresh the layer. You could also useiface.legendInterface().refreshLayerSymbology(inputlayer)
to refresh the legend symbology.Properties > Style
, double-click a symbol and click the Test button to see if your expression is valid.