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

Incorrect @turf/intersect result with polygon holes #2230

Open
TractsCTO opened this issue Nov 30, 2021 · 2 comments · May be fixed by #2346
Open

Incorrect @turf/intersect result with polygon holes #2230

TractsCTO opened this issue Nov 30, 2021 · 2 comments · May be fixed by #2346
Assignees
Milestone

Comments

@TractsCTO
Copy link

TractsCTO commented Nov 30, 2021

@turf/intersect version: 6.5.0
@turf/mask version: 6.5.0
@turf/helpers version: 6.5.0

Intersect does not produce a correct result when a polygon contains a hole, that hole contains an island, and the polygon to be intersected intersects that island. The part intersecting the island is ignored in the output.

As a simple example, here we create a large square with a small square hole in the middle, and use turf mask to invert it, then intersect that resulting mask with another large square of the same dimensions but without the hole. In this example, result is null, when in fact it should be a polygon with the same dimensions as the small square:

import {polygon} from '@turf/helpers';
import turfMask from '@turf/mask';
import turfIntersect from '@turf/intersect';

// coordinates of a 16 x 16 square:
const square = [[[0,16],[0,0],[16,0],[16,16],[0,16]]];
// coordinates of the same square, but with a 4 x 4 hole in the middle:
const withHole = [[[0,0],[16,0],[16,16],[0,16],[0,0]],[[6,6],[6,10],[10,10],[10,6],[6,6]]];
const pSquare = polygon(square); // the square polygon
const pWithHole = polygon(withHole); // the square with hole polygon
const mask = turfMask(pWithHole); // the mask (inverse) of the square with hole
// the intersection of the mask with the square:
const result= turfIntersect(mask, pSquare); // result is null, should be a 4 x 4 square
@tmcw
Copy link
Collaborator

tmcw commented Oct 8, 2022

I think that this fails at a different stage. turf-mask doesn't care about inverting the inner rings of its input, so the geometry for mask in this example is just a world geom minus the square geometry.

CleanShot 2022-10-08 at 11 00 49@2x

I think, as far as I can tell, that the bug is that turf-mask should return a MultiPolygon in this case, which would allow the "inverted" geometry to have an island:

CleanShot 2022-10-08 at 11 01 37@2x

And that then works properly with turf-intersect.

This hinges on whether turf-mask is really expected to "invert" features, or whether it's just masking the outer ring. I don't have a preference or leaning there.

Demo: https://observablehq.com/d/f74ec973c66b1940

(there's a checkbox in there to toggle whether to use a multipolygon)

@rowanwins rowanwins linked a pull request Oct 9, 2022 that will close this issue
4 tasks
@rowanwins
Copy link
Member

I've added a PR #2346 that adds support for holes to @turf/mask, I've left default behaviour the same but there is now an optional argument so that it can be over-ridden in cases like these.

@rowanwins rowanwins self-assigned this Oct 9, 2022
@rowanwins rowanwins added this to the 7.0.0 milestone Oct 9, 2022
@smallsaucepan smallsaucepan modified the milestones: v7, v8 Dec 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants