Подтвердить что ты не робот

Найти координату ближайшей точки на полигоне Shapely

Скажем, у меня есть следующий Polygon и Point:

>>> poly = Polygon([(0, 0), (2,8), (14, 10), (6,1)])
>>> point=Point(12,4)

введите описание изображения здесь

Я могу рассчитать расстояние точки до многоугольника...

>>> dist=point.distance(poly)
>>> print dist
2.49136439561

... но я хотел бы знать координату точки на границе полигона, где это кратчайшее расстояние измеряется.

Мой первоначальный подход заключается в том, чтобы буферизовать точку на расстоянии до полигона и найти точку, в которой эта окружность касается многоугольника:

>>> buff=point.buffer(dist) 

введите описание изображения здесь Однако я не уверен, как вычислить эту точку. Два многоугольника не пересекаются, поэтому list(poly.intersection(buff)) не даст мне эту точку.

Я на правильном пути с этим? Есть ли более простой метод?

4b9b3361

Ответ 1

Существует простой способ сделать это ретрансляцию на стройных функциях. Во-первых, вам нужно получить внешнее кольцо многоугольника и спроектировать укажите на кольцо. Обязательно получить внешний вид как LinearRing, поскольку полигоны не имеют функции проекции. В отличие от интуиции, это дает расстояние, расстояние от первой точки кольца до точки в кольце, ближайшем к данный момент. Затем вы просто используете это расстояние, чтобы понять интерполяционная функция. См. Код ниже.

from shapely.geometry import Polygon, Point, LinearRing

poly = Polygon([(0, 0), (2,8), (14, 10), (6,1)])
point = Point(12,4)

pol_ext = LinearRing(poly.exterior.coords)
d = pol_ext.project(point)
p = pol_ext.interpolate(d)
closest_point_coords = list(p.coords)[0]

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

Если многоугольник не имеет внутренних колец, код будет работать даже для точек внутри многоугольника. Это потому, что мы на самом деле работаем с внешним кольцом в виде строки и игнорируем, является ли строка строки из многоугольника или нет.

Проще всего распространить этот код на общий случай вычисления расстояния любой точки (внутри или вне многоугольника) до ближайшей точки на границе многоугольника. Вам нужно всего лишь вычислить ближайшую точку (и расстояние) от точки до всех линейных колец: внешнее кольцо и каждое внутреннее кольцо многоугольника. Затем вы просто сохраняете минимум.

введите описание изображения здесь

Ответ 2

Рассматриваются два случая: (1) ближайшая точка лежит на ребре, а (2) ближайшая точка является вершиной. Случай (2) легко проверить - просто возьмите расстояние до каждой вершины и найдите минимум. Случай (1) включает в себя немного больше математики, но все же не так уж плохо. Вам нужно сделать две вещи для случая (1): (a) найти, где нормаль от точки до края пересекает край, и (b) проверить, что она лежит внутри отрезка (в отличие от прохода мимо одного из заканчивается). Если это не на сегменте линии, игнорируйте его (одна из вершин будет ближайшей точкой на этом ребре).