Turfjs / turf

A modular geospatial engine written in JavaScript and TypeScript
https://turfjs.org/
MIT License
9.28k stars 938 forks source link

Bug: turf/difference removes arrays of MultiPolygon Input #1475

Closed codeofsumit closed 3 years ago

codeofsumit commented 6 years ago

Hi all! Great work again on the removal of jsts, it made leaflet.pm so much smaller and better 👍. I've tried to track down an issue in the plugin and I think it might be the output of difference.

Here's a gif showing a test of cutting an additional hole in a MultiPolygon: cutproblem

Here's the data for testing Input 1:

{
    type: 'Feature',
    properties: {
        name: 'Original Viereck',
        category: 'default',
        id: '6BA2d7Kdsr7ytyhERLcB',
    },
    geometry: {
        type: 'MultiPolygon',
        coordinates: [
            [
                [
                    [-74.007991, 40.712882],
                    [-74.002844, 40.710215],
                    [-73.995466, 40.714509],
                    [-74.002983, 40.716637],
                    [-74.003519, 40.71568],
                    [-74.005797, 40.715789],
                    [-74.007991, 40.712882],
                ],
            ],
            [
                [
                    [-74.005369, 40.716355],
                    [-74.003402, 40.716756],
                    [-74.004774, 40.717144],
                    [-74.005369, 40.716355],
                ],
                [
                    [-74.003605, 40.713988],
                    [-74.002854, 40.714769],
                    [-74.001266, 40.714167],
                    [-74.001609, 40.713289],
                    [-74.003605, 40.713988],
                ],
            ],
        ],
    },
};

Input 2:

{
    type: 'Feature',
    properties: {},
    geometry: {
        type: 'Polygon',
        coordinates: [
            [
                [-74.005558, 40.713403],
                [-74.005558, 40.712573],
                [-74.003949, 40.712573],
                [-74.003949, 40.713517],
                [-74.005558, 40.713403],
            ],
        ],
    },
};

Using difference 6.0.2 like this:

JSON.stringify(difference(g1, g2))

gives the result:

{
    type: 'Feature',
    properties: {},
    geometry: {
        type: 'Polygon',
        coordinates: [
            [
                [-74.005558, 40.713403],
                [-74.005558, 40.712573],
                [-74.003949, 40.712573],
                [-74.003949, 40.713517],
                [-74.005558, 40.713403],
            ],
        ],
    },
};
ilijaz commented 6 years ago

As I know new martinez realization of a difference doesn't support MultiPolygon geometries.

codeofsumit commented 6 years ago

@ilijaz ah ok, the turf docs currently suggest otherwise and might need an update: http://turfjs.org/docs#difference @w8r can you chim in if this is planned? This martinez issue might be related: https://github.com/w8r/martinez/issues/69 🤔

w8r commented 6 years ago

Not sure it's caused by martinez, please, look at this codepen https://codepen.io/w8r/pen/LJyOmP

codeofsumit commented 6 years ago

@w8r thanks for clarifying, so it seems martinez is in fact supporting MultiPolygons as input for difference

rowanwins commented 6 years ago

Hi @codeofsumit

Thanks for the bug report - I'll take a look at what's going

codeofsumit commented 6 years ago

@rowanwins have you been able to take a look yet?

Looking into @turf/difference in Line 54, it seems like it should return a MultiPolygon as the output from Martinez has a length of 2. When looking at my test result though, it's just a polygon 🤔

codeofsumit commented 5 years ago

hey folks! Just wanted to ask once more if you were able to take a look at this bug. In case we don't speak before: merry christmas to all of you! 🎄

rowanwins commented 5 years ago

Hi @codeofsumit

Looking into this a bit further, your original poly looks like the geojson is misformed.

The hole in your first poly is not nested deeply enough, it should be represented as

{
  "type": "FeatureCollection",
  "features": [
    {
    "type": "Feature",
    "properties": {},
    "geometry": {
        "type": "MultiPolygon",
        "coordinates": [
            [
                [
                    [-74.007991, 40.712882],
                    [-74.002844, 40.710215],
                    [-73.995466, 40.714509],
                    [-74.002983, 40.716637],
                    [-74.003519, 40.71568],
                    [-74.005797, 40.715789],
                    [-74.007991, 40.712882]
                ],
                 [
                    [-74.003605, 40.713988],
                    [-74.002854, 40.714769],
                    [-74.001266, 40.714167],
                    [-74.001609, 40.713289],
                    [-74.003605, 40.713988]
                ]
            ],
            [
                [
                    [-74.005369, 40.716355],
                    [-74.003402, 40.716756],
                    [-74.004774, 40.717144],
                    [-74.005369, 40.716355]
                ]

            ]
        ]
    }
}
  ]
}

I have noticed before that leaflet can do some funky things with rendering multipolys with holes

In the v7 branch I'm using the polygon-clipping library which looks like its going to do a good job of tracking holes and multipolys etc

rowanwins commented 3 years ago

Resolved in v6.2.0 onwards