В данный момент поддержка векторных карт в mapsoft находится в состоянии разработки. Еще не все сделано, возможны любые изменения.
Для получения изображение карты можно использовать команду командной строки:
$ ms2render <vmap2_file> -c <render_config> <options>
Конфигурационный файл передается через параметр -c, --config. По умолчанию используется файл render.cfg в той же директории, что и карта.
Кроме того, изображение карты можно смотреть в программе ms2view, передав директорию с картой через параметр командной строки --vmap и название конфигурационного файла через параметр --vmap_config (это сейчас не работает!).
Рисование карты выполняется в виде последовательности "шагов" (drawing steps). Каждый шаг описан в конфигурационном файле и содержит набор свойств (feature). Также, конфигурационный файл может содержать команды, не являющиеся шагами рисования. Пример конфигурационного файла: data/render.cfg Формат описания шагов рисования:
(point|line|area|text):<tnum> <feature> <options> ... + <feature> <options> ... + <feature> <options> ... ... (map|brd) <feature> <options> ... + <feature> <options> ... + <feature> <options> ... ...
Шаги point, line, area, text описывают рисование линейного, точечного, площадного или текстового объекта с номером типа <tnum>. Шаг map описывает рисование на всей площади карты (можно нарисовать одноцветную подложку, но можно делать и более хитрые вещи), Шаг brd описывает рисование границы и закрашивание области вне ее.
Свойства (features):
stroke <width> <color> -- Нарисовать контур объекта линией заданной толщины и цвета. Применимо к шагам point, line, area, text, brd. Цвет всегда задается в виде 32-битного числа с прозрачностью (0xFF000000 - черный, 0xFFFF0000 - красный, 0x80FFFFFF - белый полупрозрачный и т.п.). Для текстового объекта линией обводятся контуры букв.
fill <color> -- Заливка заданным цветом. Применимо к шагам point, line, area, map, text, brd. Для текстового объекта заливка применяется к контурам букв, результат немного отличается от использования стандартной функции рендера текста (см. свойство write ниже). Для точек - влияет только на свойства lines и circles.
pulk_grid <step> <color> <line width> -- Рисование сетки в системе координат Пулково-1942, как на советских картах. Применимо только к шагу map. Параметр step - в километрах, если <=0, то выставляется некоторое автоматическое значение.
fi_grid <step> <color> <line width> -- Рисование сетки в системе координат ETRS-TM35FIN, для финских карт. Применимо только к шагу map. Параметр step - в километрах, если <=0, то выставляется некоторое автоматическое значение.
grid_labels <size> <font> <color> -- Нарисовать подписи к сетке.
font <size> <font pattern> -- Установить шрифт
для рисования текстовых объектов. "font pattern" задается в терминах библиотеки
fontconfig, какая-то информация есть тут:
https://www.freedesktop.org/software/fontconfig/fontconfig-devel/x19.html
https://www.freedesktop.org/software/fontconfig/fontconfig-user.html
https://wiki.archlinux.org/index.php/Font_configuration
write <color> -- Нарисовать текстовый объект заданным цветом.
patt <image file> <scale> <dx> <dy> -- Заливка площади заданной картинкой. Применимо к шагам line, area, text, map, brd. Картинка - в любом растровом формате, поддержтиваемом mapsoft2: png, gif, tiff, jpeg. Кроме того, поддерживаются картинки svg. Путь к картинке должен быть указан относительно места, где лежит конфигурационный файл. Параметр scale - масштаб картинки, dx и dy - сдвиг картинки (в единицах размера картинки). По умолчанию картинка выравнивается по центру. Если dx=dy=-0.5, то выравнивание будет сделано по левому-нижнему углу. Для текстового объекта заливка применяется к контурам букв.
И растровые и SVG картинки всегда загружается в виде растра, в собственном масштабе (то есть, если в SVG указан размер 100x200 точек, то такой растр и будет создан). После этого картинки перемасштабируются к нужному размеру. Старайтесь избегать больших картинок, перемасштабированных к маленькому размеру и заполняющих большую область. Во-первых, это очень медленно, это самая медленная операция при рисовании карт. Во-вторых, начиная с некоторого масштаба и размера заливки libcairo перестает рисовать что-либо. Как это устроено, я пока не понял, сделал лишь очевидное ограничение: размер картинки ограничен величиной один пиксел (после этого она перестает масштабироваться). Но для больших исходных картинок это не помогает.
При рисовании плиточных карт плитки должны укладываться в картинку целое число раз. Это достигается использованием параметра fit_patt_size (см.ниже).
img <image file> <scale> <dx> <dy> -- Рисование изображения. Применимо к шагам point, area (в этом случае картинка рисуется в центре площади). Картинка задается так же, как и в свойстве patt.
img_filter <flt> -- Установить фильтр растровых изображений. Применимо к шагам point, area, text, map, brd, используется совместно со свойствами img и patt. Возможные значение: fast, good, best, nearest, bilinear (см. https://www.cairographics.org/manual/cairo-cairo-pattern-t.html#cairo-filter-t)
smooth <distance> -- Использовать закругленные линии с заданным размером закругления. Применимо к шагам line, area, brd, используется совместно со свойствами stroke, fill, patt.
dash <len1> ... -- Использовать штриховые линии. Параметры задают длины штрихов и промежутков между ними, так как это принято в библиотеке Cairo. (Если параметр один - длины штрихов и промежутков равны, если параметров более одного - они задают чередование длин штрихов и промежутков между ними). Применимо к шагам line, area, text, brd используется совместно со свойством stroke.
cap round|butt|square -- Описывает, как рисовать окончание линии. Применимо к шагам line, area, text, brd, используется совместно со свойством stroke. По умолчанию - round.
join round|miter -- Описывает, как рисовать стыки сегментов линий. Применимо к шагам line, area, text, brd, используется совместно со свойством stroke. По умолчанию - round.
operator <op> -- Установить оператор рисования. Возможные значения: clear, source, over, in, out, atop, dest, dest_over, dest_in, dest_out, dest_atop, xor, add, saturate (см. https://www.cairographics.org/operators/). Значение по умолчанию - over. Применимо к шагам point, line, area, text, map, brd.
clip -- Установить обрезку изображения по объекту типа text, area, map или brd. Обрезка будет действовать для всех дальнейших шагов до нового clip. Чтобы вернуться к обрезке по границе или сбросить обрезку, сделайте map clip или brd clip
outer -- Использовать внешнюю область для заливки и обрезки (только для объекта типа brd).
lines <lines> ... -- Вместо самого объекта рисовать дополнительные линии, привязанные к каким-то местам объекта (см. свойство draw_pos). Аргументы - одно- или многосегментные линии в виде json-массивов: [[x1,y1],[x2,y2]]... Для рисования линий используются те же свойства, что и для рисования самого объекта (stroke, fill, cap, smooth и т.д.). Для линейных и площадных объектов координты ориентированы по направлению объекта: x вдоль линии, y - перпендикулярно, вправо от нее. Для точечных объектов x вправо, y - вниз. На ориентацию также влияет свойство rotate и параметр наклон объекта.
circles <circle> ... -- Вместо самого объекта рисовать дополнительные окружности, привязанные к каким-то местам объекта (см. свойство draw_pos). Аргументы - параметры окружностей в виде трехэлементных json-массивов: [x,y,r]. Для рисования окружностей используются те же свойства, что и для рисования самого объекта (stroke, fill, cap, smooth и т.д.). Координты ориентированы по направлению объекта: x вдоль линии, y - перпендикулярно, вправо от нее. На ориентацию также влияет свойство rotate и параметр наклон объекта.
draw_pos (point|begin|end)
draw_pos (dist|edist) <dist> [<dist_b>] [<dist_e>] -- Место рисования элементов lines и circles: point -- в каждом узле объекта (значение по умолчанию и единственное возможное значение для точечных объектов); begin/end -- в начальной/конечной точке; dist, edist -- периодически вдоль объекта, на заданном расстоянии друг от друга; При этом параметры <dist> <dist_b> <dist_e> задают период, начальное и конечное расстояние. Значения по умолчанию: <dist_b>=<dist>/2, <dist_e>= <dist_b>. Если второй параметр имеет значение dist, то начальное расстояние и период отсчитывюаются точно, а конечное расстояние получается не менее <dist_e>. Если edist -- то период подстраивается так, чтобы конечное расстояние было равно в точности <dist_e>.
move_to <max_distance> (area|line|point):<tnum> -- Сдвинуть точки объекта к ближайшему линейному объекту, или ближайшей границе площадного объекта, или ближайшей точке типа type, но не далее max_distance. Применимо к шагам типа point/line/area.
rotate_to <max_distance> (area|line):<tnum> -- То же, что и move_to, но картинка объекта также поворачивается по направлению линии.
rotate_from <max_distance> (area|line):<tnum> -- Сдвинуть точки объекта от ближайшего линейного объекта, или ближайшей границы площадного объекта, или ближайшей точки типа type, на min_distance. Применимо к шагам типа point/line/area.
rotate <angle,deg> -- Повернуть картинку объекта или текст на фиксированный угол (градусы, по часовой стрелке). Добавляется к собственным поворотам объекта или повороту с помощью свойства rotate_to. Свойство применимо к шагам point, line, area, text. См ниже раздел про повороты объектов.
short_expand <length> -- Удлиннить короткие линии до указанной длины, пропорционально удлиннив крайние сегменты.
short_skip <length> -- Удалить линии, имеющие длину меньше указанной.
sel_range <width> <color> -- Нарисовать предполагаемый диапазон объекта, по которому он выбирается из базы данных. Для расчета диапазона используются остальные правила рисования (например, stroke с ненулевой толщиной линии увеличивает диапазон на толщину линии, картинка - на диагональный размер картинки и т.п.) Для поиска текста используется параметр max_text_size (см.ниже).
pix_align <(0|1)> -- Округлять координаты текста к целым пикселам. Похоже, что этот параметр не очень нужен, если правильно настроен hinting шрифта. Применимо к шагу типа text.
name <name> -- Объявить название шага (для показа в интерфейсе). По умолчанию название составляется из типа объекта, напрмер "line:0x25".
group <name> -- Название группы для данного шага. Группа может включать несколько шагов.
В одном шаге рисования могут присутствовать несколько свойств. На каждом шаге рисование происходит в следующем порядке:
Определяется диапазон, в котором надо искать объекты. На него влияют свойства, которые приводят к сдвигу объектов или созданию картинки конечного размера: stroke, img, patt, move_to, rotate_to. Для текстовых объектов используется некий фиксированный размер (по умолчанию 1024 точки, см. команду max_text_size ниже).
Если шаг имеет тип point, line, area, text, то выбираются соответствующие объекты в нужном диапазоне.
Если присутствует свойство sel_range, то рисуются прямоугольники вокруг объектов.
Настраивается оператор рисования (свойство operator), настраивается шрифт (свойство font).
Если присутствуют свойства stroke, fill, patt, то строится "путь" рисования (path).
Выполняется заливка картинкой (свойство patt).
Выполняется заливка цветом (свойство fill).
Выполняется рисование контура (свойство stroke). При этом настраиваются параметры рисования, соответствующие свойствам dash, cap, join.
Выполняется рисование картинок (свойство img).
Выполняется рисование текста (свойство write).
Если хочется использовать другой порядок (например, сперва контур, потом заливку, потом паттерн) - придется сделать несколько последовательных шагов рисования.
Дополнительные команды, которые могут встречаться в конфигурационном файле:
set_ref file <filename> -- установить "естественную" привязку карты из файла (сейчас поддерживаются только файлы OziExplorer). Потом карта может быть нарисована в другой системе координат, но относительно "естественной" привязки считаются толщины линий, размер шрифтов и т.п. При установки привязки устанавливается также и граница карты.
set_ref nom <name> <dpi> -- установить "естественную" привязку карты по советскому номенклатурному листу, с заданным разрешением (в точках на дюйм, например 300). Использовуется "расширенный формат" номенклатурных названий, допускающий одиночные листы (например r36-010) и "диапазоны" листов (например j42-040.3x3 -- блок из девяти одиночных листов). При установки привязки устанавливается также и граница карты.
set_ref nom_fi <name> <dpi> -- установить "естественную" привязку карты по финскому номенклатурному листу, например V51.
set_ref none -- убрать "естественную" привязку и границу карты.
set_brd file <filename> -- установить отдельно границу карты, используя трек, записанный в файле (возможно, с несколькими сегментами).
set_brd nom <name> -- установить отдельно границу карты, используя название номенклатурного листа.
set_brd none -- очистить границу карты.
max_text_size <number> -- изменить максимальный размер текста (в точках). Этот параметр используется при поиске текстовых объектов на карте. Значение по умолчанию - 1024 точки. Размер относится к "естественному" масштабу карты, при изменении масштаба параметр перемасштабируется соответствующим образом.
minsc <number> -- изменить минимальный масштаб карты (меньше которого она рисуется сплошной заливкой). Масштаб считается относительно "собственной" привязки, которая устанавливается командой set_ref. По умолчанию этот параметр равен 0.01.
minsc_color <color> -- изменить цвет заливки для карты с масштабом меньше минимального. По умолчанию 0xFFDB5A00.
define <name> <definition> -- определить переменную. В последующем файле все вхождения ${<name>} будут заменены на <definition>.
define_if_undef <name> <definition> -- определить переменную, если она еще не определена.
if <name> (==|!=) <name>
ifdef <name>
ifundef <name>
else
endif -- команды if/else/endif: в зависимости
от истинности условия, обрабатывать или игнорировать текст, заключенный
между if и endif. Пары if/endif могут быть вложенными, команда else
инвертирует последнее условие, заданное командой if.
include <name> -- прочитать внешний файл. Путь
к файлу может быть абсолютный, или относительный, от директории текущего
конфигурационного файла. Директории относительных путей, используемых
во вложенном файле (картинки, другие include'ы) считаются от положения
этого вложенного файла.
obj_scale <val> -- увеличить все объекты (шрифт,
толщины линий, картинки и т.д.), то же, что параметр командной строки
--obj_scale.
fit_patt_size 0|1 -- подстраивать размер паттернов
под размер картинки. Это полезно при генерации плиточных карт.
То же, что параметр командной строки --fit_patt_size.
Возможность отключать в интерфейсы свойства move_to, rotate_to, а, может, и любые свойства.
Более разверyтый интерфейс команды ms2mapdr render: параметры для задания привязки и масштаба линий, исключения заданных групп шагов рисования и т.п.
"Расталкивание" линейных объектов. Например, рисовать дорогу на неком минимальном расстоянии от реки, чтобы линии не наползали.
Объекты имеют параметр "наклон" (angle). Наклон применяется только к тексту, растровым картинкам или картинкам, нарисованным с помощью свойств lines и circles, но не к координатам объекта. Наклон может отсутствовать, в этом случае картинка объекта ориентируется на верх карты. Если наклон задан, то он отсчитывается от географического севера, по часовой стрелке.
Свойство рисования rotate_to ориентирует картинку объекта по указанной линии, игнорируя его собственный наклон.
Свойство рисования rotate добавляет к наклону (собственному или возникшему из-за использования rotate_to) фиксированный угол (в градусах, по часовой стрелке).
В формате VMAP параметр наклон объектов и текста определялся весьма странно: angle = atan2(dlat, dlon), где отрезок с координатами (dlat, dlon) определяет направление объекта в географических координатах. Поскольку координаты имеют разных масштаб по lat и lon, эта величина сильно отличается от настоящего угла поворота. При экспорте/импорте объектов из vmap наклоны объектов пересчитываются. Надо ли делать так при работе с MP (куда такие наклоны тоже попадали) - непонятно. Можно, наверное, сделать специальный параметр в конфигурационных файлах для импорта/экспорта...
Привязка карты может быть установлена через конфигурационный файл (команда set_ref), из файла или по номенклатурному листу. При этом также устанавливается граница (которую потом можно нарисовать командой brd). Также, границу можно изменить командой set_brd, из файла с треком (трек может быть многосегментным).
Такая, установленная через конфигурационный файл привязка не обязательно будет использована для рисования карты: при отрисовке используется свой механизм преобразований в разные системы координат и ничто не мешает нарисовать карту в любой другой системе. Например, при рисовании карты через ms2render используется связка функций geo_mkref (задание привязки с помощью набора параметров) и write_geoimg - рисование картинки в соответствии с привязкой. По умолчанию используется собственная привязка карты, но ее можно поменять с помощью параметров --mkref. Отдельно можно поменять добавить "внешнюю" границу с помощью переметров --border_wgs или --border_file. Можно использовать параметр --tmap, чтобы сгенерировать набор плиток (они, разумеется, рисуются в своей собственной системе координат).
При установке привязки через конфигурационный файл запоминается ее "естественный" масштаб, размер точки растра в метрах. Он важен при выборе толщины линий, размер шрифтов и т.п. Если карта рисуется в другой системе координат, то все эти величины будут перемасштабироваться. Кроме того, может быть удобно использовать параметр --obj_scale - дополнительный множитель для всех таких размеров. Если карта не имеет собственной привязки (установленной через коннфигурационный файл), то размеры объектов не будут меняться при перемасштабировании карты.
Размер шрифтов при таком подходе вычисляется так (возможно, надо это как-то поменять): Сперва задается "естественная привязка". Например, можно сказать, что это номенклатурный лист с масштабом 1:100000 и разрешением 200dpi. Это задает размер точки растра на местности, в данном случае это 12.7m. Текст рендерится в стандартном разрешении Cairo, 96dpi (то есть, шрифт 10pt будет иметь размер 10/72 * 96 * 12.7m = 169 м на местности). При рисовании карты в других масштабах и проекциях размер шрифта (и ширина линий) перемаштабируется, чтобы все размеры (на местности) оставались теми же.
Один из возможных рецептов: инкрементальное создание набора плиток из листов карты. Каждый лист имеет свою привязку и границу (например, это номенклатурные листы). При рисовании должна быть включена обрезка объектов по границе карты (см. команду clip_border). Программе map_render даются параметры --tmap - делать набор плиток, --add - дорисовывать листы на старые плитки, если они имеются, --border_file/--border_wgs - дополнительно обрезать все по внешней границе.