Я заинтересован в изучении средней ширины многоугольника, который представляет дорожное покрытие. У меня также есть осевая линия дороги как вектор (который иногда не точно в центре). В этом примере линия дороги - красная, а многоугольник - синий:
Один из подходов, основанных на грубой силе, который я придумал, заключается в том, чтобы буферизовать линию небольшими приращениями, пересечь буфер с сеткой рыболовной сети, пересечь полигон дороги с сеткой рыболовной сети, вычислить площадь пересечения для обеих мер пересечения и продолжать делать это до тех пор, пока ошибка маленькая. Это грубый подход, и мне интересно, есть ли более элегантное решение. Кроме того, это скрыло бы ширину большой дороги и небольшой дороги.
Меня интересует решение, использующее программное обеспечение ArcGIS 10, PostGIS 2.0 или QGIS. Я видел этот вопрос и загрузил инструмент Дэна Паттерсона для ArcGIS10, но я не смог рассчитать, что я хочу с ним.
Я только что обнаружил инструмент Minimum Bounding Geometry в ArcGIS 10, который позволяет мне создавать следующие зеленые полигоны:
Это похоже на хорошее решение для дорог, которые следуют за сеткой, но не будут работать иначе, поэтому я все еще заинтересован в любых других предложениях.
Ответы:
Часть проблемы состоит в том, чтобы найти подходящее определение «средней ширины». Некоторые из них являются естественными, но будут отличаться, по крайней мере, немного. Для простоты рассмотрим определения, основанные на свойствах, которые легко вычислить (что, например, исключит те, которые основаны на преобразовании средней оси или последовательностях буферов).
В качестве примера рассмотрим, что архетипическая интуиция многоугольника с определенной «шириной» представляет собой небольшой буфер (скажем, радиуса r с квадратными концами) вокруг длинной, довольно прямой ломаной (скажем, длины L ). Мы думаем о 2r = w как о его ширине. Таким образом:
Его периметр P приблизительно равен 2L + 2w;
Его площадь A приблизительно равна w L.
Ширина w и длина L могут быть восстановлены как корни квадратичного x ^ 2 - (P / 2) x + A; в частности, мы можем оценить
Когда вы уверены, что многоугольник действительно длинный и тощий, в качестве дальнейшего приближения вы можете взять 2L + 2w, чтобы получить 2L, откуда
Относительная ошибка в этом приближении пропорциональна w / L: чем тоньше многоугольник, тем ближе w / L к нулю и тем лучше становится приближение.
Мало того, что этот подход чрезвычайно прост (просто разделите площадь по периметру и умножьте на 2), с любой формулой не имеет значения, как ориентирован многоугольник или где он расположен (потому что такие евклидовы движения не изменяют ни площадь, ни периметр).
Вы можете рассмотреть возможность использования любой из этих формул для оценки средней ширины для любых полигонов, которые представляют сегменты улиц. Ошибка, которую вы делаете в первоначальной оценке w (с помощью квадратичной формулы), возникает из-за того, что область A также содержит крошечные клинья на каждом изгибе исходной полилинии. Если сумма углов изгиба равна t радиан (это полная абсолютная кривизна ломаной), то на самом деле
P = 2L + 2w + 2 Pi tw и
A = L w + Pi tw ^ 2.
Включите их в предыдущее (квадратная формула) решение и упростите. Когда дым рассеивается, вклад от термина кривизны t исчез! То, что первоначально выглядело как приближение, совершенно точно для несамопересекающихся буферов ломаной линии (с квадратами на концах). Поэтому для полигонов переменной ширины это разумное определение средней ширины.
источник
Здесь я показываю небольшую оптимизацию в отношении решения @whuber и говорю о «ширине буфера», потому что это полезно для интеграции решения более общей задачи: есть ли обратная функция st_buffer, которая возвращает оценку ширины?
Для этой проблемы, @celenius вопрос о ширине улицы ,
sw
, решениегде
sw
«средняя ширина»,g1
центральная линияg2
, а улицаg2
- это полигон . Я использовал только стандартную библиотеку OGC, протестировал PostGIS и решил другие серьезные практические приложения с той же функцией buffer_width.ДЕМОНСТРАЦИЯ
A2
это площадьg2
,L1
длина центральной линии (g1
) ofg2
.Предположим , что мы можем генерировать с
g2
помощьюg2=ST_Buffer(g1,w)
, и этоg1
является прямой, такg2
это прямоугольник с длинойL1
и шириной2*w
, иЭто не та же формула @whuber, потому что здесь
w
половинаg2
ширины прямоугольника ( ). Это хорошая оценка, но, как мы видим из тестов (ниже), она не является точной, и функция использует ее как подсказку, чтобы уменьшитьg2
площадь, и как окончательную оценку.Здесь мы не оцениваем буферы с «endcap = square» или «endcap = round», которые нуждаются в сумме с
A2
областью точечного буфера с тем жеw
.СПИСОК ЛИТЕРАТУРЫ: на аналогичном форуме 2005 года В. Хубер объясняет подобные и другие решения.
ИСПЫТАНИЯ И ПРИЧИНЫ
Для прямых результаты, как и ожидалось, являются точными. Но для других геометрий результаты могут быть неутешительными. Основная причина, пожалуй, в том, что вся модель предназначена для точных прямоугольников или для геометрий, которые могут быть аппроксимированы «прямоугольником полосы». Вот «тестовый набор» для проверки пределов этого приближения (см.
wfactor
Результаты выше).ПОЛУЧЕННЫЕ РЕЗУЛЬТАТЫ:
С прямоугольниками (центральная линия - прямая):
С ДРУГИМИ ГЕОМЕТРИЯМИ (сложенная осевая линия):
Об этом
btype
смотрите руководство ST_Buffer , с хорошими иллюстрациями и LINESTRING, используемыми здесь.ВЫВОДЫ :
w_estim
всегда лучше чемw_near
;g2
геометрии, все в порядке, любойwfactor
wfactor=~0.01
на 1% ошибкиw_estim
. До этого фактора используйте другой оценщик.Осторожность и профилактика
Почему возникает ошибка оценки? Когда вы используете
ST_Buffer(g,w)
«модель прямоугольной полосы», вы ожидаете, что новая область, добавленная буфером ширины,w
равнаw*ST_Length(g)
илиw*ST_Perimeter(g)
... Если нет, обычно с помощью наложений (см. Согнутые линии) или «стилизации», это когда оценка среднейw
неисправности . Это главное сообщение тестов.Чтобы обнаружить эту проблему на любом типе буфера , проверьте поведение генерации буфера:
ПОЛУЧЕННЫЕ РЕЗУЛЬТАТЫ:
источник
Если вы можете объединить данные многоугольника с данными центральной линии (пространственными или табличными средствами), просто сложите площади многоугольника для каждого выравнивания центральной линии и разделите на длину центральной линии.
источник
Я разработал формулу для средней ширины многоугольника и поместил ее в функцию Python / ArcPy. Моя формула получена из (но существенно расширяет) самого простого понятия средней ширины, которое я видел в других местах; то есть диаметр круга, имеющего ту же площадь, что и ваш многоугольник. Однако в приведенном выше вопросе и в моем проекте меня больше интересовала ширина самой узкой оси. Кроме того, меня интересовала средняя ширина для потенциально сложных, невыпуклых форм.
Мое решение было:
То есть:
Функция:
Вот экспортированная карта со средней шириной (и некоторыми другими атрибутами геометрии для справки) по множеству фигур с использованием функции сверху:
источник
area / perimeter * 4
.Другое решение с приблизительной медиальной осью:
Результат, безусловно, будет неправильным для тех многоугольников, где приблизительная медиальная ось не является единой непрерывной линией, поэтому вы можете проверить это перед шагом 1 и вернуться
NULL
или что-то еще.Вот пример функции PostgreSQL (примечание: вам нужно установить расширения postgis и postgis_sfcgal ):
Недостаток:
Это решение не будет работать со случаями, когда многоугольник является почти прямоугольным, и человек может интуитивно определить его длину, но приблизительная средняя ось имеет небольшие ветви вблизи края, и, таким образом, алгоритм возвращает None.
Пример:
источник