Мануал: Построение конвексного полигона средствами PostGIS
Добавлено: 30 май 2016, 15:19
На данном сайте есть статья про ArcView и автоматизацию построения конвексных полигонов. У меня в свое время возникла схожая задача делать то же самое, но средствами PostGis.
В статье есть такая замечательная картинка:

Исходные данные:
Предположим, что мы хотим нарисовать границу вокруг всех домов, находящихся на одной улице. У нас есть таблица houses, в которой есть поля
city - город;
street_name - название улицы;
house_number - номер дома;
geom - геометрия (координаты объекта);
Пример условный, поэтому не будем вдаваться в детали. Соответственно, каждый объект в таблице - это дом, привязанный к некоей улице, находящейся в некоем городе. Соответственно, для каждого дома улица, на которой он расположен, может быть уникальным признаком, по которому мы и будем группировать дома.
Задача:
На основании уникального признака нарисовать визуальную границу вокруг каждого набора точек с этим признаком (т.е. вокруг всех домов, находящихся на одной улице, должна быть своя граница)
Решение
Рассмотрим поэтапно на примере одной улицы, пусть она называется "Солнечная". Поскольку нам пока важна только геометрия, будем выбирать именно ее.
1 этап.
Стандартным select'ом выберем из базы все дома, расположенные на Солнечной улице:
2 этап.
полученную выборку надо преобразовать в объект GEOMETRYCOLLECTION с помощью функции
3 этап.
Теперь вокруг полученного объекта GEOMETRYCOLLECTION можно построить конвексный полигон с помощью функции
На картинке выше видно, что просто конвексный полигон может быть неудобен - желательно иметь некую буферную зону вокруг точек, по которым мы строим полигон (то, что на картинке называется "ошибка локации").
Сделать такую буферную зону нам поможет еще одна функция postgis, а именно
С ее помощью можно указать радиус буферной зоны (для точки это будет окружность), а потом, уже с учетом этой буферной зоны, можно строить полигон вокруг точек. Кстати, эту буферную зону можно добавить как для каждой точки, так и на последнем этапе - для полигона. Смотря какие цели.
В итоге, объединив все функции в один запрос, получим такую конструкцию:
В моем случае буфера в 0.0004 оказалось более, чем достаточно.
В статье есть такая замечательная картинка:

Исходные данные:
Предположим, что мы хотим нарисовать границу вокруг всех домов, находящихся на одной улице. У нас есть таблица houses, в которой есть поля
city - город;
street_name - название улицы;
house_number - номер дома;
geom - геометрия (координаты объекта);
Пример условный, поэтому не будем вдаваться в детали. Соответственно, каждый объект в таблице - это дом, привязанный к некоей улице, находящейся в некоем городе. Соответственно, для каждого дома улица, на которой он расположен, может быть уникальным признаком, по которому мы и будем группировать дома.
Задача:
На основании уникального признака нарисовать визуальную границу вокруг каждого набора точек с этим признаком (т.е. вокруг всех домов, находящихся на одной улице, должна быть своя граница)
Решение
Рассмотрим поэтапно на примере одной улицы, пусть она называется "Солнечная". Поскольку нам пока важна только геометрия, будем выбирать именно ее.
1 этап.
Стандартным select'ом выберем из базы все дома, расположенные на Солнечной улице:
Код: Выделить всё
select geom from houses where street_name = 'Солнечная';
полученную выборку надо преобразовать в объект GEOMETRYCOLLECTION с помощью функции
Код: Выделить всё
ST_Collect(geom)
Теперь вокруг полученного объекта 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 = 'Солнечная';