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

Issue with turf.difference behavior between Turf.js v5.16 and v6.5 (and recent versions) #2836

Open
elyeshkiri opened this issue Feb 10, 2025 · 1 comment

Comments

@elyeshkiri
Copy link

elyeshkiri commented Feb 10, 2025

I’ve encountered a discrepancy in the behavior of the turf.difference function between Turf.js versions 5.16 and 6.5.

In version 5.16, using turf.difference to subtract holes (multipolygon) from a world polygon works as expected, producing the correct result. However, when I update to version 6.5, the output is incorrect or differs from the expected result.

Steps to Reproduce:

Use the following world polygon as the outer boundary:

const worldPolygon = turf.polygon([[
    [-180.0, 89.0],
    [-180.0, -89.0],
    [180.0, -89.0],
    [180.0, 89.0],
    [-180.0, 89.0]
]]);

Use the multipolygon as the holes:

const multiPolygon =  turf.multiPolygon([
    [
        [
            [
                1.5848481682316446,
                48.31986594114687
            ],
            [
                1.8832104345803926,
                48.42342314863003
            ],
            [
                1.8734490264407953,
                48.31243967954646
            ],
            [
                2.0474541685456376,
                48.433892157002646
            ],
            [
                1.9407386741551667,
                48.44339036470831
            ],
            [
                2.139324407980982,
                48.51231658749331
            ],
            [
                2.140165825025228,
                48.54733551405033
            ],
            [
                2.005794737854104,
                48.62423252424017
            ],
            [
                2.14201346746852,
                48.62423252424017
            ],
            [
                2.1464195901569383,
                48.80761089514678
            ],
            [
                2.017641560842897,
                48.71825624766248
            ],
            [
                1.9156353862877893,
                48.79208242133859
            ],
            [
                1.9086020675566275,
                48.71211628317572
            ],
            [
                1.977029724641852,
                48.69007709065282
            ],
            [
                1.9380268126907942,
                48.663014310869556
            ],
            [
                1.9059004038856775,
                48.68139940276142
            ],
            [
                1.9020902267645763,
                48.638079149302555
            ],
            [
                1.8821344534680975,
                48.62423252424017
            ],
            [
                1.9008723646838,
                48.62423252424018
            ],
            [
                1.8853998352913024,
                48.448315795534654
            ],
            [
                1.7548343829094222,
                48.459936767662384
            ],
            [
                1.5848481682316446,
                48.31986594114687
            ]
        ]
    ],
    [
        [
            [
                1.7796498887017833,
                48.75364922492895
            ],
            [
                1.9059004038856775,
                48.68139940276142
            ],
            [
                1.9086020675566275,
                48.71211628317572
            ],
            [
                1.7796498887017833,
                48.75364922492895
            ]
        ]
    ],
    [
        [
            [
                2.0474541685456376,
                48.433892157002646
            ],
            [
                2.269137922503419,
                48.414161204603545
            ],
            [
                2.3139242542554825,
                48.62423252424017
            ],
            [
                2.14201346746852,
                48.62423252424017
            ],
            [
                2.140165825025228,
                48.54733551405033
            ],
            [
                2.1779387566694766,
                48.52571906686143
            ],
            [
                2.139324407980982,
                48.51231658749331
            ],
            [
                2.13897493841921,
                48.497772017709025
            ],
            [
                2.0474541685456376,
                48.433892157002646
            ]
        ]
    ],
    [
        [
            [
                2.268015568539596,
                48.408896777510364
            ],
            [
                2.2741686461205703,
                48.41371344527771
            ],
            [
                2.269137922503419,
                48.414161204603545
            ],
            [
                2.268015568539596,
                48.408896777510364
            ]
        ]
    ],
    [
        [
            [
                2.2741686461205703,
                48.41371344527771
            ],
            [
                2.4578541878508133,
                48.39736452202297
            ],
            [
                2.4938366712502784,
                48.58567095470934
            ],
            [
                2.2741686461205703,
                48.41371344527771
            ]
        ]
    ]
])

Apply turf.difference to subtract each hole from the world polygon;

let result = turf.difference(worldPolygon, multiPolygon);

The output from Turf.js v5.16 works as expected, but in Turf.js v6.5, the result is incorrect.

Expected Result:

The world polygon should have the specified holes subtracted correctly, and the resulting polygon should reflect these changes.

Image

https://jsfiddle.net/om39s8fh/1/

Actual Result:

In Turf.js v6.5 and recent versions, the output is incorrect, and the holes do not seem to be subtracted from the world polygon as expected.
https://jsfiddle.net/yg2dj108/2/

Image

@hf-farmqa
Copy link

hf-farmqa commented Feb 17, 2025

Time for me to pile on to this with another example. Specifically with changes from 6.5 to 7+

const targetBody = {
  type: "Feature",
  properties: {},
  geometry: {
    type: "Polygon",
    coordinates: [[[-97.21939, 47.192546], [-97.219274, 47.192509], [-97.219274, 47.192416], [-97.219311, 47.192354], [-97.219428, 47.192352], [-97.219512, 47.192469], [-97.21939, 47.192546]]],
  },
};

const shapeToRemove = {
  type: "Feature",
  properties: {},
  geometry: {
    type: "Polygon",
    coordinates: [
      [[-97.21946286472821, 47.192500011605965], [-97.21936021525944, 47.192446501553235], [-97.2193683023461, 47.1925390791966], [-97.21939, 47.192546], [-97.21946286472821, 47.192500011605965]]],
  },
};

Shapes look like this where we want to remove the orange chunk from the yellow section.
Image

// Turf 6.5

const diff = turf.difference(targetBody, shapeToremove);

  {
    "type": "Feature",
    "properties": {},
    "geometry": {
      "type": "Polygon",
      "coordinates": [[[-97.219512,47.192469], [-97.219428,47.192352], [-97.219311,47.192354], [-97.219274,47.192416], [-97.219274,47.192509], [-97.2193683023461,47.1925390791966], [-97.21936021525944,47.192446501553235], [-97.21946286472821,47.192500011605965], [-97.219512,47.192469]]]
    }
  }

Expected results. The orange segment is removed
Image

// Turf 7+

const diff = turf.difference(turf.featureCollection([targetBody, shapeToremove]));

{
  "type": "Feature",
  "properties": {},
  "geometry": {
    "type": "Polygon",
    "coordinates": [
        [[-97.219512,47.192469], [-97.219428,47.192352], [-97.219311,47.192354], [-97.219274,47.192416], [-97.219274,47.192509], [-97.21939,47.192546], [-97.219512,47.192469]],
        [[-97.21939,47.192546], [-97.2193683023461,47.1925390791966], [-97.21936021525944,47.192446501553235], [-97.21946286472821,47.192500011605965], [-97.21939,47.192546]]
    ]
  }
}

Very unexpected results. Get back a polygon containing two rings

  1. The first/exterior ring of the original yellow section
  2. An interior ring which closely resembles the original orange section (being interpreted as a hole)

The outputs suggest that the diff decided that I was just cutting a hole out of the original shape instead of an entire segment. 

This rendering is a little odd but the result is that same convex yellow shape with a hole that is extremely close the edges
Image

You might say: "The shapeToRemove geometry here is just off a bit. Use something that aligns better with the edges of the target shape, or better yet, extends beyond them"

To which I would reply: "The shapeToRemove here comes directly from the result of a turf.intersect between the targettBody and an original shape. The orange section is the result of that intersect and I would expect it to be as 'best-est' a shape as I can get for this kind of diff"

I've seen loads of examples of likely related issues where diff leaves behind these thin tails or slivers that it didn't in 6.5.
Something changed in the 7+ release that adjusted this. Idk if this is a wholly unexpected bug or if the changes made things 'too precise' comparatively and so all of these little things that were truncated are started to show up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants