Shapely .contains () метод, но включая границы? - PullRequest
0 голосов
/ 06 июля 2019

Я работаю с полигонами Shapely, и мне нужен способ удалить все меньшие полигоны в пределах большего полигона.Я попытался использовать метод .contains(), который предоставляет Shapely, но метод не возвращает True, если меньший многоугольник не полностью находится внутри большего многоугольника.

В принципе, я хочу такой метод, как .contains()но он возвращает True, если многоугольник находится на границе внешнего многоугольника, как на картинке

here.

Вот многоугольники с картинки, представленной в формате wkt:

Зеленый:

POLYGON Z ((14.4265764858233823 45.3396418051734784 0.0000000000000000, 14.4267228266679606 45.3395430970275015 0.0000000000000000, 14.4266753563381904 45.3394727193694536 0.0000000000000000, 14.4265290154936121 45.3395714275154376 0.0000000000000000, 14.4265764858233823 45.3396418051734784 0.0000000000000000))`  

Красный:

POLYGON Z ((14.4265450394689161 45.3395951840357725 0.0000000000000000, 14.4265695507109317 45.3395786509942837 0.0000000000000000, 14.4265802185605700 45.3395944667317679 0.0000000000000000, 14.4265982245953417 45.3395823215079616 0.0000000000000000, 14.4265715327703994 45.3395427492501426 0.0000000000000000, 14.4265290154936121 45.3395714275154376 0.0000000000000000, 14.4265450394689161 45.3395951840357725 0.0000000000000000))

Я также пытался использовать метод .intersects(), но он возвращает True для полигонов снаружиданного многоугольника, у которого есть некоторые общие границы, которые я не хочу.

Я надеюсь, вы понимаете, что мне нужно, и я благодарен, если кто-то знает решение этой проблемы.

1 Ответ

1 голос
/ 06 июля 2019

Обычно метод contains должен работать при тестировании, если один многоугольник находится внутри другого и имеет общие границы.Например, если вы возьмете следующий простой пример, он будет работать так, как ожидалось:

from shapely.geometry import Polygon

a = Polygon([(0, 0), (2, 0), (2, 2), (0, 2)])
b = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])
a.contains(b)
# True

enter image description here

Но довольно часто случается, что из-заиз-за погрешностей точности внутренний многоугольник выходит наружу, и тест не проходит.

Здесь, например, я нарисовал ваши полигоны и увеличил масштаб в левой верхней точке пересечения:

import matplotlib.pyplot as plt

plt.plot(*green.exterior.xy, c='g')
plt.plot(*red.exterior.xy, c='r')

Вы можете видеть, что линии не лежат друг на друге идеально:

enter image description here

Существует несколько способов решения этой проблемы.Первый, например, был предложен в Как бороться с ошибками округления в Shapely и в некоторых Shapely в GitHub :

  1. Уменьшите меньший многоугольник или немного увеличьте его:

    big.contains(small.buffer(-1e-14))
    # True
    big.buffer(1e-14).contains(small)
    # True
    
  2. Убедитесь, что область меньшего многоугольника, которая находится за пределами большего, близка к нулю:

    small.difference(big).area < 1e-14
    # True
    
  3. Проверьте, близки ли расстояния каждой вершины меньшего многоугольника к большему многоугольнику:

    from shapely.geometry import Point
    
    vertices = map(Point, small.exterior.coords)
    distances = map(big.distance, vertices)
    all(distance < 1e-14 for distance in distances) 
    # True
    

Возможно, есть и другие способычтобы выполнить тест, но я думаю, что этого будет достаточно.

...