- PVSM.RU - https://www.pvsm.ru -

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

Для моего проекта понадобилось построить пешеходные маршруты и считать их длину.
Я решил эту задачу с помощью pgrouting [1], который в свою очередь опирается на postgis [2].
Postgis — это расширение к Postgresql, реализующее стандарт OpenGis [3].
В данном расширение содержится обширный функционал для работы с пространственными данными.
Это позволяет писать интересные приложения.
В частности, OpenStreetMap [3] использует 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 карты.
Для этого нам понадобится сама карта [4] и osm2pgsql [5].
Я не буду рассказывать, как устанавливать 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 [6].

По окончанию работы в базе появилось 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

Источник [7]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/postgresql/76314

Ссылки в тексте:

[1] pgrouting: http://pgrouting.org/

[2] postgis: http://postgis.net/

[3] OpenGis: http://www.opengeospatial.org/

[4] карта: http://download.geofabrik.de/europe/russia-european-part.html

[5] osm2pgsql: http://wiki.openstreetmap.org/wiki/Osm2pgsql

[6] openstreetmap wiki: http://wiki.openstreetmap.org/wiki/Elements

[7] Источник: http://habrahabr.ru/post/245015/