jts icon indicating copy to clipboard operation
jts copied to clipboard

Buffer 0 of a Polygon returns a Multipolygon

Open james-willis opened this issue 1 year ago • 3 comments

I have the an invalid polygon with a bowtie in it. when I call buffer(0) on it I am returned a MultiPolygon when I was expecting a Polygon. Is this expected behavior? shapely/GEOS does the same thing as JTS on the example below.

I though buffering a polygon with an arg >= 0 should always return a polygon.

As a work around I am getting the first geometry from the MultiPolygon using .getGeometryN(0)

example polygon:

POLYGON ((0.2168424022222222 0.7856802211875938, 0.2168423616666666 0.7856805547357139, 0.216842553888889 0.78568063640693, 0.2168426177777778 0.7856804854181173, 0.2168427411111111 0.7856805005170004, 0.2168427861111111 0.7856801251037353, 0.2168428594444445 0.7856799528390603, 0.2168435277777778 0.7856802376591108, 0.2168431877777777 0.7856801964803175, 0.2168431094444445 0.7856803810985494, 0.2168428927777777 0.7856803550186543, 0.2168428677777778 0.785680560912529, 0.2168430827777779 0.7856806528784344, 0.2168431522222223 0.7856804902223075, 0.2168434072222223 0.785680521106386, 0.2168436483333334 0.7856799542116875, 0.2168427677777778 0.785679579484358, 0.2168426700000001 0.7856795678170193, 0.2168423383333333 0.7856794271226224, 0.2168421033333332 0.7856799789189748, 0.2168421794444444 0.7856793440785954, 0.2168418766666667 0.7856792157378013, 0.2168416766666668 0.7856796858630218, 0.2168416394444443 0.7856799940178721, 0.2168420844444443 0.7856801827540525, 0.2168424022222222 0.7856802211875938))

example result after calling buffer(0):

MULTIPOLYGON (((0.2168424022222222 0.7856802211875938, 0.2168423616666666 0.7856805547357139, 0.216842553888889 0.78568063640693, 0.2168426177777778 0.7856804854181173, 0.2168427411111111 0.7856805005170004, 0.2168427861111111 0.7856801251037353, 0.2168428594444445 0.7856799528390603, 0.2168435277777512 0.7856802376590994, 0.2168436483333334 0.7856799542116875, 0.2168427677777778 0.785679579484358, 0.2168426700000001 0.7856795678170193, 0.2168423383333333 0.7856794271226224, 0.2168421033333332 0.7856799789189748, 0.2168421794444444 0.7856793440785954, 0.2168418766666667 0.7856792157378013, 0.2168416766666668 0.7856796858630218, 0.2168416394444443 0.7856799940178721, 0.2168420844444443 0.7856801827540525, 0.2168424022222222 0.7856802211875938)), ((0.2168435277777479 0.7856802376591071, 0.2168431877777777 0.7856801964803175, 0.2168431094444445 0.7856803810985494, 0.2168428927777777 0.7856803550186543, 0.2168428677777778 0.785680560912529, 0.2168430827777779 0.7856806528784344, 0.2168431522222223 0.7856804902223075, 0.2168434072222223 0.785680521106386, 0.2168435277777479 0.7856802376591071)))

james-willis avatar Jun 07 '24 23:06 james-willis

In general JTS does not guarantee results for invalid geometry inputs. Buffer does a bit better than this, in that it can produce reasonable results for invalid inputs. But it guarantees that the output is valid. In this case, the only way to produce a valid result that is faithful to the input linework is to convert the shape into a MultiPolygon.

Note that while in the past buffer(0) was the recommended way (hack!) to turn invalid polygons into valid geometry, this has been superseded by the GeometryFixer API. This is likely available in Shapely as well, as make_valid.

dr-jts avatar Jun 07 '24 23:06 dr-jts

Thanks for the quick and informative response.

I noticed the following quote from the GeometryFixer documentation:

Polygon: transform into a valid polygon...

However, my testing revealed that the GeometryFixer (and make_valid in shapely) has the same behavior as buffer(0).

Is this intended behavior? If so I could submit a PR to update the documentation to reflect that fixing a polygon may return a multipolygon

james-willis avatar Jun 08 '24 00:06 james-willis

I noticed the following quote from the GeometryFixer documentation:

Polygon: transform into a valid polygon...

However, my testing revealed that the GeometryFixer (and make_valid in shapely) has the same behavior as buffer(0).

Is this intended behavior? If so I could submit a PR to update the documentation to reflect that fixing a polygon may return a multipolygon

Yes, that is intended behaviour. Feel free to submit a PR, or I can update it.

dr-jts avatar Jun 08 '24 05:06 dr-jts