I have a layerA with roads and a layerB with one shortest path.
If I put an aggregate function into a virtual field in layerB to calculate the sum of fieldAA where the shortest path contains features of layerA, it returns the sum of every feature in layerA.
I tried different expression and they returned all the same result (sum of every feature):
aggregate( 'layerA', 'sum', "fieldAA", contains($geometry, $geometry))
aggregate( 'layerA', 'sum', "fieldAA", contains(geometry($currentfeature), $geometry))
aggregate( 'layerA', 'sum', "fieldAA", within($geometry, geometry($currentfeature)))
In the documentation you find
So I was wondering to which geometry they both refer to and how I can perform an expression like contains(geometry currentfeature layerA, geometry features layerB)
Suggestions on how to get the same result with a custom pythoncode in the function editor are also welcome.
Best Answer
As far as I know, the filter expression (fourth parameter of
aggregate
) can only access fields and values from the referenced layer (layerA
in your example) and not from the layer you're going to store results into (i.e.,layerB
). Two possible solutions could be:Join attributes by location
from Processing (selectcontains
asGeometric predicate
and the valuesum
forStatistics for summary
).Function Editor
and use Python code.I'll elaborate more on the second solution.
A function with the following parameters would be handy in your case:
layerA
for you).layerA
to aggregate (fieldAA
for you).So, go to
Field Calculator
, open theFunction Editor
, create a new file, and paste this code:Click on Load to register the functions above, go to the
Expression
tab and write this expression:Still in the
Field Calculator
, create/choose your target field (fromlayerB
) and clickOK
.You should get the sum of
fieldAA
from only those features inlayerA
contained by each feature inlayerB
.NOTE 1: The
sum_contains()
function uses a cache to avoid building the whole spatial index for each feature (source: How to Use Function Editor in QGIS Field Calculator).NOTE 2: Once you use the aforementioned expression the cache is built for the road layer, so, if you edit features from such layer and you want to use the
sum_contains()
function again, you would need to go toFunction Editor
, select the file you created, and click onLoad
so that the index is initialized again. Otherwise, you would be using an outdated index.EDIT: Adding in-line comments to explain the code.