База
May 21, 2023

Создание слоя: хранение гео данных

В предыдущих статьях я обмолвился, что мы будем хранить данные в БД Postgres. Почему именно он? На самом деле, все просто до безумия - самая распространенная БД, очень сильно себя зарекомендовавшая. Postgres используют многие, поэтому не вижу никаких причин его не использовать.



Чем же мы сегодня будем заниматься?

  1. Вспомним немного теории баз данных
  2. Посмотрим, что нам будет помогать в хранении и обработке гео данных

Немного теории БД

PostgreSQL - это мощная реляционная база данных с открытым исходным кодом бизнес-уровня. Она позволяет использовать реляционные SQL и нереляционные JSON данные и запросы.

Я думаю, все прекрасно знают, что реляционная модель предусматривает единственный способ представления данных – в виде набора двумерных таблиц.

Основные понятия, которыми будем оперировать


Ремарка

Если вы не читали статью про форматы данных, рекомендую сначала вернуться к ней


Из чего состоит таблица? Вы скажите, что все просто - колонки и строки. И да, вы окажитесь правы, но я есть другие понятия - поля (они же атрибуты) и кортежи.


Поля или атрибуты - описание колонок таблицы. Они состоят из описания

  • Типа данных
  • Признака обязательности - может ли быть пустым поле
  • Длинна значения, если тип данных позволяет ограничить
  • Признак главного ключа (primary key)
  • Признак внешнего ключа (foreign key)

Есть еще ряд параметров, но нам хватит и этого 🙃

Ключи какие-то нам тут даешь... Какие двери ими открывать?

Главный ключ (он же primary key) обычно вешается на поле с идентификатором объекта. С его помощью можно однозначно идентифицировать, какой перед нами объект.

Primary key может быть несколько. Такое явление называется составным ключом. На практике именно в ГИС я такого не наблюдал, но, если понадобится, разберемся детально в процессе.

Внешний ключ (foreign key) обычно служит для связи двух таблиц между собой. Обычно в него записывают значение primary key другой таблицы. Таких ключей может быть несколько в рамках одной таблицы.

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

Например. Предположим, мы решили организовать склад хранения колес. Для этого нам необходимо иметь данные об автомобиле и его владельце, а также при приеме колес на хранение нужно учитывать ряд параметров - радиус колеса и тд. В этом случае можно схему БД можно представить следующим образом:

Пример БД

Получается, владелец (owners) может иметь несколько автомобилей. У автомобилей (cars), как мы знаем, по 4 колеса (wheels). Везде получается связь 1 ко многим.


Что же такое кортеж?

Кортежем является строка таблицы, содержащая данные по полям.


Ну и зачем же ты нам это рассказываешь?
Следите за ходом мысли!

Немного вернемся к самой первой статье и вспомним, что такое объект с точки зрения картографии.

Объект - сущность, содержащая в себе геометрию и ее атрибутивный состав. Объект без геометрии существовать не может.

Из этого определения мы можем сделать вывод, что:

  1. Для того, чтобы у нас был именно картографический объект, необходимо иметь поле типа Geometry
  2. Атрибутивный состав объекта - набор полей таблицы

Что же получается?

А получается интересная штука.

Слой получается путем создания таблицы, одним из полей которой является геометрия. С точки зрения GeoJSON, таблицу можно представлять в виде FeatureCollection, каждый кортеж которой - Feature, а поля таблицы попадают в properties.

Иными словами, в 90% случаев одна таблица в БД соответствует одному слою.

Бывают исключения. Например, мы хотим, чтобы на один объект приходилось несколько геометрий, каждая из которых могла быть стилизована по-своему.
В таком случае разумно будет создать две таблицы и связать их между собой в отношении 1 ко многим, либо использовать GeometryCollection и JSON поле с массивом атрибутов для геометрий.
Если мы будем делать несколько таблиц, то нам придется их все равно соединить в одну таблицу (создать представление (view) данных), где будет дублирование информации. Можно обойтись без представления, поскольку Geoserver'у можно скормить SQL, в котором прописать связь. На мой взгляд, это не самый удачный вариант, потому что можно забыть об этом SQL, изменить таблицу в бд, а потом сидеть и гадать, почему же у меня слой перестал выводится или что-то не отображается.


Как хранить гео данные в Postgres?

Вы можете задаться вопросом, а как же хранить гео данные, если Postgres по-умолчанию не умеет?

Вы всегда можете воспользоваться вариантом JSON полей, куда прописывать GeoJSON, но это не наш случай. В нашем варианте мы будем рассматривать расширение PostGIS.

PostGIS — программное расширение с открытым исходным кодом, расширяющее пространственную базу данных системы управления PostgreSQL. Расширение добавляет поддержку географических объектов, благодаря чему появляется возможность выполнять запросы местоположения в SQL.PostGIS позволяет хранить ряд географических и пространственных данных — точек, ломаных линий, полигонов, растр, а также использовать их для разных операций, например, поиска.

PostGIS в PostgreSQL используется для снятия ограничений, расширения функций и позволяет применять:

  • растровые данные;
  • функции создания геометрий и управления ими (создание и удаление полей с географическими данными, запросы скриптов, библиотек);
  • функции редактирования геометрий и их форматированного вывода;
  • расширенные 2D- и 3D-функции, в том числе для определения пересечений в 3D-пространстве);
  • инструменты для определения пространственных отношений и измерений (например, для сравнения расстояния по плоскости и на сфере);
  • функции создания и отображения растров в удобном формате (например, в JPEG или PNG);
  • инструменты обработки растров (очищение рельефа, векторизация, увеличение или уменьшение яркости).

Возможности связки PostGIS и PostgreSQL на практике могут использоваться для определения:

  • расстояния от точки до точки;
  • ближайшей точки между извилистыми улицами на местности;
  • улицы или даже дома по определенным координатам;
  • количества домов, попадающих в заданную область пространства;
  • количества объектов, находящихся поблизости с заданной точкой;
  • площади, расстояний, длин, периметров заданных объектов и множества других данных.

Например, PostgreSQL с предустановленным расширением PostGIS может использоваться для:

  • вычисления площади города, региона, государства;
  • поиска ближайшей кофейни или магазина;
  • построения карты (в том числе растровой) с отображением заданных объектов;
  • поиска объектов или местностей, отвечающих заданным критериям (самый крупный город, самая южная страна, самая высокая точка).

Именно благодаря нему у нас и появляется возможность создавать поля с типом Geometry.

Все возможности PostGIS описывать не буду, иначе это будет долго и очень много. Будем разбирать на практике, быстрее поймете 🙃


Поскольку нам предстоит изучение довольно большого объема информации, я решил поделить эту статью на несколько частей.

В следующей части мы коротко пробежимся о том, что такое контейнеризация и docker, а также запустим Postgres с установленным PostGIS.