Обнаружение разветвленной формы многоугольника?

13

У меня есть векторный слой с миллионами полигонов, создающих непрерывное покрытие. Мне нужно классифицировать их в соответствии с их формой. Я уже использую несколько индексов формы из ландшафтной экологии, таких как компактность ( 4piA / P ^ 2 ), средняя ширина ( 2A / P ), номер формы ( P / sqrt (A) ), я также видел этот ответ на Расчет округлости / компактности многоугольник?

Моя проблема в том, что все эти метрики используют только некоторое соотношение площади и периметра. Даже индекс фрактального измерения использует только площадь и периметр ( 2ln (0.25P) / ln (A) ). Но как я могу различить два полигона с одинаковой площадью и периметром, но абсолютно разной формы? Как этот разветвленный многоугольник A:

разветвленный полигон против изогнутой полосы

которую я попытался нарисовать с той же площадью и периметром, что и изогнутая полоса B. Все мои известные индексы для них будут одинаковыми. Но для меня очень важно отличать простые полосы (в том числе изогнутые, как новолуние) от сложных разветвленных фигур.

Я намеренно показываю многоугольник B как изогнутую полосу, а не как прямую полосу, потому что мне известен индекс относительной окружности, который обнаруживает прямые вытянутые формы, но у моих многоугольников могут быть такие же окружности. Даже если я построю выпуклую оболочку и вычислю соотношение площадей Apolygon / Aconvex , здесь это может быть очень похоже.

Итак, как я могу четко отличить разветвленный многоугольник A от многоугольника B в векторных данных ? (Преобразование их в растр потребовало бы чрезвычайно малого размера ячеек, огромного набора данных и недостатка памяти, поэтому это невозможно). Существуют ли другие индексы формы, которые включают другие параметры? В идеале метод должен различать не только четко разветвленные многоугольники, но даже C и D:

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

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

Я приветствую математические решения / алгоритмы, которые я позже реализовал в Python.

надя
источник
1
Вам не нужно много Python. Пытаться ! форма !. выпуклая оболочка (). симметричная разница (! shape!) в полевом калькуляторе. Попробуйте сначала на небольшой копии подмножества. См. Справку arcpy geometry для правильного синтаксиса.
FelixIP
Это может быть отличным вопросом, но в данный момент вы задаете несколько вопросов, не связывая, спрашиваете ли вы о QGIS или ArcGIS Desktop, а затем также добавляете в Python. После того, как вы точно укажете, что вы пытались, потенциальным ответчикам будет легче помочь вам понять, где вы застряли. Я предлагаю сосредоточить внимание на QGIS, чтобы избежать появления вашего первого ответа.
PolyGeo
1
У меня есть данные в базе геоданных Esri, потому что размер шейп-файла уже превышал 2 ГБ. Я мог бы что-то сделать с этим, если есть рабочее решение в QGIS или где-то еще. Но я не спрашиваю внутри конкретного программного обеспечения. Я спрашиваю о метрике, методе математического определения формы со сложной границей (разветвленной). 1 вопрос Научная статья с формулой тоже подойдет, я подумаю, как это реализовать самостоятельно.
Надя
1
Моя первая мысль была такой же, как и у вас, когда я смотрел на различия между числом и размером полигонов, оставшихся после вычитания оригинала из его выпуклой (или вогнутой) оболочки (см. Также альфа-формы).
user2856
1
Если бы только скелет был достаточно быстрым для вычисления, я бы использовал для вычисления 4A / PL, площадь, периметр, длину между фермерными узлами скелета для компактности. То же относится и к самому большому вписанному кругу.
FelixIP

Ответы:

11

Вы могли бы взглянуть на следующий метод: скелетировать ваши полигоны и лучше поработать над объектами типа линии, связанными с вашим исходным полигоном, с уникальным исходным идентификатором полигона. Я предполагаю, что есть некоторые догадки (например, когда рассматривать ломаную линию как реальную осевую линию: минимальная длина, чтобы полилиния имела право на статус центральной линии). Когда число осевой линии больше 1 для одного исходного многоугольника, тогда оно разветвляется.

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

Пример :

  • когда вы рисуете букву Y, вы используете по крайней мере 2 непрерывных мазка (= 2 полилинии), поэтому он разветвлен, потому что минимальное количество штрихов> 1.
  • когда вы рисуете букву L, вы используете как минимум 1 непрерывный ход. Это не разветвленная.

Еще примеры этой логики:

  • Когда вы рисуете A: 2 штриха = это разветвленная
  • Когда ты пишешь Б: 3 удара = это разветвленный
  • когда вы рисуете C: 1 ход = это не разветвленная
  • и т.д

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

Смотрите: Скелетонизируйте векторы в QGIS / Python или http://postgis.net/docs/ST_StraightSkeleton.html.

Или

пример

Источник: извлечение осевой линии сложного многоугольника в PostGIS / Python

РЕДАКТИРОВАТЬ: Для случаев C & D, вам уже нужно иметь отфильтрованные формы B (неразветвленные).

  • Убедитесь, что уникальный идентификатор связывает центральную линию и исходный многоугольник.
  • Превратите свои полигоны в полилинии
  • Уплотните центральную полилинию и пограничную полилинию с помощью правильных точек (не слишком много, чтобы избежать проблем с памятью позже, но достаточно, чтобы «поймать» неправильные биты.
  • Создать матрицу расстояний между точками центральной линии и точками границы
  • Храните в матрице только те строки, где ID_centerline = ID_borderline
  • Создать статистику для значения стандартного отклонения
  • Установите привязанное значение, чтобы указать для высоких значений SD, что это нерегулярный контур, и создайте требуемый индикатор для каждого уникального идентификатора.
  • Верните индикатор в исходный многоугольник, соединив поле на основе уникального идентификатора.
gisnside
источник
Спасибо за идею, я постараюсь создать
осевые
Просто проблема разграничения моих полигонов C и D останется
Надя
Вам могут понадобиться разные методы для разных случаев и разделить работу. Если у вас есть неразветвленные полигоны (B), вы можете уточнить B, чтобы попытаться найти C и D. Проблема в том, что я не вижу, какую логику вы используете, чтобы отличить C от D. Возможно, вам придется четко сформулировать это с помощью Критерии.
Гиснсайд
1
Разница между C и D, по-видимому, заключается в том, что в C стороны многоугольника находятся примерно на одинаковом расстоянии от центральной линии, в то время как в D стороны имеют неодинаковое расстояние от центральной линии.
csk
1
@csk Я вижу это. Я предполагаю, что преобразование этого в код будет вычислять статистику по расстоянию между осевой линией и границей. Уплотняя ломаную линию границы с большим количеством точек, затем преобразуя эту границу в точки + расстояние от эквивалентной работы по центральной линии даст статистику по этому поведению. Если стандартное отклонение велико, то, вероятно, форма будет неправильной. Трудно понять, как это сделать на тысячах полигонов, хотя ... хороший вызов там
gisnside