Генерация полигонов из набора пересекающихся линий

10

Это простой и довольно распространенный вопрос, который уже задавался для разных целей (см. , Например, эту ссылку и это тоже ), но здесь мы ищем не программный пакет, а алгоритмы, которые мы могли бы попытаться реализовать, скажем, в Python .

Итак, как показано ниже, набор линий отображается (они уже обрезаны, кстати).
Алгоритмы / идеи для генерации полигонов (как показано красным) ?

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

разработчик
источник
Известна ли граница Внешнего квадрата или она тоже должна быть прочитана из входных строк?
Девдатта Тенгше

Ответы:

5

Ну, мы поместили здесь ответ, который не является полным ответом на наш вопрос, то есть вопрос останется « открытым для ответа ». Это, однако, решение проблемы в вопросе. Вот трюк, который мы использовали:

Сначала давайте посмотрим результаты :
введите описание изображения здесь

Таким образом, данные линии в leftпостроенных полигонах показаны в middle. Они настоящие многоугольники, как показано в right;)

Для приведенного ниже алгоритма мы использовали Shapelyпакет в Python .

  • линии ==> MultiLineString {:: M}
  • добавить крошечный buffer, скажем, eps{:: MB}
  • регион ==> Polygon {:: P} (регион здесь квадрат)
  • P.difference(MB) {получившиеся полигоны}

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

разработчик
источник
4

JTS Topology Suite имеет класс Polygonizer, который в значительной степени делает это.

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

Девдатта Тенгше
источник
Как сказано в описании кода, он не будет работать так, как ожидал автор вопроса: «ребра должны быть правильно обозначены узлами; то есть они должны встречаться только в своих конечных точках. Полигонизатор будет работать на вводе с неверным узлом, но не будет формировать многоугольники из не ребра "
Пабло
1
В JTS есть операция для правильного разбиения линий в вершинах. Может быть, ОП мог бы посмотреть и на это.
Девдатта Тенгше
3

Вы можете взглянуть на пакет Python Shapely, в частности, polygonize ()

Дейв
источник
Заметим, что полигонизация в Shapely ( from shapely.ops import polygonize) использует GEOS.Polygonize из GEOS . Так что это ссылка, где есть ссылка на ссылку ...: |
Разработчик
Наши испытания polygonizeне увенчались успехом. Однако спасибо, что напомнили нам, Shapelyс помощью которого мы могли бы найти решение (трюк, на самом деле) в виде ответа.
Разработчик
2

Вот еще одно решение, которое мы могли бы найти.

Используя DCELмы можем сделать блоки из соприкасающихся линий.

Для Python есть пакет {здесь} . Это крошечная реализация с некоторыми ошибками. Тем не менее, с некоторыми усилиями он может быть использован для этой проблемы. Также обратите внимание на следующие этапы:

Этап предварительной обработки, с помощью которого обнаруживаются все пересечения между линиями. Тогда соответственно все линии разбиваются на отрезки в точках взаимодействия. Список точек пересечения и список связанных ребер необходимы для DCEL.

разработчик
источник
Поскольку этот метод является оригинальным решением и дает гораздо лучшую производительность по сравнению с другим методом, в котором используется differenceоперация.
Разработчик