Bug report #12749
when using custom functions to style a layer, map canvas gives wrong colors (incoherent with legend)
Status: | Closed | ||
---|---|---|---|
Priority: | Normal | ||
Assignee: | - | ||
Category: | Symbology | ||
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 |
Description
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
History
#1
Updated by Jürgen Fischer about 9 years ago
- Category set to Symbology
#2
Updated by Martin Dobias about 9 years ago
- Status changed from Open to Feedback
Works fine for me with tests like "$id > 10".
Probably something specific to your custom function... could you please post the function source and the data you used for testing?
#3
Updated by Harrissou Santanna about 9 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.
#4
Updated by Giovanni Manghi over 8 years ago
- Target version deleted (
Future Release - High Priority) - Status changed from Feedback to Open
- Priority changed from High to Normal
#5
Updated by Sebastian Dietrich over 8 years ago
- Affected QGIS version changed from 2.8.2 to master
Confirmed on master (25c289441ef2074826cf27aac6fb49667e8d9a23).
The behaviour is provider-specific. It does not occur when using a memory layer.
#6
Updated by Sebastian Dietrich over 8 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.
#7
Updated by Harrissou Santanna over 8 years ago
Thanks Sebastian for digging this.
Could this be related to #14273
#8
Updated by Sebastian Dietrich over 8 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()[0]
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 8 years ago
Sebastian - does it help if you alter
https://github.com/qgis/QGIS/blob/e9ef51341c2cef016648be6c619a4d43ffe362ca/python/core/__init__.py#L43
from
QgsExpression.Function.__init__(self, name, args, group, helptext, usesgeometry)
to
QgsExpression.Function.__init__(self, name, args, group, helptext, usesgeometry, [QgsFeatureRequest.AllAttributes])
?
#10
Updated by Sebastian Dietrich over 8 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
attr1
and attr2
.@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.
#11
Updated by Nyall Dawson over 8 years ago
Sounds reasonable. I'd open a PR and get Nathan to take a look, this is his baby ;)
#12
Updated by Giovanni Manghi over 7 years ago
- Easy fix? set to No
- Regression? set to No
#13
Updated by Giovanni Manghi over 5 years ago
- Status changed from Open to Closed
- Resolution set to end of life
End of life notice: QGIS 2.18 LTR
Source:
http://blog.qgis.org/2019/03/09/end-of-life-notice-qgis-2-18-ltr/