Мануал: Построение конвексного полигона средствами PostGIS

Ответить
lenny314156
Интересующийся
Сообщения: 35
Зарегистрирован: 27 июл 2013, 21:47
Репутация: 6

Мануал: Построение конвексного полигона средствами PostGIS

Сообщение lenny314156 » 30 май 2016, 15:19

На данном сайте есть статья про ArcView и автоматизацию построения конвексных полигонов. У меня в свое время возникла схожая задача делать то же самое, но средствами PostGis.

В статье есть такая замечательная картинка:
Изображение

Исходные данные:

Предположим, что мы хотим нарисовать границу вокруг всех домов, находящихся на одной улице. У нас есть таблица houses, в которой есть поля
city - город;
street_name - название улицы;
house_number - номер дома;
geom - геометрия (координаты объекта);
Пример условный, поэтому не будем вдаваться в детали. Соответственно, каждый объект в таблице - это дом, привязанный к некоей улице, находящейся в некоем городе. Соответственно, для каждого дома улица, на которой он расположен, может быть уникальным признаком, по которому мы и будем группировать дома.

Задача:

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

Решение

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

1 этап.
Стандартным select'ом выберем из базы все дома, расположенные на Солнечной улице:

Код: Выделить всё

select geom from houses where street_name = 'Солнечная';
2 этап.
полученную выборку надо преобразовать в объект GEOMETRYCOLLECTION с помощью функции

Код: Выделить всё

ST_Collect(geom)
3 этап.
Теперь вокруг полученного объекта GEOMETRYCOLLECTION можно построить конвексный полигон с помощью функции

Код: Выделить всё

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

Сделать такую буферную зону нам поможет еще одна функция postgis, а именно

Код: Выделить всё

ST_Buffer(geom, float radius)
С ее помощью можно указать радиус буферной зоны (для точки это будет окружность), а потом, уже с учетом этой буферной зоны, можно строить полигон вокруг точек. Кстати, эту буферную зону можно добавить как для каждой точки, так и на последнем этапе - для полигона. Смотря какие цели.

В итоге, объединив все функции в один запрос, получим такую конструкцию:

Код: Выделить всё

select st_buffer(st_convexHull(st_collect(geom)), 0.0004) from houses where street_name = 'Солнечная';
В моем случае буфера в 0.0004 оказалось более, чем достаточно.

Ответить

Вернуться в «PostGIS/PostgreSQL»