Skip to content

UnaryUnion gives error: found two shells in EdgeRing list #1355

@theroggy

Description

@theroggy

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:

Image

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions