2

I am trying to use overlay_intersects() inside an expression in order to loop through the features from a target layer that intersect with a feature having a certain "id".

request_string = "overlay_intersects(layer:='"+target_layer_name+"', filter:=id='"+matching_feature_id+"')"
features = current_layer.getFeatures(request_string)

for feat in features:
    print(feat.attribute('name')+" intersects with the feature having id '"+matching_feature_id+"'")

But this doesn't loop, all features are evaluated to false in this situation.

If I use the same expression in the Field Calculator and set a field like matches with it, this is going to work as expected: all features from the current layer that intersect with the one having id matching_feature_id in the target layer will have their field matches set to true and the others to false.

Field matches (boolean) = overlay_intersects(layer:='target_layer_name', filter:=id='matching_feature_id')

  • QGIS: 3.22.7-Białowieża
  • Python: 3.9.2
2
  • What are those variables target_layer_name and matching_feature_id in your expression? If they are variables you have defined previously in the Python code, then you need to insert them into the expression properly e.g. with f-string formatting, otherwise they will be interpreted as string literals. The same goes for how you are using it in your print statement.
    – Ben W
    Commented Jun 15, 2022 at 2:36
  • It's for the sake of clarity on StackEchange, they are indeed variables that end up being concatenated. But I also tried not using it as a variable and put the actual ids in the string to see if it works. I edited my question so it doesn't add unnecessary confusion Commented Jun 15, 2022 at 7:01

2 Answers 2

2

You must to build QgsFeatureRequest() object with your expression.

Try this:

request_string = "overlay_intersects(layer:='target_layer_name', filter:=id='matching_feature_id')"
request = QgsFeatureRequest().setFilterExpression(request_string)
features = current_layer.getFeatures(request)

for feat in features:
    print(feat.attribute('name')+' intersects with the feature having id "matching_feature_id"')

Take a look to the Filtering a layer with expressions documentation.

6
  • I test it and it worked fine. Verify that you are using the id of the layer not the name, an id looks like this: New_scratch_layer_436261ed_c8d0_47f2_8e0a_9c44c7079f65.
    – Mayo
    Commented Jun 14, 2022 at 14:27
  • Thanks. I tried it too but it didn't work, I just tried again with your code without success. It shouldn't be necessary to use this intermediate class according to the documentation qgis.org/pyqgis/3.22/core/… To me it seems like overlay_intersects() function doesn't behave the same in this context compared to the Field Calculator. Commented Jun 14, 2022 at 14:27
  • I did that too, seems to be a bug 🤔 Commented Jun 14, 2022 at 14:28
  • And the query thing works fine as I can get all the features by replacing the current expression by true to match all features. Commented Jun 14, 2022 at 14:30
  • Try without the filter first to debug the expression: overlay_intersects(layer:='target_layer_name')
    – Mayo
    Commented Jun 14, 2022 at 14:31
0

It seems that it was caused because the two layers were using two different projections (e.i. EPSG4326 and EPSG2154). I reprojected the first one to EPSG2154 and it worked!

However I'd be happy to get some hints from the community about why PyQGIS couldn't do it whereas the Field Calculator had no problem to deal with it. I was induced in error because the panel showed points correctly placed upon each other.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.