Postgis тип данных Geometry на примере импортированных OpenStreetMap карт

в 12:50, , рубрики: geometry, OpenStreetMap, OSM, postgis, postgresql, Геоинформационные сервисы

Для моего проекта понадобилось построить пешеходные маршруты и считать их длину.
Я решил эту задачу с помощью pgrouting, который в свою очередь опирается на postgis.
Postgis — это расширение к Postgresql, реализующее стандарт OpenGis.
В данном расширение содержится обширный функционал для работы с пространственными данными.
Это позволяет писать интересные приложения.
В частности, OpenStreetMap использует postgis для отображения своих карт.
Постараюсь рассказать о том, как выглядят в postgis, импортированные osm карты.

Я пропущу описание того, как устанавливать postgres и postgis.
Начну с создания базы для хранения пространственных данных.

Создадим базу данных:

create database openstreetmap;

Инициализируем postgis:

create extension postgis;

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

Создадим таблицу в нашими пространственными данными:

create table my_map(
    id bigserial primary key,
    name text,
    shape geometry
);

В этой таблице поле shape имеет тип geometry.
В postgis этот тип данных является основным для представления объектов в евклидовой системе координат.

Добавим во вновь созданную таблицу точку, соответствующую центру Санкт-Петербурга:

insert into my_map(name, shape) values ('Центр СПб', ST_Point(30.3250575, 59.9174455));

Функция ST_Point создает объект точку типа geometry.
Также есть ST_MakeLine, ST_MakeEnvelope, ST_MakePolygon и другие полезные конструкторы.

Теперь можно перейти к загрузке osm карты.
Для этого нам понадобится сама карта и osm2pgsql.
Я не буду рассказывать, как устанавливать osm2pgsql.
Это зависит от системы и на windows кажется нетривиальным.
Скачав файл russia-european-part-latest.osm.pbf запускаем импорт:

osm2pgsql -d openstreetmap -U iakov -C 2000 russia-european-part-latest.osm.pbf

Неочевидным мне кажется только параметр -С он определяет размер в мегабайтах кэша, используемого при загрузке.
По умолчанию, он равен 800 и для конкретного файла не хватило, поэтому я его увеличил до 2000.
Сразу после запуска появляется надпись:

NOTICE:  table "planet_osm_point" does not exist, skipping

Это не ошибка. Postgis пытается удалить нужные ему таблицы. Так база пустая их еще не существует.

Значительное время занимает обработка данных:

Processing: Node(83577k 1816.9k/s) Way(8382k 37.42k/s) Relation(245290 939.81/s)  parse time: 531s

Это обрабатываются объекты osm. Node — это узлы, которые соответствуют точкам на карте. Way — это путь, упорядоченный список узлов.
Relation — отношение, в которые можно объединять другие элементы(узлы, пути, отношения).
Подробнее об этом можно прочитать на openstreetmap wiki.

По окончанию работы в базе появилось 4 таблицы: planet_osm_line, planet_osm_point, planet_osm_polygon, planet_osm_roads.
В planet_osm_point хранятся обработанные узлы, в planet_osm_line хранятся незамкнутые пути, в planet_osm_polygon хранятся замкнутые пути, в planet_osm_roads хранятся пути, которые соответствуют дорогам.
В каждой таблице есть поле way типа geometry.
Можно посмотреть тип геометрии с помощью GeometryType:

openstreetmap=# select GeometryType(way) from planet_osm_point group by GeometryType(way);
 geometrytype
--------------
 POINT
(1 row)

openstreetmap=# select GeometryType(way) from planet_osm_line group by GeometryType(way);
 geometrytype
--------------
 LINESTRING
(1 row)


openstreetmap=# select GeometryType(way) from planet_osm_polygon group by GeometryType(way);
 geometrytype
--------------
 MULTIPOLYGON
 POLYGON
(2 rows)

openstreetmap=# select GeometryType(way) from planet_osm_roads group by GeometryType(way);
 geometrytype
--------------
 LINESTRING
(1 row)

Четырех типов POINT, LINESTRING, POLYGON, MULTIPOLYGON достаточно, чтобы хранить карту.

Автор: corvette

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js