Bug report #12749
when using custom functions to style a layer, map canvas gives wrong colors (incoherent with legend)
|Affected QGIS version:||master||Regression?:||No|
|Operating System:||Easy fix?:||No|
|Pull Request or Patch supplied:||No||Resolution:||end of life|
|Crashes QGIS or corrupts data:||No||Copied to github as #:||20848|
Sorry, I don't know how i may title this bug... Hope that I'll explain it well.
I've set a custom function that I apply to a categorized style. The result seems and I set the color to apply to each classes. OK
But when looking to the map canvas, the colors applied to the layer are not coherent with the choice I made. these are inverted count on the layer.
The attached file may better explain. As you can see, there should be no red feature (count =0) but all the features are shown in red.
Tested on windows
#3 Updated by Harrissou Santanna over 6 years ago
Sorry, it's not that kind of functions. I wrote a custom function in the function editor. I was learning how this feature works so I wrote this function that retrieves for each feature the number of filled fields (NULL values are set to be shown NULL). Here it is. This code adapted to the console returns right nb for each feature.
@qgsfunction(args=0, group='Custom') def compta(value1, feature, parent): nb = 0 for idx in range(len(feature.attributes())): attr = feature.attributes()[idx] if not attr == NULL : nb = nb +1 return nb
It can be applied on any data sample.
Then, Style menu > Categorized, fill the field box with $compta. Classify.
The classification shows the right classes. But when applied, it doesn't apply right colors although the "count features" is right as shown in previous attached file.
Labelling with this function doesn't seem to work properly.
#6 Updated by Sebastian Dietrich over 5 years ago
Seems like a caching issue. When classifying, the actual values of all attributes are fetched and the classification works correctly. However, the feature given to the user defined function compta() does not have the values filled in, so all features are counted as having no attributes set at all.
Probably an optimization to not fetch lots of stuff not needed for rendering anyway.
#8 Updated by Sebastian Dietrich over 5 years ago
Another interesting observation:
If you pass an attribute as a parameter, that attribute's value is available within feature.
@qgsfunction(args='auto', group='Custom') def firstAttr(dummy, feature, parent): return feature.attributes()
Make the expression
firstAttr(123) and it always returns NULL when drawing a feature.
Make the expression
firstAttr("NameOfFirstAttribute") and it returns the correct value when drawing a feature.
#9 Updated by Nyall Dawson over 5 years ago
Sebastian - does it help if you alter
QgsExpression.Function.__init__(self, name, args, group, helptext, usesgeometry)
QgsExpression.Function.__init__(self, name, args, group, helptext, usesgeometry, [QgsFeatureRequest.AllAttributes])
#10 Updated by Sebastian Dietrich over 5 years ago
does it help ...
Yes! The features are rendered correctly after that change.
I wonder if it could be an additional parameter to the
@qgsfunction() what attributes the function expects to be filled. E.g.
@qgsfunction(args='auto', group='Custom', attrs=['attr1', 'attr2'])
would load the values of the attributes named
@qgsfunction(args='auto', group='Custom', attrs=True)
would load the values of all attributes.
Unconditionally loading all attribute values when a user defined function is used in an expression might be a regression for some people with large layers, many attributes and a function that does not use the attribute values at all.
#13 Updated by Giovanni Manghi over 2 years ago
- Status changed from Open to Closed
- Resolution set to end of life
End of life notice: QGIS 2.18 LTR