1

I am trying to implement a polygon smoothing operation with shapely. I am doing this with the combination of erode and dilate (polygon.buffer function with positive and negative numbers). The specification of my smooth function goes something like this:

  1. The operation must be conservative. There must not be any part of the original shape that is not covered by the smoothed shape
  2. any protrusion must be preserved
  3. any concavity must be smoothed out
  4. Topology must be preserved

dilate followed by erode solves this with shapely in cases where the topology does not change with the operation. See example code below.

from shapely.geometry import Polygon
import numpy as np
from descartes import PolygonPatch
from matplotlib import pyplot as plt

# create a large square
x = np.array([-5,-5,5,5])
y = np.array([5,-5,-5,5])
poly1 = Polygon(zip(x,y))

# smaller square to cut away from first
x = np.array([-4,-4,4,4])
y = np.array([4,-4,-4,4])
poly2 = Polygon(zip(x,y))

# small shape to cut away from left side
x = np.array([-11,-11,0,0])
y = np.array([1,-1,0,0])
poly3 = Polygon(zip(x,y))

poly_t=poly1.difference(poly2)
poly4 = poly_t.difference(poly3)

poly5= poly4.buffer(0.45)
poly5= poly5.buffer(-0.45)

fig = plt.figure()

ax = fig.add_subplot(121)
plt.axis([-5.5, 5.5, -5.5, 5.5])

patch = PolygonPatch(poly5)
ax.add_patch(patch)

plt.show()

Visualized below is the before and after smoothing operation applied. the change of topology of the dilate operation is the cause of the unintended behaviour. Shapely polygons can be in a state where they are self intersecting, where they are "invalid" in some sence. I would like this to be the case for the intermediate polygon (the one where dilate has been applied, awaiting the erode). However, it seems the buffer function in shapely has no such feature.

Do you have a suggestion on how to solve this problem with Shapely still being the geometry engine? worst case, a solution with another framework.

before and after

Stefan Karlsson
  • 1,092
  • 9
  • 21

1 Answers1

1

GEOS recently added the GEOSPolygonHullSimplify function. It can compute both outer and inner hulls of polygons (and MultiPolygons).

Outer hull of a polygon with a hole

For more information see the following blog posts:

http://lin-ear-th-inking.blogspot.com/2022/04/outer-and-inner-concave-polygon-hulls.html http://lin-ear-th-inking.blogspot.com/2022/05/using-outer-hulls-for-smoothing.html

It sounds like it meets your requirements:

  • the result (of an outer hull) covers the input
  • an outer hull preserves protrusions and smooths out concavities
  • topology is preserved (i.e. the number of holes remains identical)

If this is not in Shapely now, it should be easy to add.

dr_jts
  • 211
  • 1
  • 5
  • thanks @dr_jts. I deeply appreciate and enjoy the work you are doing with the GEOS code-base. Will continue this discussion on that forum: https://github.com/shapely/shapely/discussions/1739 – Stefan Karlsson Feb 03 '23 at 07:10