Unexpected divide by zero errors
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 4.5k
- Forks
- 631
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 10
Description
I have a valid polygon that looks fine on the surface from what I can tell, but they if I try and simplify it I get a divide by error in GEOS that bubbles up to an error in python.
import numpy as np
import shapely
from shapely.wkt import loads
rawp = loads("POLYGON ((5.757315768570891 477.44961942445883, 90.77830516299935 543.8752973639498, 248.07849054369257 342.5402442964279, 464.48223238911964 241.62951691200377, 413.06565212535094 131.36631050791692, 416.62730100296994 126.80760789705967, 365.4518827373675 17.06157503979785, 361.89023385974843 21.620277650655183, 32.689759002847666 442.9776645778203, 5.757315768570891 477.44961942445883))")
def simplify(poly):
mindist = 5
with np.errstate(over="raise", divide="raise", invalid="raise"):
return poly.simplify(np.sqrt(mindist), preserve_topology=True)
simplify(rawp) # fails
simplify(shapely.set_precision(rawp, 1e-8)) # fine
Gives the following error
---------------------------------------------------------------------------
FloatingPointError Traceback (most recent call last)
Cell In[1], line 12
9 with np.errstate(over="raise", divide="raise", invalid="raise"):
10 return poly.simplify(np.sqrt(mindist), preserve_topology=True)
---> 12 simplify(rawp) # fails
13 simplify(shapely.set_precision(rawp, 1e-8)) # fine
Cell In[1], line 10, in simplify(poly)
8 mindist = 5
9 with np.errstate(over="raise", divide="raise", invalid="raise"):
---> 10 return poly.simplify(np.sqrt(mindist), preserve_topology=True)
File /opt/conda/lib/python3.10/site-packages/shapely/geometry/base.py:547, in BaseGeometry.simplify(self, tolerance, preserve_topology)
538 def simplify(self, tolerance, preserve_topology=True):
539 """Returns a simplified geometry produced by the Douglas-Peucker
540 algorithm
541
(...)
545 otherwise invalid geometries.
546 """
--> 547 return shapely.simplify(self, tolerance, preserve_topology=preserve_topology)
File /opt/conda/lib/python3.10/site-packages/shapely/decorators.py:77, in multithreading_enabled.<locals>.wrapped(*args, **kwargs)
75 for arr in array_args:
76 arr.flags.writeable = False
---> 77 return func(*args, **kwargs)
78 finally:
79 for arr, old_flag in zip(array_args, old_flags):
File /opt/conda/lib/python3.10/site-packages/shapely/constructive.py:881, in simplify(geometry, tolerance, preserve_topology, **kwargs)
846 """Returns a simplified version of an input geometry using the
847 Douglas-Peucker algorithm.
848
(...)
878 <POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))>
879 """
880 if preserve_topology:
--> 881 return lib.simplify_preserve_topology(geometry, tolerance, **kwargs)
882 else:
883 return lib.simplify(geometry, tolerance, **kwargs)
FloatingPointError: divide by zero encountered in simplify_preserve_topology
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the supplied Python reproducer and inspect shapely/geometry/base.py around BaseGeometry.simplify and shapely/constructive.py around simplify_preserve_topology. Trace how the call reaches GEOS and identify why this polygon triggers a divide-by-zero under numpy.errstate while the precision-adjusted version does not. Done means the reproducer no longer raises unexpectedly and the behavior is covered by an appropriate regression test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100