У меня есть набор полигонов, представляющих большие площади, скажем, городские кварталы. Я хочу определить большие перекрывающиеся области между ними.
Но есть проблема: иногда эти многоугольники перекрываются по периметру (потому что они нарисованы с небольшой точностью). Это создаст длинные и узкие перекрытия, которые меня не волнуют.
Но в других случаях будут существенные перекрытия надежных многоугольников, то есть большие области, где многоугольник соседства перекрывает другой. Я хочу выбрать только эти.
Смотри картинку ниже только перекрытий. Представьте, что я хочу выделить только синий многоугольник в левом нижнем углу.
Я мог бы смотреть на области, но иногда узкие были такими длинными, что в итоге они имели такие же большие области, как синий многоугольник. Я пытался сделать соотношение площади / периметра, но это также дало смешанные результаты.
Я даже пытался использовать ST_MinimumClearance
, но иногда к большим областям прикрепляется узкая часть или две очень близкие вершины.
Есть идеи о других подходах?
В конце концов, для меня лучше всего было использовать отрицательный буфер, как предложили @Cyril и @FGreg ниже.
Я использовал что-то вроде:
ST_Area(ST_Buffer(geom, -10)) as neg_buffer_area
В моем случае единицы измерения были метрами, поэтому 10 м отрицательного буфера.
Для узких полигонов эта область вернула ноль (также геометрия была бы пустой). Затем я использовал этот столбец, чтобы отфильтровать узкие полигоны.
Ответы:
Я бы попытался создать отрицательный буфер, если он ест тонкие многоугольники, тогда хорошо, если он не ест многоугольник, то он мой ... :-)
запустите этот скрипт, предварительно установив 2/3 ширины линейных полигонов ...
ОПЕРАЦИОННЫЕ СИСТЕМЫ :-)...
источник
ST_Area(ST_Buffer(geom, -10))
-10 в моем случае -10 метров. Если что-то вернуло 0 из этого выражения, я мог бы отфильтровать его.Вместо площади / периметра лучше использовать площадь, разделенную на квадрат периметра (или его инверсию).
Это также называется «индекс формы». Квадрат периметра, деленный на площадь, имеет минимальное значение 4 * Pi () (в случае диска, который является самой компактной 2D геометрией), поэтому его можно нормализовать с помощью 4 * Pi () для простого интерпретация (нормализованные значения, близкие к 1, означают, что у вас очень компактные объекты, а квадраты имеют значения приблизительно 1,27).
РЕДАКТИРОВАТЬ: порог на области будет полезным для удаления очень маленьких артефактов, которые могут быть компактными. Тогда индекс формы показал бы лучший контраст. РЕДАКТИРОВАТЬ: в дополнение к этому ответу, использование ST_Snap может помочь вам решить проблему до ее возникновения.
источник
(o.overlap_perimeter^2 / o.overlap_area) / (4 * Pi()) as overlap_ratio
? Это имеет худшие результаты для меня, чем просто площадь / периметр.o.overlap_perimeter / (4 * sqrt(o.overlap_area)) as overlap_ratio
соответствии с этой статьей, но все еще худшие результаты (хотя трудно определить, что я имею в виду под худшими) isprs-ann-photogramm-remote-sens-spatial-inf-sci.net/I-7/135/… , стр. 183.Одним из вариантов будет использование отношения площади многоугольника к самой длинной линии, которую можно нарисовать с использованием его конечностей. Выявление длинных узких полигонов.
select * from polygons where ST_Length(ST_LongestLine(geom, geom)) < ST_Area(geom) * 4
Это работает очень хорошо для многоугольников. Вы можете настроить соотношение (с которым вы умножаете площадь) в соответствии с вашими потребностями и проекцией.
источник
Похоже, это может соответствовать вашему варианту использования: устранить выбранные полигоны
Похоже, вы хотели бы попробовать вариант «Крупнейшая общая граница».
источник
Это выглядит как идеальный вариант использования расширения топологии PostGIS . Параметр допуска топологии будет определять, как далеко вы позволите вершинам привязываться к другим существующим полигонам, справляться с низкой точностью исходных данных и очищать их.
Одним словом, стратегия такова:
1. Включите расширение топологии
2. Создайте новую пустую топологию
Третий параметр - это допуск в единицах CRS; выбирай мудро. В идеале, вы хотите CRS, где единица измерения метров. Если единица CRS не является метрами, как в WGS 84 или 4326, используйте
ST_Transform
для перепроектирования ваших полигонов.3. Добавьте столбец TopoGeometry в таблицу полигонов
Это возвращает новый
layer_id
. Сохраните, это понадобится позже. Это будет слой,1
если вы начинаете с нуля, и увеличивается при каждом новом вызове.4. Добавьте все полигоны в топологию.
Это может занять несколько часов для большого набора данных, будьте терпеливы.
1
это layer_id, возвращенный ранее.5. Найдите лица, появляющиеся в нескольких кварталах
Найти все грани из топологии, которые присутствуют в 2 или более топогеометрии. Я оставлю запрос в качестве упражнения. Возможно, проще всего это с помощью
GetTopoGeomElements
функции, затем сгруппировать по идентификатору лица и посмотреть на те из них, которые насчитывают 2 или более. В качестве альтернативы, вы можете создать новую таблицу с очищенной геометрией из столбца topogeom, просто привести ее к стандартной геометрииtopogeom::geometry
и повторить то, что у вас уже есть, но теперь с чистым набором данных без накладок.источник