shapely / shapely

Manipulation and analysis of geometric objects
https://shapely.readthedocs.io/en/stable/
BSD 3-Clause "New" or "Revised" License
3.9k stars 566 forks source link

Exception in affinity.rotate a polygon #2102

Closed buganini closed 3 months ago

buganini commented 3 months ago

Expected behavior and actual behavior.

T1 and T2 works, T3 leads to exception, T2 and T3 are just different by one vertex so I am not sure if it's a float precision issue

T1 POLYGON ((37.08909791235274 41.825815186890395, 61.23724356957945 35.35533905932738, 67.70771969714247 59.503484716554084, 24.148145657226706 -6.4704761275630185, 37.08909791235274 41.825815186890395))
T2 POLYGON ((37089097.91235274 41825815.18689039, 67707719.69714247 59503484.71655408, 24148145.657226708 -6470476.127563018, 37089097.91235274 41825815.18689039))
Traceback (most recent call last):
  File "/Users/buganini/repo/buganini/kikit-ui/rotate.py", line 34, in <module>
    p1 = affinity.rotate(p0, -15, origin=(0,0))
  File "/Applications/KiCad/KiCad.app/Contents/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/shapely/affinity.py", line 150, in rotate
    return affine_transform(geom, matrix)
  File "/Applications/KiCad/KiCad.app/Contents/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/shapely/affinity.py", line 74, in affine_transform
    return shapely.transform(geom, _affine_coords, include_z=ndim == 3)
  File "/Applications/KiCad/KiCad.app/Contents/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/shapely/coordinates.py", line 65, in transform
    geometry_arr = lib.set_coordinates(geometry_arr, new_coordinates)
shapely.errors.GEOSException: IllegalArgumentException: Points of LinearRing do not form a closed linestring

Steps to reproduce the problem.

from shapely import affinity
from shapely.geometry import Polygon

p0 = Polygon([
    (25, 50),
    (50, 50),
    (50, 75),
    (25, 0),
    (25, 50)
])

p1 = affinity.rotate(p0, -15, origin=(0,0))
print("T1", p1)

p0 = Polygon([
    (25000000, 50000000),
    # (50000000, 50000000),
    (50000000, 75000000),
    (25000000, 0),
    (25000000, 50000000)
])

p1 = affinity.rotate(p0, -15, origin=(0,0))
print("T2", p1)

p0 = Polygon([
    (25000000, 50000000),
    (50000000, 50000000),
    (50000000, 75000000),
    (25000000, 0),
    (25000000, 50000000)
])

p1 = affinity.rotate(p0, -15, origin=(0,0))
print("T3", p1)

Operating system

Apple M2 macOS Sonoma 14.3

Shapely version and provenance

2.0.4 installed from PyPI using pip

theroggy commented 3 months ago

I'm not able to reproduce.

What is the version of geos you are using?

I'm using geos 3.12.2 (via conda-forge). With a pip installation you probably won't be able to get to geos 3.12.2 yet (this is for shapely 2.1), but if you install shapely 2.0.5 you should get version 3.11.4 of geos which might help.

buganini commented 3 months ago

I was using 3.11.3-CAPI-1.17.3 Upgrading to shapely 2.0.5 fixes this issue.

jorisvandenbossche commented 3 months ago

This might have been a case of https://github.com/shapely/shapely/issues/2066 (which we indeed fixed in shapely 2.0.5)

theroggy commented 3 months ago

This might have been a case of #2066 (which we indeed fixed in shapely 2.0.5)

My test was with shapely 2.0.4 with GEOS 3.12.2 which didn't have the problem...

jorisvandenbossche commented 3 months ago

The issue was specific to MacOS 14+ with numpy 2.0 installed from wheels, so you probably didn't run into it while testing