NULL and None
Fun fact: NULL is not None
With this in mind it's easy to fix the code
@qgsfunction(args=-1, group='Custom')
def mean_col(cols, feature, parent):
vals = [feature[i] for i in cols if feature[i] != NULL]
return sum(vals)/float(len(vals))
Do not write to layers in expressions
Additional advice: never write to layers in expressions. Expressions are often executed in threads and in different contexts and using layer.changeAttributeValue()
and similar functions may result in undefined behavior (read: crash).
Using values instead of attribute names
Another interesting experiment for educational purpose.
Instead of providing column names to the function, you can also provide values.
@qgsfunction(args='auto', group='Custom')
def mean_value(vals, feature, parent):
vals = [val for val in vals if val != NULL]
return sum(vals)/float(len(vals))
And then call it with
mean_value("kk1", "kk2", "kk3", "kk4")
The interesting result is: it will return NULL as soon as at least one column is NULL.
How comes? QGIS assumes the result for an expression function is NULL as soon as at least one parameter is NULL for performance reasons. It's possible to control this behavior, but unfortunately the @qgsfunction
decorator does not support this to date (QGIS 3.2).
To workaround this behavior we can either provide a full-blown QgsExpressionFunction
implementation which is out of scope for this answer.
Or just take a little detour and use an array instead.
@qgsfunction(args='auto', group='Custom')
def mean_value(vals, feature, parent):
vals = [val for val in vals if val != NULL]
return sum(vals)/float(len(vals))
and then call it with
mean_value(array("kk1", "kk2", "kk3", "kk4"))
Use the "Value Relation" field widget to select multiple items from a list
1. Create a spreadsheet with two columns.
Call the first column "key." In this column, enter the values that you want saved in the attribute table. You can use your keywords, or you can assign a shorter key to each keyword. For example, I used numbers as my keys. The value "hotel" will be saved in the attribute table as 1. This allows you to store relatively long values in a more compact format. You could also use abbreviations, such as h for hotel, and g for garden. If you prefer, you can put the same value in each column.
Call the second column "value." In this column, put all of your keywords ("restaurant", "hotel", "garden" and so on).
[![enter image description here][1]][1]
Save the spreadsheet in csv format.
2. Import the csv as an attribute-only table (ie without geometry).
3. Set up value relation widget
Open layer properties for the historical areas layer.
Open the Attributes Form tab.
Select the field (in my example the field is "categories").
For Widget Type, choose "value relation." For layer, select the table you added in step 2. (in my example the table is called "book2"). For key, select the key column. For value, select the value column.
When you create a new point, the data entry form will now give you a checklist.
The attribute table will store multiple values in a single field:
Best Answer
When you add a new a field from the attribute table, you can add a comment to that field.
You can view the comment in the layer properties...
...and by mousing over the field name in the edit feature form.
Note: There are probably other ways to use the field comment feature, but I couldn't find any documentation. Basically every website has a comment section, so "comment" is useless as a search term.
There's no way to add comment text to an existing field (at least not that I could find, but see the note above). A workaround would be to create a new field with the desired comment. Then fill the new field with values from the old field, and delete the old field.
Tested adding a field with a comment with the following file types: