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

  • 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 '17 at 9:49
  • unfortunately doesn't seem to work ether :/ – Nico Aug 3 '17 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 '17 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 '17 at 10:19
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\''

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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