Язык: RU EN
На главную...

Форматы векторных карт в Mapsoft2 (2022-11-22)

В данный момент поддержка векторных карт в mapsoft находится в состоянии разработки. Еще не все сделано, возможны любые изменения.

Тут описан формат, в котором mapsoft2 может хранить наборы объектов: точек, линий, многоугольников и подписей, его преобразование в другие форматы, разные операции с ним. Для настоящей карты нужно иметь разную дополнительную информацию: название, границу, геодезическую привязку, правила рисования объектов, правила связи между объектами и т.п., однако полноценно этот уровень пока не сделан и делать его планируется отдельно. Тут описывается только работа с объектами. Некоторые форматы (например, MP) поддерживают разную дополнительную информацию о карте. Обычно низкоуровневые функции поддерживают чтение и запись этих полей, однако при преобразовании в другой формат это все должно теряться - здесь нас интересуют только объекты.

В mapsoft2 основных форматом является VMAP2. В mapsoft1 основным был текстовый формат VMAP - он до сих пор поддерживается, а с 2020 до 2022 -- база данных с гео-индексацией mapdb.

Для работы с векторыми картами используются программы ms2vmap (преобразование форматов и разные другии операции) и ms2vmapdb (разные операции с базой данных). Программа ms2render используется для рендера векторных карт.


VMAP2: объект карты

См. vmap2/vmap2obj.h

Объект является типом dMultiLine, многосегментной линией. Используются координаты WGS84.

Объект содержит следующие дополнительные поля:


VMAP2: хранилище объектов, гео-индексация

См. vmap2/vmap2.h

В mapsoft используется одно хранилище объектов VMAP2, которое, однако, может хранить объекты в двух видах: в виде простых STL контейнеров в памяти, или в базе данных BerkleyDB на диске (файл с расширением .vmap2db). Работа с хранилищем в памяти должна быть быстрее (не надо кодировать объекты для помещения в базу данных), однако при работе с базой данных на диске не тратится время на чтение и запись всех объектов.

В любом случае объекты хранятся в ассоциативном массиве с ключом типа uint32_t. Таким образом, у объектов появляется уникальный идентификатор, однако он должен использоваться только при работе с конкретным хранилищем. При преобразовании в другой формат (даже в текстовый формат VMAP2) эта информация теряется.

Параллельно с основным хранилищем строится база данных гео-идексации, которая тоже расположена либо в памяти, либо на диске (файл с расширением .map2gh). Ключ - комбинация из типа объекта (старший байт в начале!) и строки Geohash, значение - id объекта в основной базе. Записи с одинаковыми ключами допустимы. Один объект может присутствовать в нескольких записях (это позволяет записывать объект, пересекающий границу короткого геохеша, в виде двух записей с длинными геохэшами). Используя эту базу, можно быстро получить списов всех типов, или список всех объектов данного типа, или список всех объектов данного типа, находящихся в данном районе.

С точки зрения хранилища объектов никакой разницы между точками, линиями, площадными и текстовыми объектами нет. Различается только тип объекта. В данный момент не слишком хорошо определено, как должен обрабатываться точечный или текстовый объект, содержащий несколько координат. Должна ли использоваться только первая точка или все точки? Должны ли линии в текстовом объекте использоваться для рисования текста вдоль кривого контура?

Объекты не могут быть пустыми (не содержать координат). Такой запрет связан с невозможностью разместить объект в базе гео-индексации.


VMAP2: база данных BerkleyDB

Объекты хранятся в BerkleyDB, в файле с расширением .vmap2db (вообще, mapsoft2 использует расширения файла, чтобы определить его формат). Ключ -- число uint32_t, значение -- запакованный объект: в начале записан тип объекта (uint32_t), потом идет последовательность в стиле RIFF: 4-символьный тэг ("crds", "name" и т.п.), 4-байтовое число - длина данных в байтах, данные. Для текстовых данных (название объекта, комментарии и т.п.) используется кодировка UTF8. Как устроены теги, можно посмотреть в vmap2/vmap2obj.h, методы :pack() и unpack().

База данных для гео-индексации - расположенный рядом файл с тем же именем и с расширением .vmap2gh. При отсутствии этого файла он создается заново (это не слишком быстрая операция), поэтому при каких-то проблемах с этим файлом его можно просто удалить.

В данный момент никакого окружения BerkleyDB не создается, каждый файл является независимой базой данных, одновременно работать с базой данный может только одна программа. В будущем при необходимости можно будет делать окружение с блокировками, логами, транзакциями... В базах данных используются только дефолтные функции сравнения ключей, поэтому все утилиты для работы с базами BerkleyDB (db_load/db_dump и т.п.) должны работать.

В данный момент не рекомендуется использовать базу данных для хранения реальных карт: формат еще не устоялся. Кроме того, сам я планирую хранить карты в текстовом формате (например, чтобы было удобно использовать git).


VMAP2: текстовый формат

Объекты VMAP2 могут храниться в простом текстовом формате (файлы с расширением .vmap2). В файле объекты разделены пустой строкой. В начале идет строка с типом объекта, причем первый байт записывается в виде слова (point, line, area, text), а два последних -- в виде десятичного или шестнадцетеричного числа, отделенного двоеточием, например "line:0x211". После этого идет несколько строк вида "<тэг><пробел><значение>. В строковых значениях (name, comm, tags) символы \, \n, \0 заменены на \\, \\n, \\0. Выравнивание преобразовано в строки "SW", "W" и т.п. Координаты записаны в виде пар чисел (долгота и широта), разделенных пробелами. Многосегментные линии записаны в виде нескольких строк с тэгом crds. Как устроены тэги можно посмотреть в vmap2/vmap2obj.h, методы :write() и read().

Все объекты в текстовом файле сортируются для удобства хранения в git и наблюдения за изменениями.


Файл с описанием типов

См. vmap2/vmap2types.h

При преобразовании в другие форматы и при создании новых подписей обычно требуется дополнительная информация о типе объекта. Она хранится в специальном текстовом файле и читается в структуру VMap2type со следующими полями:

Пример записей в файле с типами:

type point:0x0F00
 + name      "триангуляционный знак"
 + fig_mask  "2 1 0 2 0 7 57 -1 20 0.000 1 1 -1 0 0"
 + fig_pic   "pics/trig.fig"
 + mp_end 1
 + label_type 5

type text:5
 + name "вершины"
 + fig_mask "4 0 0 41 -1 18 9 0.0000 4"

формат VMAP

VMAP - текстовый формат хранения векторнных карт, использующийся в mapsoft1. Поддержка формата - в vmap/, преобразование в VMAP2 - в vmap2/vmap2io_vmap.cpp.

Особенности преобразования VMAP в VMAP2:

Особенности преобразования VMAP2 в VMAP:


формат MP

"Польский формат", исплльзующийся для преобразования карт в векторные карты img для garmin, популярный при редактировании таких карт. Поддержка формата - в mp/, преобразование в VMAP2 - в vmap2/vmap2io_mp.cpp.

Описание формата: http://magex.sourceforge.net/doc/cGPSmapper-UsrMan-v02.4.pdf

Текст про поддержку формата в mapsoft2: ifdef(`',`',`https://github.com/slazav/mapsoft2-libs/tree/master/mp#readme')

Особенности преобразования MP в VMAP2:

Особенности преобразования VMAP2 в MP:


формат FIG

Векторный графический формат, который я использую для редактирования карт. В mapsoft2 есть расширение формата для хранения гео-привязки и работы с треками, точками, растровыми и векторныи картами. Самое первое, с чего начался mapsoft в 1998 году -- это простые скрипты на awk, позволяющие взять скачанные из gps-приемника геоданные и записать такой привязанный fig-файл. Потом можно было вручную подложить туда растровую карту, нарисовать еще треки и другим скриптом извлечь их для загрузки в gps.)

При записи в fig файл он всегда должен существовать заранее: оттуда будет взята привязка и объекты, не относящиеся к карте. Создать привязанный fig-файл можно программой ms2geofig. TODO: тут довольно много всего надо бы написать...


формат OSM XML

В библиотеке mapsoft2 имеется небольшой модуль для чтения формата OSM XML. Объекты типа node читаются в ассоциативный массив id - координаты, кроме того, читаются объекты point (node с непустыми тэгами), way и relation.

Поддерживается преобразование OSM XML в другие векторные форматы с помощью программ ms2vmap, ms2vmap2. Для этого используется отдельный конфигурационный файл, который задается параметром --osm_conf. Формат файла пока не устоялся, сейчас читаются строчки типа "(point|way) <options&rt; <type1&rt; [<type2&rt;]". Здесь options - json объект, поля которого должны совпасть с тегами объекта, type1 - тип в который преобразуется объект, type2 (задается только для линий) - точечный тип в который преобразуется объект, если он слишком мал. Предельный размер задается командой "set min_size <value&rt;" в метрах и действет на все последующие записи в файле. Значение по умолчанию - 10м.

Примеры:

way   '{"highway": "unclassified", "tunnel": ""}' line:0x06
way   '{"tunnel": "yes"}' line:0x16
point '{"natural": "cave_entrance"}' point:0x6601

формат Shape

В mapsoft2 есть возможность читать и писать файлы Shape с помощью библиотеки shapelib. Взаимодействие с форматом vmap2 пока не сделано, но, кажется, при необходимости это сделать несложно.


Разные операции с картой vmap2

TODO: обновление подписей, обновление по тэгу, обрезка и т.п.