shapely: minimum_rotated_rectangle is incorrect in 2.0.0
Expected behavior and actual behavior.
In shapely 2.0.0 the following code produces an incorrect minimum_rotated_rectangle with area=20.4 when it should be 20.
In shapely <2.0.0 the correct minimum_rotated_rectangle with area=20 is found.
Steps to reproduce the problem.
"""
In shapely 2.0.0 the following code produces an incorrect
minimum_rotated_rectangle with area=20.4 and raises:
> assert new_minimum_rotated_rectangle.area == true_minimum_rotated_rectangle.area
E assert 20.400000000000006 == 20.0
E + where 20.400000000000006 = <POLYGON ((5.1 5.3, 1.5 6.5, -0.2 1.4, 3.4 0.2, 5.1 5.3))>.area
E + and 20.0 = <POLYGON ((1 1, 1 6, 5 6, 5 1, 1 1))>.area
bug_in_2_0_0.py:32: AssertionError
"""
import numpy as np
import matplotlib.pyplot as plt
from shapely.geometry import MultiPoint, Polygon
def test_minimum_rotated_rectangle():
points = np.array(
[[1, 1], [1, 5], [3, 6], [4, 2], [5, 5]]
)
pts = MultiPoint(points)
new_minimum_rotated_rectangle = pts.minimum_rotated_rectangle
true_minimum_rotated_rectangle = Polygon([[1, 1], [1, 6], [5, 6], [5, 1]])
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(5, 5))
ax.plot(*points.T, c="red", marker=".")
ax.plot(*np.array(new_minimum_rotated_rectangle.boundary.coords).T,
c="green", marker="o", alpha=0.2
)
ax.plot(*np.array(true_minimum_rotated_rectangle.boundary.coords).T,
c="blue", marker="X", alpha=0.2
)
ax.set(xlim=(0, 10), ylim=(0, 10))
plt.show()
print(true_minimum_rotated_rectangle.area)
print(true_minimum_rotated_rectangle.boundary)
print(new_minimum_rotated_rectangle.area)
print(new_minimum_rotated_rectangle.boundary)
assert new_minimum_rotated_rectangle.area == true_minimum_rotated_rectangle.area
Operating system
Ubuntu, MacOS, Windows
Shapely version and provenance
Shapely 2.0.0 installed from PyPI using pip or from conda-forge using mamba.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 25 (20 by maintainers)
Commits related to this issue
- restore the custom oriented_envelope to solve https://github.com/shapely/shapely/issues/1670 add a new test and remove duplicated tests for oriented_envelope and minimum_rotated_rectangle — committed to idanmiara/shapely by idan-miara a year ago
- restore and vectorized the custom oriented_envelope to solve #1670 add a new test and remove duplicated tests for oriented_envelope and minimum_rotated_rectangle — committed to idanmiara/shapely by idanmiara a year ago
- restore and vectorized the custom oriented_envelope to solve #1670 add a new test and remove duplicated tests for oriented_envelope and minimum_rotated_rectangle — committed to idanmiara/shapely by idanmiara a year ago
- restore and vectorized the custom oriented_envelope to solve #1670 add a new test and remove duplicated tests for oriented_envelope and minimum_rotated_rectangle — committed to idanmiara/shapely by idanmiara a year ago
- restore and vectorized the custom oriented_envelope to solve #1670 add a new test and remove duplicated tests for oriented_envelope and minimum_rotated_rectangle — committed to idanmiara/shapely by idanmiara a year ago
- constructive.py - oriented_envelope: add a custom implementation (now default) to solve #1670, fix doctests oriented_envelope_custom.py - the actual custom implementation test_constructive.py - add re... — committed to idanmiara/shapely by idanmiara a year ago
In my head the idea would be that the default is still the original (1.x) shapely version? So the default of None would be “use whatever shapely currently think is best”, and in the future that might change to use the GEOS version if that gets fixed.
That preserves behaviour compared to shapely 1.8, and still gives the option to pass
method="minimum_diameter"(or different naming) for the people that prefer the currently faster method.On https://github.com/shapely/shapely/issues/1670#issuecomment-1607101266:
For the updated version of https://github.com/shapely/shapely/pull/1708 that I would like to include in the release, I removed the
methodkeyword, given that it’s not something we would like to keep long term, and the latest GEOS already provides the fast option. Conda users will already have GEOS 3.12 when installing shapely 2.0.2, and for pip users we will hopefully have a shapely 2.1 in some time (for those users, it’s a temporary step back in performance, but also only for a new feature of 2.0, not compared to 1.8)