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') 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().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) rule.setScaleMaxDenom(scale) # 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 use
iface.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.