Sometimes, when using parallel_offset
or buffer
, the resulting contour is not closed correctly. The point where the contour is not closed correctly always seems to be the first/last point of the contour.
The following is an issue I initially posted on StackExchange.
Here is a minimal working example that produces a contour which is not closed when using parallel_offset
. When using buffer
, a rounded edge is created (despite the mitred
style).
Curiously, in my larger dataset there are other very similar contours which close successfully.
import matplotlib.pyplot as plt
from shapely.geometry.polygon import LinearRing
def plot_line(ax, ob, color):
x, y = ob.xy
ax.plot(x, y, color=color, alpha=0.7, linewidth=3,
solid_capstyle='round', zorder=2)
polygon = [[-29.675, -30.675],
[-28.4094, -29.4094],
[-28.325, -29.325],
[-28.325, -29.764],
[-28.325, -29.7933],
[-28.4587, -29.8274],
[-28.4676, -29.8297],
[-28.5956, -29.8814],
[-28.6041, -29.8848],
[-28.724, -29.953],
[-28.732, -29.9576],
[-28.8417, -30.0413],
[-28.849, -30.0469],
[-28.9466, -30.1445],
[-28.9531, -30.151],
[-29.0368, -30.2607],
[-29.0424, -30.268],
[-29.1106, -30.3879],
[-29.1152, -30.3959],
[-29.1669, -30.5239],
[-29.1703, -30.5324],
[-29.2044, -30.6661],
[-29.2067, -30.675],
[-29.6457, -30.675],
[-29.675, -30.675]]
poly_line = LinearRing(polygon)
poly_line_offset = poly_line.parallel_offset(0.05, side="left", resolution=16,
join_style=2, mitre_limit=1)
# Alternative:
# poly_line_offset = poly_line.buffer(0.05, resolution=16, join_style=2, mitre_limit=1).exterior
fig = plt.figure()
ax = fig.add_subplot(111)
plot_line(ax, poly_line, "blue")
plot_line(ax, poly_line_offset, "green")
plt.show()
Windows 7, Python 3.6.2
Shapely 1.6.3 (installed from PyPI)
@doctor-ian this is an interesting application and in fact crashes my Python. I think there's a bug in the GEOS library here. Parallel offset isn't designed for closed rings, but ought to fail more gracefully. A negative buffer of a polygon, on the other hand, works:
@sgillies I already feared that the underlying problem is not in shapely. Regarding the buffer: It also fails when the value is exceeding a certain negative value, i.e. when self-intersections occur. Is this also a bug or intended?
A bug, I think.
In the C-API, GEOSOffsetCurve_r is documented to accept only LINESTRINGs. If we want to accept LinearRings too, then that support would need to be added on somehow.
Most helpful comment
@doctor-ian this is an interesting application and in fact crashes my Python. I think there's a bug in the GEOS library here. Parallel offset isn't designed for closed rings, but ought to fail more gracefully. A negative buffer of a polygon, on the other hand, works: