boolean-contains: incorrectly returns true for Polygon with bite taken out of the side and the polygon's boundary box #1897
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
npm test
at the sub modules where changes have occurred.npm run lint
to ensure code style at the turf module level.When using Turfjs to generate quadtiles from OpenStreetMap country boundaries, I ran into scenario where boolean-contains returns true when it should not have. The polygons in question are:
I am checking if the polygon with the "bite" taken out the side contains the rectangular tile that clipped it. boolean-contains returns true, when it should return false.
The current logic does a check that all the points of the contained polygon lie within the containing polygon. This is obviously a good short-cut test to perform, but cannot give a definitive yes answer.
I looked at the JTS implementation of cover() to get an idea of how they are doing it. They have some point-in-poly shortcut tests, then have to do a full topological comparison. I used cover() rather than contains() because it matches the implementation of how turfjs has defined contains, in regards to polygon boundaries. The comments on JTS contains() vs compare() code do a good job outlining the difference.
My PR to fix this adds another check to the logic. Only return true if the difference between the polygon being contained and the containing polygon is null. IE, check that there is no part of the contained polygon outside of the containing polygon.
I have added equivalent logic to boolean-within, as well as test cases to both.
On the topic of boolean-within, the logic is slightly different to boolean-contains, specifically it's handling of features with null geometries. If this is meant to be an exact opposite of boolean-contains, perhaps it can simply import the boolean-contains package and call it with swapped parameters, rather than duplicating the code in both packages?