Создание слоя: загрузка данных
В прошлом уроке мы с вами поднимали данных Postgres в контейнере. Если вы забыли или пропустили, рекомендую вернуться и освежить знания.
Мы с вами уже знаем, что для создания слоя необходимо иметь геометрию.
Но у нас же ничего нет... Где нам ее взять??
И на такой вопрос есть решение. Мы с вами рассмотрим самую популярную задачу - загрузку OpenStreetMap (OSM) в свою базу с дальнейшим выводом на карту.
Что нам потребуется?
Подготовка базы данных
Первое, что нам необходимо сделать - создать отдельную базу данных с отдельным пользователем, чтобы отделить OSM от всех остальных данных.
На прошлом занятии мы уже подключились к базе данных с помощью pgAdmin. С этого места и продолжим наш путь джедая котика.
- Открываем наш сервер и кликаем ПКМ по Login/Group roles => Create => Login/Group Role... (рис 1.)
- Указываем имя нашего пользователя. У меня это будет osm (Рис 2.)
- На вкладке Definition указываем пароль и не забываем его запомнить/записать (Рис 3.)
- На вкладке Privileges ставим ползунок напротив Can login (Рис 4.)
Теперь пришло время создавать наше хранилище данных.
- Кликаем ПКМ по Databases (Рис 5.)
- Указываем основные параметры (Рис 6.)
- Для работы с геометрией обязательно необходимо поставить расширение postgis
Котик, база готова. Что же дальше?
А дальше мы будем заливать данные!
Первое, что нам потребуется - скрипты для загрузки и файл. Я уже подготовил загрузчик. Сегодня мы посмотрим, как же его использовать.
Загрузчик сделан на базе утилиты osm2pgsql. Что же это за штука такая чудесная? Osm2pgsql позволяет без особых усилий и больших страданий загружать данные OSM в базу postgres.
Нам необходимо склонировать репозиторий в любую удобную папку.
Далее необходимо собрать docker образ, в котором установлен osm2pgsql. Для этого необходимо выполнить команду и дождаться окончания.
cd ./osm2pgsql && docker build -t osm2pgsql:latest .
Теперь нам необходимо скачать файл с данными. Переходим на сайт и качаем russia-latest.osm.pbf.
Этот файл необходимо положить по пути: repository_path/data/files,
где repository_path - папка, куда был склонирован репозиторий
Открываем файл osm2pgsql/osm2pgsql.sh в любом удобном редакторе и меняем следующие переменные
PG_DATABASE - название базы данных
PG_USER - пользователь, которого мы создавали
PG_HOST - ip адрес postgres. У меня указан host.docker.internal, поскольку один контейнер будет подключаться к другому и все это происходит локально. Если у вас БД где-то на сервере, необходимо подставить свой ip
PG_PORT - порт, на котором запущен postgres
После того, как все нужные операции были проделаны, остается самое интересное - запустить.
Из папки с репозиторием выполняем следующую команду
sh osm2pgsql/osm2pgsql.sh
Терминал запросит пароль. Необходимо ввести пароль от пользователя, которого создавали.
Внимание! При вводе пароля символы видно не будет. Учтите это.
Если все сделано верно, то вы должны увидеть следующую картину:
На этом моменте вы можете пойти гулять, играть, пить чай. В общем, все, что душе угодно.
По окончанию работы скрипта у нас должна быть следующая картина
На этом моменте работа со скриптом будет закончена и можно вернуться в базу данных.
Открываем нашу БД и смотрим на таблички. Должно быть 9 таблиц. Если у вас не видно таблиц, то можно нажать на схему public ПКМ и выбрать пункт Refresh.
Давайте заглянем в какую-нибудь табличку, например, planet_osm_roads.
Выбираем ее ЛКМ и кликаем на кнопку с иконкой таблицы вверху.
Перед нами открылось что-то странное и непонятное, похожее на Excel. Без паники!
Сейчас нас интересует одна единственная колонка.
Если мы пролистаем вправо до самого конца, то обнаружим колонку way и что-то непонятное в данных. Это и есть наша геометрия! Ураааа!
Мы можем выделить колонку и посмотреть геометрию на карте прям из pgAdmin. Для этого нажимаем на заголовок, чтобы выделить все строки, а затем в заголовке жмем на кнопку с иконкой карты.
Но, подождите, а почему все белое???
Сейчас я покажу немного магии postgis.
Чтобы добавить подложку на эту карту, проекция у геометрии должна быть EPSG:4326 и никакая другая. Давайте это проверять.
SELECT way, ST_SRID(way), ST_ASGeoJSON(way)::jsonb FROM public.planet_osm_roads LIMIT 10
Немного поясню, что сейчас произошло.
На первых уроках я показывал и рассказывал про GeoJSON. В postgis есть функции для работы с данным форматом. Одну из таких мы сейчас и использовали - ST_ASGeoJSON.
Данная функция позволяет показать геометрию в формате GeoJSON.
Тут нам уже наглядно видно две вещи:
- Если смотреть параметр crs, то видно проекцию EPSG:3857
- Более опытный человек может взглядом на координаты понять, что за проекция (это нарабатывается только насмотренностью)
Если мы не хотим смотреть на координаты, то проекцию можно посмотреть, использовав данную функцию.
Итак, мы убедились, что наша проекция не соответствует требованию о наличии EPSG:4326.
Предлагаю не модифицировать данные, а создать на основе них представления (views, вьюхи), в которых как раз перепроецируем геометрию.
View представляет собой таблицу с данными, построенными на основе других данных. То есть мы можем выполнить запрос, собрать данные, а в случае изменения исходной таблицы, View автоматически пересчитается.
Переходим к созданию вьюхи. Выбираем ПКМ Views => Create => View...
Указываем имя. У меня это v_planet_osm_roads.
Указываем владельца - созданный нами пользователь.
Переходим на вкладку Code. Здесь нам нужно вставить запрос, которым будет формироваться view.
SELECT ST_Transform(way, 4326) as geometry FROM public.planet_osm_roads
ST_Transform позволяет трансформировать геометрию из одной проекции в другую. В данном случае мы трансформируем геометрию из поля way с проекцией 3857 в 4326.
Важно учитывать, что для ST_Transform необходима установленная у изначальной геометрии проекция. Бывают моменты, когда у геометрии нет четко проставленной проекции. В таком случае трансформация будет ругаться.
Чтобы решить такой вопрос, может потребоваться выполнение двух функций одновременно. Вторая функция ST_SetSRID(geometry, proj). Она позволяет указать, в какой проекции находится геометрия.
Выполняя ST_Transform(ST_SetSRID(geometry, proj1), proj2) получаем нужный результат.
Теперь давайте посмотрим, что получилось. View смотреть можно точно так же, как и обычную таблицу.
Мы видим таблицу, состоящую из одной колонки.
Попробуем посмотреть геометрию.
А теперь немного волшебства
Все это круто - таблички, геометрии, какие-то поля, но пока это мало чего нам дает.
Мы с вами знаем, что для описания объекта нам необходим тип Feature, properties и геометрия. Геометрия у нас есть, тип тоже, а где properties?
SELECT way, name, population, boundary FROM public.planet_osm_roads
то увидим табличку из 4 полей, где way - геометрия, а остальные - набор данных. Так вот, наш набор данных - это и есть properties. То есть мы можем представить представить объект в виде
Поле way переехало в geometry, остальные поля уехали в properties, где ключ - наименование поля, значение - значение из строки.
Таким нехитрым способом мы получили описание объекта.
Для описания слоя нам потребуется уже более верхоуровневая сущность - FeatureCollection. Она содержит в себе массив features - объектов.
Ой, так получается, что таблица в БД соответствует слою?
Вот мы и создали наши первые слои. А что с этим делать дальше, я покажу в следующих уроках.