shapely / shapely/shapely

Unexpected divide by zero errors

Open
#1,787 3 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

geos needs info
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.