2

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

4
  • Try adding inputlayer.triggerRepaint() at the end to refresh the layer. You could also use iface.legendInterface().refreshLayerSymbology(inputlayer) to refresh the legend symbology.
    – Joseph
    Aug 3, 2017 at 9:49
  • unfortunately doesn't seem to work ether :/
    – Nico
    Aug 3, 2017 at 10:08
  • What happens if you switch off all the other layers? Can the points be seen? If you right-click the points layer and go to Properties > Style, double-click a symbol and click the Test button to see if your expression is valid.
    – Joseph
    Aug 3, 2017 at 10:12
  • found the error, had to change "style" to "amenity"... so stupid - I'm sorry for your time Joseph, should definitely find it myself! 😅
    – Nico
    Aug 3, 2017 at 10:19

1 Answer 1

3

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\''
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.