Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QGIS Expression - overlay_intersects #59408

Open
2 tasks done
pigreco opened this issue Nov 11, 2024 · 15 comments
Open
2 tasks done

QGIS Expression - overlay_intersects #59408

pigreco opened this issue Nov 11, 2024 · 15 comments
Labels
Bug Either a bug report, or a bug fix. Let's hope for the latter! Expressions Related to the QGIS expression engine or specific expression functions

Comments

@pigreco
Copy link
Contributor

pigreco commented Nov 11, 2024

What is the bug or the crash?

I noticed that using the return_details and sort_by_intersection_size options does not give the expected results.

If the object to evaluate has more parts or is multipart, the output is incorrect, that is, the output returns only the length (or area) of the largest part.

In the image below I highlight the fact that the L-shaped segment is calculated only the length of the longest segment.
image

In the case of Multipolygon with separate parts, the area of ​​the largest overlap is calculated and not the overall area.
image

Steps to reproduce the issue

I attach an example project (use the views to correctly display the two cases)I attach an example project (use the views to correctly display the two cases)

progetto_overlap.zip

https://discourse.osgeo.org/t/espressione-di-qgis-overlay-intersects/111118/1

Versions

Versione di QGIS3.41.0-Master
Revisione codice QGISfda2aa46e9
 
Librerie
Versione Qt5.15.13
Versione Python3.12.7
Versione GDAL/OGR3.11.0dev-b281c45d9a
Versione PROJ9.5.0
Versione database del Registro EPSGv11.016 (2024-08-31)
Versione GEOS3.13.0-CAPI-1.19.0
Versione SQLite3.46.1
Versione PDAL2.8.1
Versione client PostgreSQL16.2
Versione SpatiaLite5.1.0
Versione QWT6.3.0
Versione QScintilla22.14.1
Versione SOWindows 11 Version 2009
Questa copia di QGIS scrive messaggi di debug.
 
Plugins Python attivi
DataPlotly4.2.0
felt3.1.5
gps_replay0.0.5
HCMGIS24.10.20
mmqgis2021.9.10
nominatim_locator_filter0.3.2
profile-manager0.31
qconsolidate1.1.0
qduckdb1.0.1
quick_map_services0.19.34
relazioniplugin1.1
SelectionFilter1.0
db_manager0.1.20
MetaSearch0.3.6
processing2.12.99

The problem is present on QGIS 3.34.12, QGIS 3.40.0 and the master

Supported QGIS version

  • I'm running a supported QGIS version according to the roadmap.

New profile

Additional context

No response

@pigreco pigreco added Expressions Related to the QGIS expression engine or specific expression functions Bug Either a bug report, or a bug fix. Let's hope for the latter! labels Nov 11, 2024
@pigreco
Copy link
Contributor Author

pigreco commented Nov 11, 2024

I add a demo:
note that the L-shaped sides

2024-11-11_14h03_45.mp4

@agiudiceandrea
Copy link
Member

agiudiceandrea commented Nov 11, 2024

@elpaso, may you have a look at this?
From the docs and from the description of your PR #46683 it is unclear what the value of the 'overlap' key is supposed to contain exactly when the return_details parameter is set to true.

I would assume it should contain the area / length of the geometry resulting from the intersection between the current feature's geometry and each intersecting feature from the layer whose intersection is checked.

When the geometry resulting from the intersection is composed by a single part, that assumption seems correct.
When the geometry resulting from the intersection is composed by more then one part, then it looks like the value of the 'overlap' key contains the area / length of only (the greatest) one of the geometry's parts, instead of the area / length of the whole geometry.

Moreover, when the geometry resulting from the intersection is composed by e.g. a polygon and a line (i.e. a GeometryCollection), then the resulting array item is missing in the function result.

@elpaso elpaso self-assigned this Nov 15, 2024
@elpaso
Copy link
Contributor

elpaso commented Nov 15, 2024

It's been a while but looking at the specifications the overlap value is supposed to return the maximum value in case of multiple matches (at least for linestring case).

The goal of this implementation was to have a tool to identify small (difficult to catch by eye) imperfections in the digitized shapes, to be corrected manually, having the max value allows to filter for intersections that are below a small given value.

When the result of an intersection is a geometry collection of different geometry types the design decision was to return nothing.

So, it seems to me that this is the expected behavior, perhaps we can clarify it in the documentation.

@elpaso
Copy link
Contributor

elpaso commented Nov 15, 2024

@andreasneumann maybe you remember better than me if this is the expected behavior.

I am happy to fix this if it is confirmed to be a bug.

@andreasneumann
Copy link
Member

@andreasneumann maybe you remember better than me if this is the expected behavior.

I am happy to fix this if it is confirmed to be a bug.

@elpaso I used this at my previous employer Kanton Solothurn. They care only about area/area overlaps and did not care about the length of lines in the intersection areas. So we did not test this behaviour back then.

So I think it would be good to fix this, if the behaviour is like @pigreco describes.

@elpaso
Copy link
Contributor

elpaso commented Nov 15, 2024

@andreasneumann maybe you remember better than me if this is the expected behavior.
I am happy to fix this if it is confirmed to be a bug.

@elpaso I used this at my previous employer Kanton Solothurn. They care only about area/area overlaps and did not care about the length of lines in the intersection areas. So we did not test this behaviour back then.

So I think it would be good to fix this, if the behaviour is like @pigreco describes.

Happy to fix it as I said, but the thing is that I am having an hard time to understand what would be the expected behavior (i.e. if there is a bug or not).

Returning the total length of the overlapping segments at first makes sense but it would be different than the behavior for polygons which by design returns the biggest overlapping part (so that you can easily filter for overlaps below a certain threshold).

As far as geometry collections are the result of an intersection what should we return instead of nothing: the length, the area or both?

@elpaso
Copy link
Contributor

elpaso commented Nov 15, 2024

Summarizing: we have two separate topics here:

  1. in case of multiple intersects with the same geometry type the result is by design to return the biggest/largest intersecting part measurement length or area (this is not a bug: it was by design)
  2. in case the multiple intersects are of different geometry type the choice was to return nothing (again: not a bug because there isn't a choice that makes sense except maybe to return null, or 0 or -1 instead of nothing at all).

@agiudiceandrea
Copy link
Member

agiudiceandrea commented Nov 15, 2024

@elpaso, I'm not sure to understand the purpose of such design logic.

Please see the following examples:

  1. 'L1' blue: Polygon ((0 0, 0 6, 6 6, 6 0, 0 0)) | 'L2' green: Polygon ((6 0, 6 2, 4 2, 4 4, 6 4, 6 6, 12 6, 12 0, 6 0))
    image

    overlay_intersects('L1',@id) (on L2) correctly returns [ 1 ]
    overlay_intersects('L1',@id,return_details:=true) (on L2) incorrectly returns [ ] like there was no intersection.

  2. 'L1' blue: Polygon ((0 0, 0 6, 6 6, 6 0, 0 0)) | 'L2' green: Polygon ((7 0, 7 1, 5 1, 5 2, 7 2, 7 3, 4 3, 4 5, 7 5, 7 6, 12 6, 12 0, 7 0))
    image

    The intersection of the two geometries is a multi-part polygon with an area of 5 units, composed by a part with an area of 4 units and another part with an area of 1 unit.
    overlay_intersects('L1',@id,return_details:=true) (on L2) returns [ { 'id': 1, 'overlap': 4, 'radius': 1, 'result': 1 } ]: the returned overlap value is 4 units (only the area of the biggest part) while in my opinion it should be 5 units (the total area).
    Even considering the described use case ("you can easily filter for overlaps below a certain threshold"), then the correct returned overlap value should be 1, i.e. the area of the smallest part, otherwise, if I want to filter the intersections containing overlaps below the value of e.g. 2, this intersection will be incorrectly missed.

  3. 'L1' blue: LineString (0 0, 1 1, 2 1, 3 1, 4 0) | 'L2' green: LineString (0 2, 1 1, 2 1, 3 1, 4 2)
    image

    The intersection of the two geometries (the green / blue dashed line) is a line with length of 2 units.
    overlay_intersects('L1',@id,return_details:=true) (on L2) returns [ { 'id': 1, 'overlap': 1, 'result': 1 } ]: the returned overlap value is 1 unit instead of 2 units.

@pigreco
Copy link
Contributor Author

pigreco commented Nov 15, 2024

My point of view:

in case the overlap is a line (even starting from two polygons), it must return the total length of the line and not its longest part, in fact as you can see from the screenshot, it doesn't make sense (for me) that it returns only the longest part.

image

elpaso added a commit to elpaso/QGIS that referenced this issue Nov 18, 2024
Partial fix for qgis#59408

- try to merge multilinestrings to get the max length
- consider the tested geomery type when intersection is a collection

Funded by: Body & Soul 🎵
elpaso added a commit to elpaso/QGIS that referenced this issue Nov 18, 2024
Partial fix for qgis#59408

- try to merge multilinestrings to get the max length
- consider the tested geomery type when intersection is a collection

Funded by: Body & Soul ♬
@elpaso
Copy link
Contributor

elpaso commented Nov 18, 2024

I respect your opinion about what makes sense to you but you must admit that others may see that differently.

IIRC the use case was to identify accidental/unwanted overlapping polygons, this means that if the result of the intersection between polygons has multiple parts (if we have only one part we all agree about the expected behavior) in order to decide whether this is accidental or not you are not interest in the smallest intersection neither in the sum of the intersections but in the value of the biggest one, because if the largest intersection is bigger than x it you can reasonably suppose that the overlap between the two features couldn't happen by mistake, so you can make a filter to return all the features that have an intersection (with their biggest part, if multi) smaller than x to fetch the list of potential mistakes to be manually checked.

It makes sense to me and most certainly to who commissioned and funded this work.

Now I can understand that there are other use cases where the report details may behave differently but I'm not gonna change the established behavior: you may turn this ticket into a feature request but it is definitely not a bug (except for the documentation enhancement).

@agiudiceandrea
Regarding what to return in case of feature collection results (mixed types like in your first example above) I agree that there is an issue and we should IMHO return the polygons value in case the tested geometry is a polygon , a length in case it is a linestring and ignore the rest.

So, what I am going to fix is your

  • case number 1 when return details is set, meaning that it will match and return '4' (this was a case of geometry collection result)
  • case number 3 when return details is set, meaning that it will match and return '2' (even if the intersection calculated by GEOS is actually two segments of length 1)

Case number 2 shows the expected behavior.

@pigreco
Copy link
Contributor Author

pigreco commented Nov 18, 2024

It makes sense to me and most certainly to who commissioned and funded this work.

Ok, but I only discovered the use case now, before it was not explained anywhere.

Then, it is a use case not very intuitive and therefore for me it was a bug.

The sum of the parts is instead intuitive and is very useful in data analysis.

thanks for the time dedicated, for me we can close the issue

@pigreco
Copy link
Contributor Author

pigreco commented Nov 20, 2024

@elpaso
but then you fixed it, now it works!
I get the sum of the segments.
I downloaded and tested this #59477 (comment)

image

Grazie mille!!!

@pigreco
Copy link
Contributor Author

pigreco commented Nov 21, 2024

Unfortunately it is true only if the parts are contiguous and not separate
image

@pigreco
Copy link
Contributor Author

pigreco commented Nov 29, 2024

I close the issue because I understand that there is no will to fix it (and maybe it's late to do so)
I just add that the use case explained is very particular and should not be in the core of QGIS but implemented as a plugin.

I would like to understand how many people use these new options, in my opinion no one.

regards

@pigreco pigreco closed this as completed Nov 29, 2024
@pigreco
Copy link
Contributor Author

pigreco commented Dec 5, 2024

I'm reopening the issue, maybe it's necessary to merge the related PR?

@pigreco pigreco reopened this Dec 5, 2024
elpaso added a commit to elpaso/QGIS that referenced this issue Dec 5, 2024
Partial fix for qgis#59408

- try to merge multilinestrings to get the max length
- consider the tested geomery type when intersection is a collection

Funded by: Body & Soul ♬
elpaso added a commit to elpaso/QGIS that referenced this issue Dec 5, 2024
Partial fix for qgis#59408

- try to merge multilinestrings to get the max length
- consider the tested geomery type when intersection is a collection

Funded by: Body & Soul ♬
elpaso added a commit to elpaso/QGIS that referenced this issue Dec 9, 2024
Partial fix for qgis#59408

- try to merge multilinestrings to get the max length
- consider the tested geomery type when intersection is a collection

Funded by: Body & Soul ♬
qgis-bot pushed a commit that referenced this issue Dec 11, 2024
Partial fix for #59408

- try to merge multilinestrings to get the max length
- consider the tested geomery type when intersection is a collection

Funded by: Body & Soul ♬
@elpaso elpaso removed their assignment Jan 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Either a bug report, or a bug fix. Let's hope for the latter! Expressions Related to the QGIS expression engine or specific expression functions
Projects
None yet
Development

No branches or pull requests

4 participants