6

I have a simple project in QGIS 3.10.5: a polygon layer and a point layer. When the user add a point feature which intersects a polygon feature, a calculate field make this intersection and get the id attribute of the polygon feature.

In my desktop project, I used refFunctions extension, and result is ok. I have a calculate field in my point layer with an expression: geomintersects('polygonLayer', 'polygonID').

I deployed this project in QField and refFunctions isn't working anymore, even when geopackage is synchronised with desktop project. I tried an other expression without using, refFunctions but it's not working better.

aggregate(
layer:= 'polygonLayer',
aggregate:='concatenate',
expression:=polygonID,
concatenator:=', ',
filter:=intersects($geometry, geometry(@parent))
)

How to calculate an intersection between two layers (and get an attribute value) with QField?

Can I use a "native" QGIS function to make this intersection in a calculate field? (without using aggregate because my field is an integer id)

-- EDIT

In my point layer, I also have a date field wich have a default value format_date( now(),'yyyy-MM-dd HH:mm:ss'). When I add a feature in QField, date is well calculated and displayed in the form but aggregate function result isn't. When I synchronize my layer with QFieldSync, date value is ok but my intersection field with aggregate function is NULL.

How to explain this? Both are functions, why behaviours are different?

Documentation seems to indicate, this should works, maybe I'm missing something.

2 Answers 2

10

refFunctions won't work in QField as it is a QGIS desktop plugin (and is the downside of the many answers that rely on a plugin for expression-based solutions) - QField won't recognise the functions.

With your aggregate expression, consider using expression:=to_string("polygonID") if the polygonID field is numeric, as concatenate only works on string values.

Note 2021-08: Above is now outdated as QField from at least version 1.8 onwards supports QGIS 3.16 expressions which does include the ported version of refFunctions - overlay_intersects(), overlay_within() etc. Please use these instead as they are much more elegant!

e.g. array_to_string(overlay_intersects('polygonLayer',"polygonID"))

The rest of this answer is more about handling the expression when layer names have changed for whatever reason.


If your expression isn't working because the underlying field name has changed, you have two options:

Option 1: Use Layer ID

You can obtain the layer ID in the Expression window under Map Layers; double-click the layer you want.

enter image description here

Although the layer ID contains the original filename in front the reference stays the same even if you change the layer name. The example below shows two aggregate expression inside the point labels, one using the layer ID for the line layer, the other using the layer name (initially named tr_road).

When I change the layer name the expression using the layer ID still evaluates, but the expression using the layer name fails completely (which was probably what happened to you)

enter image description here


Option 2: Test for valid layer name

The downside to layer IDs is that they are unique each layer in a project. If your aggregate expression is designed to always pick up a specifically named layer but you expect it to refer to any potential layer with that name (including a layer you might add later, or another layer renamed accordingly), it won't work.

To catch these errors you can use try() to return a value or attempt a different expression if the original expression fails. The expression below returns 'Layer not found' as a text string. You can make it NULL or an empty string if you don't want anything to display.

try(array_to_string(overlay_intersects('polygonLayer',"polygonID")),'Layer not found')

Alternatively, if your layer name change is predictable and your overlay_intersects() (or aggregate()) expression only needs to look at one of two options, try the following expression to use either layer name or layer name (offline)

try(
aggregate(
layer:= coalesce(layer_property('polygonLayer','name'),
                 layer_property('polygonLayer (offline)','name')),
aggregate:='concatenate',
expression:=to_string("polygonID"),
concatenator:=', ',
filter:=intersects($geometry, geometry(@parent))
), 'Layer not found')

or for QGIS 3.16 onwards:

try(
    array_to_string(
       overlay_intersects(coalesce(layer_property('polygonLayer','name'),
                                   layer_property('polygonLayer (offline)','name')),
                      "polygonID"),
                ','),
  'Layer not found')

For more complex cases where you want it to pick the first of a potentially long list of layer names, consider using with_variable() and array functions instead, so you can more easily edit your list at the top of your expression and add/remove items easily. I have put that expression in the relevant GitHub discussion thread here.

enter image description here

8
  • Ok, thanks. It's ok with this expression. I have also delete the concatenator, which is, in my case, not used. An other issue, wich maybe deserve a new post : in QGIS side, attributes default calculated value is well displayed when I identify my feature by clicking on it, but is NULL in the attributes table... am I missing something ?
    – GeoGyro
    May 2, 2020 at 11:27
  • I have edited my original post to be more specific.
    – GeoGyro
    May 2, 2020 at 11:42
  • I get it : I use QFieldSync to synchronyze my layer, and this plugin rename layer with a (offline) suffix, so in QField aggregate functions can't find this layer named without this suffix in my expression. When I change aggregate function with polygonLayer (offline), everything is ok. Hope this will rectified one day. Thanks to this post.
    – GeoGyro
    May 2, 2020 at 17:06
  • 1
    I have updated the answer with a potential solution to your invalid layer name problem with aggregate() - it has been something that has bugged me before as well
    – she_weeds
    May 3, 2020 at 2:52
  • 1
    @Taras - I use a software called ScreenToGif on Windows. I'm sure there are similar programs for other OSes.
    – she_weeds
    May 11, 2020 at 7:41
2

Great news, the last release of QFieldSync preserve the layer name without (offline) suffix. I made a quick test with aggregate function and coalesce isn't needed anymore, values are well calculated with the original layer name.

1
  • This requires QGIS 3.16.1 or newer Nov 29, 2020 at 20:01

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.