[GIS] Managing rule-based renderer in PyQGIS

categorized-renderercolorpyqgisrule-based

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.

Some screenshots:
point size are set to 2 millimeters and should be visible

Best Answer

found the answer, just had to change "style" to "amenity" to make it work... for better understanding, the syntax for the expression is:

'"COLUMN_NAME" LIKE \'FEATURE\''
Related Question