Конвертировать Multipolygon в Polygon в Python

Можно ли конвертировать Multipolygon в Polygon который заполняет все отверстия или пропускает внутренние области, используя Shapely? Я пытался с тех пор, но я не могу найти это в документации. На следующем рисунке я показываю пример мультиполигона с теми отверстиями, которые я хочу заполнить, и теми квадратами, которые я хочу удалить.

Мультиполигон с отверстиями

2 ответа

Примерный подход может быть следующим:

  1. извлечь внешнюю границу отдельных компонентов MultiPolygon представляет интерес
  2. расширить-сжать каждую из внешних границ, чтобы заполнить "дыры", которые эти границы приблизительно охватывают, например, чтобы обработать "пончик с разрезом"
  3. объединить все геометрии, полученные в предыдущем шаге

Например:

#!/usr/bin/env python
from shapely.geometry import MultiPolygon, Polygon
from shapely.ops import cascaded_union

a = 0.25
delta = 0.49

P = MultiPolygon([
    (
        ((0,0),(0,3),(3,3),(3,2-delta),(2,2-delta),(2,2),(1,2),(1,1),(2,1),(2,1+delta),(3,1+delta),(3,0),(0,0)),
        [((a, a), (1-a,a), (1-a,1-a), (a,1-a), (a,a))]
    )
])


eps = 0.01

omega = cascaded_union([
    Polygon(component.exterior).buffer(eps).buffer(-eps) for component in P
])
for x,y in zip(*omega.exterior.coords.xy):
    print(x, y)

MultiPolygonP похоже:

в то время как приведенный выше скрипт выдает ожидаемый примерный квадрат со стороной длины 3, т.е. он заполняет отверстие в левом нижнем углу, а также "пустое пространство" в центре MultiPolygon который представляется эквивалентным отверстию в процедуре расширения-сжатия с достаточно высоким значением параметра eps,

Если этого достаточно, чтобы заполнить дыры в каком-то Mul tiPolygon mВы могли бы сделать это:

no_holes = MultiPolygon(Polygon(p.exterior) for p in m)

Если вам также необходимо заполнить отверстия, возникающие при прикосновении к полигонам внутри вашего MultiPolygon, должно работать следующее:

# Create a polygon `b` that contains `m`
xmin, ymin, xmax, ymax = m.bounds
b = Polygon([(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)]).buffer(1, resolution=1)

# Take the complement of `m` in `b`, which is a MultiPolygon.
# Pick the outer polygon and take the complement in `b`.
no_holes = b - min(b - m, key=lambda p: p.bounds)
Другие вопросы по тегам