Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when MultiLineString degenerates into LineString #14

Closed
mxwell opened this issue Jan 27, 2018 · 3 comments
Closed

Error when MultiLineString degenerates into LineString #14

mxwell opened this issue Jan 27, 2018 · 3 comments

Comments

@mxwell
Copy link

mxwell commented Jan 27, 2018

For some inputs _create_centerline() returns LineString, which breaks MultiLineString constructor. Not sure, if that is so by design.

Anyway, here is an example:

from centerline import Centerline
from shapely.geometry import Polygon

p = Polygon([(614, 1005), (614, 1010), (617, 1010), (617, 1009), (620, 1009), (620, 1010), (621, 1010), (621, 1011), (624, 1011), (624, 1010), (625, 1010), (625, 1006), (624, 1006), (624, 1005), (619, 1005), (619, 1006), (618, 1006), (618, 1005), (614, 1005)])

c = Centerline(p, 10)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-f6be4fb7d387> in <module>()
----> 1 c = Centerline(p, 10)

~/.local/lib/python3.6/site-packages/centerline/main.py in __init__(self, input_geom, interpolation_dist, **attributes)
     61             setattr(self, key, attributes.get(key))
     62 
---> 63         super(Centerline, self).__init__(lines=self._create_centerline())
     64 
     65     def _create_centerline(self):

/opt/conda/envs/pytorch-py3.6/lib/python3.6/site-packages/shapely/geometry/multilinestring.py in __init__(self, lines)
     50             pass
     51         else:
---> 52             self._geom, self._ndim = geos_multilinestring_from_py(lines)
     53 
     54     def shape_factory(self, *args):

/opt/conda/envs/pytorch-py3.6/lib/python3.6/site-packages/shapely/geometry/multilinestring.py in geos_multilinestring_from_py(ob)
    117 
    118     obs = getattr(ob, 'geoms', ob)
--> 119     L = len(obs)
    120     assert L >= 1
    121     exemplar = obs[0]

TypeError: object of type 'LineString' has no len()

If you consider this an issue, I can provide PR.

Thanks.

@fitodic
Copy link
Owner

fitodic commented Jan 27, 2018

@mxwell Thanks for pointing that out! 👍

I'm just curious, considering the polygon's structure, is there a reason for using such a large border density value (i.e. 10)? Have you tried reducing this value?

I'm asking because this library uses the scipy's Voronoi algorithm for creating centerlines. Depending on the polygon's structure and the border density parameter set by the user, the Voronoi algorithm might not be able to produce enough vertices that lie completely inside the polygon (i.e. do not intersect the polygon's boundary). In that case, the output centerline can be reduced to a single line (which you were able to reproduce) or even a single point (an edge case that's already discarded).

This brings us to the problem at hand. Is this the result you were looking for?
screenshot_20180127_164838

@mxwell
Copy link
Author

mxwell commented Feb 3, 2018

Sorry for late reply.

Regarding my use case, this particular polygon is much smaller than others in the input and probably should be discarded by some kind of filter. But if I failed to filter it out or tune the density appropriately, then the single line will do.

My point is that the program could either (a) produce warning about too large density, leading to degeneration of center line, or (b) raise an exception with the same message. Currently, the error initially looks like a bug in shapely, which doesn't help during troubleshooting.

@fitodic
Copy link
Owner

fitodic commented Feb 5, 2018

@mxwell I agree. I believe a RuntimeError with a description would suffice, but the create_centerlines function should simply log it and continue processing the data. Would you like to send a PR?

P.S. The density of the Voronoi grid is inversely proportional to the border density value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants