For a combination of 3 specific valid polygons, applying unaryUnion on them gives an error using GEOS 3.14.1.
C:\Tools\miniforge3\envs\pysnippets\Library\bin\geosop.exe -a "GEOMETRYCOLLECTION (POLYGON ((-8.060879443418989 -2.6638274935170196, -8.194659017192153 -33.71089267415941, -11.242630721688515 -33.69775918301853, -11.10885114791535 -2.6506940023761434, -8.060879443418989 -2.6638274935170196)), POLYGON ((-84.63155622050482 -2.3338899473058037, -84.61842272936394 0.7140817571905578, -8.047745952278113 0.3841442109793418, -8.06087944341899 -2.6638274935170196, -84.63155622050482 -2.3338899473058037)), POLYGON ((-84.63155622050482 -2.3338899473058037, -84.61842272936394 0.7140817571905576, -11.095717656774472 0.3972777021202178, -11.108851147915349 -2.6506940023761434, -84.63155622050482 -2.3338899473058037)))" unaryUnion
Run-time exception: AssertionFailedException: found two shells in EdgeRing list
If all input polygons are oriented ccw first, the error does not occur, but e.g. nomalizing does not help.
Originally posted here: shapely/shapely#1639 (comment)
Visualization of input:
Full script to reproduce some different scenarios:
import os
import matplotlib.pyplot as plt
import shapely
from shapely import normalize, orient_polygons, plotting, unary_union, wkt
buffer_0 = wkt.loads('POLYGON ((-8.060879443418989 -2.6638274935170196, -8.194659017192153 -33.71089267415941, -11.242630721688515 -33.69775918301853, -11.10885114791535 -2.6506940023761434, -8.060879443418989 -2.6638274935170196))')
buffer_1 = wkt.loads('POLYGON ((-84.63155622050482 -2.3338899473058037, -84.61842272936394 0.7140817571905578, -8.047745952278113 0.3841442109793418, -8.06087944341899 -2.6638274935170196, -84.63155622050482 -2.3338899473058037))')
buffer_2 = wkt.loads('POLYGON ((-84.63155622050482 -2.3338899473058037, -84.61842272936394 0.7140817571905576, -11.095717656774472 0.3972777021202178, -11.108851147915349 -2.6506940023761434, -84.63155622050482 -2.3338899473058037))')
buffers = [buffer_0, buffer_1, buffer_2]
print(f"{all([b.is_valid for b in buffers])=}") # True
try:
print(f"{unary_union(buffers)=}")
except Exception as e:
print(f"Exception: {e}")
try:
print(f"{unary_union([normalize(b) for b in buffers])=}")
except Exception as e:
print(f"Exception after normalize: {e}")
try:
print(f"{unary_union([orient_polygons(b, exterior_cw=True) for b in buffers])=}")
except Exception as e:
print(f"Exception after orient_polygons with exterior_cw=True: {e}")
# orient_polygons with exterior_cw=False does work though
print(f"{unary_union([orient_polygons(b) for b in buffers])=}")
# Running with geosop gives the same error:
# Run-time exception: AssertionFailedException: found two shells in EdgeRing list
geosop = "C:\\Tools\\miniforge3\\envs\\pysnippets\\Library\\bin\\geosop.exe"
wkt = shapely.GeometryCollection(buffers).wkt
cmdline = f'{geosop} -a "{wkt}" unaryUnion'
print(f"Running command: {cmdline}")
os.system(cmdline)
# Visiualize the input
plotting.plot_polygon(buffer_0, color='red')
plotting.plot_polygon(buffer_1, color='green')
plotting.plot_polygon(buffer_2, color='blue')
plt.show()
Output:
all([b.is_valid for b in buffers])=True
Exception: AssertionFailedException: found two shells in EdgeRing list
Exception after normalize: AssertionFailedException: found two shells in EdgeRing list
Exception after orient_polygons with exterior_cw=True: AssertionFailedException: found two shells in EdgeRing list
unary_union([orient_polygons(b) for b in buffers])=<POLYGON ((-8.061 -2.664, -8.195 -33.711, -11.243 -33.698, -11.109 -2.651, -...>
Running command: C:\Tools\miniforge3\envs\pysnippets\Library\bin\geosop.exe -a "GEOMETRYCOLLECTION (POLYGON ((-8.060879443418989 -2.6638274935170196, -8.194659017192153 -33.71089267415941, -11.242630721688515 -33.69775918301853, -11.10885114791535 -2.6506940023761434, -8.060879443418989 -2.6638274935170196)), POLYGON ((-84.63155622050482 -2.3338899473058037, -84.61842272936394 0.7140817571905578, -8.047745952278113 0.3841442109793418, -8.06087944341899 -2.6638274935170196, -84.63155622050482 -2.3338899473058037)), POLYGON ((-84.63155622050482 -2.3338899473058037, -84.61842272936394 0.7140817571905576, -11.095717656774472 0.3972777021202178, -11.108851147915349 -2.6506940023761434, -84.63155622050482 -2.3338899473058037)))" unaryUnion
Run-time exception: AssertionFailedException: found two shells in EdgeRing list
For a combination of 3 specific valid polygons, applying unaryUnion on them gives an error using GEOS 3.14.1.
If all input polygons are oriented ccw first, the error does not occur, but e.g. nomalizing does not help.
Originally posted here: shapely/shapely#1639 (comment)
Visualization of input:
Full script to reproduce some different scenarios:
Output: