В данный момент поддержка векторных карт в 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 - белый полупрозрачный и т.п.). Для текстового объекта линией обводятся контуры букв.
stroke2 <width> <color> -- Повторить рисование stroke, но с другой толшиной и цветом.
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> -- Нарисовать текстовый объект заданным цветом.
# Пример конфигурационного файла: свойства stroke, stroke2, fill и write
# Во всех примерах ниже используется карта с одинаковыми объектами,
# меняются лишь правила рисования (см. docs/render_examples).
# шаг1: заполняем карту белым цветом (не обязательно, так как по умолчанию
# цвет подложки - белый)
map fill 0xFFFFFFFF
# шаг2: рисуем площадной объект типа 1 с
# зеленой границей толщины 1 и светло-зеленой заливкой
area:1 stroke 0xFF00FF00 1
+ fill 0xFFAAFFAA
# шаг3: рисуем линейный объект типа 1 линией с толщиной 5
# а потом поверх рисуем тонкую центральную линюю
line:1 stroke 0xFF00FFFF 5
+ stroke2 0xFF0000FF 1
# шаг4: рисуем точечный объект типа 1 красный точкой диаметром 8 с белой каймой
point:1 stroke 0xFFFFFFFF 12
+ stroke2 0xFFFF0000 8
# шаг5: текст (цвет синий, размер - 10px, шрифт - DejaVu Sans)
# кроме того, обводим контур белой линией толщиной 4
text:1 font 10 "DejaVu Sans:Bold:semicondensed:rgba=none"
+ write 0xFF0000FF
+ stroke 0xFFFFFFFF 4
# Нарисовать текст можно, используя свойство fill вместо write,
# В этом случае вместо стандартной функции рендера текста
# создается контур, который заливается нужным цветом.
# Результат немного отличается.
# кроме того, здесь же я даю пример использования команды define
# (см. ниже)
define white 0xFFFFFFFF
define green 0xFF00FF00
define blue 0xFF0000FF
define light_green 0xFFAAFFAA
define myfont "DejaVu Sans:Bold:semicondensed:rgba=none"
map fill ${white}
area:1 stroke ${green} 1
+ fill ${light_green}
line:1 stroke ${blue} 2
# текст:
text:1 font 10 ${myfont}
+ stroke ${white} 4
text:1 font 10 ${myfont}
+ fill ${blue}
# (Для текста можно использовать и свойство patt, заливать
# контур картинкой, хотя непонятно, зачем бы это могло пригодится...)
# Пример с полупрозрачными цветами
map fill 0xFFFFFFFF
area:1 stroke 0xFF00FF00 4
+ fill 0xFFAAFFAA
# линия имеет полупрозрачный цвет
line:1 stroke 0x800000FF 5
point:1 stroke 0xFFFF0000 8
# шаг5: текст с полупрозрачным контуром вокруг
text:1 font 10 "DejaVu Sans:Bold:semicondensed:rgba=none"
+ write 0xFF0000FF
+ stroke 0x7FFFFFFF 4
# белая полупрозрачная заливка поверх всего
map fill 0x80FFFFFF
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)
# Example for `patt` and `img` features
# fill background with a pattern and then with
# semi-transparent white color:
map fill 0x80FFFFFF
+ patt vyr_o.png 0.3
# draw polygon with contour and pattern filling
area:1 stroke 0xFF008000 1
+ patt vyr_o.png 0.3
# draw point with image
point:1 img skala.png 0.5
# draw image in the center of polygon
area:1 img skala.png 0.3
# Example for `img_filter` feature
# fill background with a pattern with `nearest` (=`fast`) filter
map patt vyr_o.png 0.3
+ img_filter nearest
# fill polygon with a pattern with default (=`good`) filter
area:1 stroke 0xFF008000 1
+ patt vyr_o.png 0.3
# картинки, нарисованные в слишком мелком масштабе
map patt vyr_o.png 0.08
# Заливка картинкой в мелком масштабе рисуется однородным
# усредненным цветом
area:1 stroke 0xFF008000 1
+ patt vyr_o.png 0.0001
# Картинка в мелком масштабе рисуется как отдельная точка с
# усредненным цветом
point:1 img skala.png 0.0001
smooth <distance> -- Использовать закругленные линии с заданным размером закругления. Применимо к шагам line, area, brd, используется совместно со свойствами stroke, fill, patt.
shift <distance> -- Сдвинуть линию в перпендикулярном направлении на указанное расстояние. Применимо к шагам line, area, brd, используется совместно со свойствами stroke, fill, patt. Игнорируется, если используется положительное значение smooth.
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.
# Example for `smooth` and `shift` features
map fill 0xFFFFFFFF
area:1 stroke 0xFF00FF00 1
+ fill 0xFFAAFFAA
+ smooth 20
line:1 stroke 0xFF0000FF 2
+ smooth 20
line:1 stroke 0xFFFF0000 2
+ shift +4
+ dash 0 4
+ cap round
line:1 stroke 0xFFFF0000 2
+ shift -4
+ dash 0 4
+ cap round
# Example for `dash` feature
map fill 0xFFFFFFFF
area:1 stroke 0xFF00FF00 1
+ fill 0xFFAAFFAA
+ smooth 20
+ dash 5
line:1 stroke 0xFF0000FF 5
+ smooth 20
+ dash 20
line:1 stroke 0xFFFF00FF 5
+ smooth 20
+ dash 4 12 4 20
point:1 stroke 0xFFFF0000 8
# Example for `cap` feature
map fill 0xFFFFFFFF
area:1 stroke 0xFF00FF00 3
+ fill 0xFFAAFFAA
+ dash 10
+ join round
line:1 stroke 0xFF0000FF 5
+ cap square
+ dash 20
line:1 stroke 0xFFFF00FF 5
+ cap butt
+ dash 4 12 4 20
point:1 stroke 0xFFFF0000 8
# Example for `join` feature
map fill 0xFFFFFFFF
area:1 stroke 0xFF00FF00 1
+ fill 0xFFAAFFAA
line:1 stroke 0xFF0000FF 10
+ join miter
+ cap butt
line:1 stroke 0xFFFF00FF 10
+ join round
+ cap butt
point:1 stroke 0xFFFF0000 8
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.
# Пример использования свойства `operator`.
# Иногда надо сделать "странную" последовательность рисовки объектов
# или их частей (А над Б, Б над В, В над А). Это можно сделать, использовав
# разные операторы рисования.
# В данном случае я хочу сделать двойную линию, причем середина должна быть
# "прозрачна" для некоторых ранее нарисованных объектов (площадной объект).
# Кроме того, контур текста тоже сделаю прозрачным для зеленой заливки.
# шаг1: рисую площадной объект
area:1 stroke 0xFF007F00 3
+ fill 0xFFAAFFAA
# шаг2: рисую линейный объект (толстая синяя линия)
line:1 stroke 0xFF0000FF 8
+ cap butt
# шаг3: стираю сердцевину линейном объекте
line:1 stroke 0xFFFFFFFF 4
+ operator clear
# шаги4 и 4а: рисую площадной объект в вырезанной области.
# Тут есть дурацкая проблема: С оператором dest_over
# свойства stroke и fill, будучи использованы в одном
# шаге рисования выглядят как примененные в обратном порядке,
# и заливка закроет часть контура. Чтобы все было правильно,
# делаю два шага: сперва контур, потом заливку.
area:1 stroke 0xFF007F00 3
+ operator dest_over
area:1 fill 0xFFAAFFAA
+ operator dest_over
# шаг5: текст, вырезаем контур
text:1 font 15 "DejaVu Sans:Bold:semicondensed:rgba=none"
+ stroke 0xFFFFFFFF 4
+ operator clear
# шаг6: зеленая заливка в вырезанной области
area:1 fill 0xFFAAFFAA
+ operator dest_over
# шаг7: рисую белую заливку там, где не было ничего нарисовано.
map fill 0xFFFFFFFF
+ operator dest_over
# шаг8: текст
text:1 font 15 "DejaVu Sans:Bold:semicondensed:rgba=none"
+ write 0xFF0000FF
clip -- Установить обрезку изображения по объекту типа text, area, map или brd. Обрезка будет действовать для всех дальнейших шагов до нового clip. Чтобы вернуться к обрезке по границе или сбросить обрезку, сделайте brd clip или map clip
# Пример использования свойства `clip`.
# Я хочу, чтобы линия, проходящая поверх зеленой заливки меняла цвет
# (например, на некоторых картах горизонтали на ледниках рисуют синим цветом).
# рисую площадной объект
area:1 stroke 0xFF007F00 3
+ fill 0xFFAAFFAA
# рисую линейный объект (толстая синяя линия)
line:1 stroke 0xFF0000FF 8
# устанавливаю обрезку по площадному объекту:
area:1 clip
# рисую линию
line:1 stroke 0xFF800080 8
# убираю обрезку
map clip
# рисую тонкую красную линию, чтоб проверить, что обрезка убрана
line:1 stroke 0xFFFF0000 2
# Того же эффекта можно добиться с помощью свойства operator.
# Однaко, в более сложных случаях clip может быть удобнее.
# контур
area:1 stroke 0xFF007F00 3
# линия
line:1 stroke 0xFF0000FF 8
# вырезаю дырку
area:1 fill 0xFFAAFFAA
+ operator clear
# рисую линию
line:1 stroke 0xFF800080 8
+ operator dest_over
# контур
area:1 stroke 0xFF007F00 3
+ operator dest_over
# заливка
area:1 fill 0xFFAAFFAA
+ operator dest_over
# красная линия
line:1 stroke 0xFFFF0000 2
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>]
draw_pos fill <w> <h> -- Место рисования элементов 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>; Если место рисования -- fill <w> <h>, то создается картинка указанного размера, рисование происходит на ней (координаты отсчитываются от левого-верхнего угла), с помощью этой картинки закрашивается площадь.
# Рисование дополнительных элементов
map fill 0xFFFFFFFF
# рисуем площадной объект
area:1 stroke 0xFF008000 1
+ fill 0xFFAAFFAA
# отмечаем узлы точки площадного синими кружками с
# красной заливкой (круг с центром в точке и радиусом 3)
area:1 stroke 0xFF0000FF 1
+ fill 0xFFFF0000
+ circles [0,0,3]
# зеленые штрихи, направленные вперед и влево от направления линии
# с периодом 10 точек
area:1 stroke 0xFF008000 1
+ lines [[0,0],[3,-3]]
+ draw_pos edist 10
# линейный объект: линия
line:1 stroke 0xFF0000FF 1
# линейный объект: синие стрелки по краям
line:1 stroke 0xFF0000FF 1
+ lines [[6,-4],[0,0],[6,4]]
+ draw_pos begin
line:1 stroke 0xFF0000FF 1
+ lines [[-6,-4],[0,0],[-6,4]]
+ draw_pos end
# поперечные линии примерно через 20 точек, расстояние от краев 12 и 24 точек:
line:1 stroke 0xFF0000FF 1
+ lines [[0,-4],[0,4],[4,4]]
+ draw_pos edist 20 12 24
# поперечные красные линии строго через 20 точек, расстояние
# от левого края 12 точек, от правого - какое получится, не меньше 12 точек:
line:1 stroke 0xFFFF0000 1
+ lines [[0,-4],[0,4],[4,4]]
+ draw_pos dist 20 12 12
# точечный объект - черная точка в центре:
point:1 stroke 0xFF000000 2
# рисуем точечный объект в виде двух треугольников
# (координата x - вправо, y - вниз)
point:1 stroke 0xFFFF0000 1
+ lines [[-3,1],[0,-4],[3,1],[-3,1]]\
[[-6,2],[0,-8],[6,2],[-6,2]]\
# Того же эффекта можно добиться с помощью свойства operator.
# Однaко, в более сложных случаях clip может быть удобнее.
# контур + заливка
area:1 stroke 0xFF007F00 2
+ fill 0xFFAAFFAA
# заливка нарисованным паттерном
area:1 draw_pos fill 16 16
+ circles [8,6,4]
+ lines [[8,10],[8,14],[10,14]]
+ stroke 0xFF000000 2
+ fill 0xFF007F00
move_to <max_distance> (area|line|point):<tnum> -- Сдвинуть точки объекта к ближайшему линейному объекту, или ближайшей границе площадного объекта, или ближайшей точке типа type, но не далее max_distance. Применимо к шагам типа point/line/area.
rotate_to <max_distance> (area|line):<tnum> -- То же, что и move_to, но картинка объекта также поворачивается по направлению линии.
move_from <max_distance> (area|line):<tnum> -- Сдвинуть точки объекта от ближайшего линейного объекта, или ближайшей границы площадного объекта, или ближайшей точки типа type, на min_distance. Применимо к шагам типа point/line/area.
rotate <angle,deg> -- Повернуть картинку объекта или текст на фиксированный угол (градусы, по часовой стрелке). Добавляется к собственным поворотам объекта или повороту с помощью свойства rotate_to. Свойство применимо к шагам point, line, area, text. См ниже раздел про повороты объектов.
# Сдвигание точек к ближайшем линиям.
# Иногда хочется, чтобы при рисовании точки точно
# попадали на линии (перевалы на хребет, отметки уреза воды на
# реки и озера, ж/д станции на ж/д)
map fill 0xFFFFFFFF
# площадной объект
area:1 stroke 0xFF00FF00 1
+ fill 0xFFAAFFAA
# линейный объект
line:1 stroke 0xFF0000FF 1
# точка - исходное положение
point:1 stroke 0xFF000000 4
point:1 stroke 0xFF000000 1
+ lines [[0,0],[0,-10],[6,-8],[0,-6]]
# точка - сдвинута к границе ближайшего площадного объекта
# (но не дальше 30 точек)
point:1 stroke 0xFF0000FF 4
+ move_to 30 area:1
point:1 stroke 0xFF000000 1
+ lines [[0,0],[0,-10],[6,-8],[0,-6]]
+ move_to 30 area:1
# точка - сдвинута к ближайшей линии типа 1 или площадному
# объекту типа 1 (но не дальше 30 точек) и повернута
point:1 stroke 0xFFFF0000 4
+ rotate_to 30 line:1 area:1
point:1 stroke 0xFF000000 1
+ lines [[0,0],[0,-10],[6,-8],[0,-6]]
+ rotate_to 30 line:1 area:1
# move_to/move_from example
area:1 fill 0xFFA0FFA0
# базовые линии и точки (синий цвет)
line:1 stroke 0xFF0000FF 2
line:1 fill 0xFF0000FF
+ circles [0,0,2]
point:1 stroke 0xFF0000FF 8
# сдвигаемые линии и точки - исходное положение (черный цвет)
line:2 stroke 0xFF000000 1
point:2 stroke 0xFF000000 4
# притяжение к базовым линиям и точкам (малиновый цвет)
line:2 stroke 0xFFFF00FF 1
+ move_to 20 line:1
point:2 stroke 0xFFFF00FF 4
+ move_to 20 point:1 line:1
# отталкивание от базовых линий и точек (красный цвет)
line:2 stroke 0xFFFF0000 1
+ move_from 20 line:1
point:2 stroke 0xFFFF0000 4
+ move_from 20 point:1 line:1
short_expand <length> -- Удлиннить короткие линии до указанной длины, пропорционально удлиннив крайние сегменты.
short_skip <length> -- Удалить линии, имеющие длину меньше указанной.
area:1 fill 0xFFA0FFA0
line:1 stroke 0xFF0000FF 6
line:1 stroke 0xFF000000 1
+ short_expand 50
line:1 stroke 0xFFFF0000 3
+ short_skip 50
sel_range <width> <color> -- Нарисовать предполагаемый диапазон объекта, по которому он выбирается из базы данных. Для расчета диапазона используются остальные правила рисования (например, stroke с ненулевой толщиной линии увеличивает диапазон на толщину линии, картинка - на диагональный размер картинки и т.п.) Для поиска текста используется параметр max_text_size (см.ниже).
# Показ границ объектов, по которым производится их выборка.
map fill 0xFFFFFFFF
# площадной объект
area:1 stroke 0xFF00FF00 1
+ fill 0xFFAAFFAA
+ sel_range 0xFFFF0000 0.5
# линейный объект
line:1 stroke 0xFF0000FF 4
+ sel_range 0xFFFF00FF 0.5
# точка - исходное положение
point:1 stroke 0xFFFF0000 4
+ sel_range 0xFFFF00FF 0.5
# точка - сдвинута к ближайшей линии типа 1 или площадному
# объекту типа 1 (но не дальше 20 точек)
point:1 stroke 0xFFFF0000 4
+ move_to 20 line:1 area:1
+ sel_range 0xFFFF00FF 0.5
# По умолчанию ищется текст с размером до 1024x1024 точек.
# Это можно изменить командой max_text_size
max_text_size 10
text:1 font 10 "DejaVu Sans:Bold:semicondensed:rgba=none"
+ write 0xFF0000FF
+ sel_range 0xFFFF00FF 0.5
pix_align <(0|1)> -- Округлять координаты текста к целым пикселам. Похоже, что этот параметр не очень нужен, если правильно настроен hinting шрифта. Применимо к шагу типа text.
text_vspace <
name <name> -- Объявить название шага (для показа в интерфейсе). По умолчанию название составляется из типа объекта, напрмер "line:0x25".
group <name> -- Название группы для данного шага. Группа может включать несколько шагов.
save_to_stack <name> -- Сохранить шаг рисования в стек с указанным именем (ничего нарисовано не будет). После можно нарисовать весь стек с помощью команды stack_render (см.ниже).
# Сохраняю шаги рисования в три стека:
# - по умолчанию
# - внутри многоугольника
# - вокруг текста
define myfont "DejaVu Sans:Bold:semicondensed:rgba=none"
# фон + зеленый многоугольник
map fill 0xFFAAFFAA
+ save_to_stack in_polygon
map fill 0xFFFFFFFF
+ save_to_stack near_text
area:1 fill 0xFFAAFFAA
+ save_to_stack near_text
# линия, разным цветом
line:1 stroke 0xFF0000FF 8
+ save_to_stack normal
line:1 stroke 0xFF008000 8
+ save_to_stack in_polygon
line:1 stroke 0xFF80A0FF 8
+ save_to_stack near_text
text:1 font 10 ${myfont}
+ write 0xFF000000
+ save_to_stack near_text
#### а теперь все рендерю
stack_render normal
# вырезаю дырку в многоугольнике
area:1 fill 0
+ operator clear
stack_render in_polygon dest_over
# вырезаю дырку вокруг текста
text:1 font 10 ${myfont}
+ stroke 0 4
+ fill 0
+ operator clear
stack_render near_text dest_over
В одном шаге рисования могут присутствовать несколько свойств. На каждом шаге рисование происходит в следующем порядке:
Определяется диапазон, в котором надо искать объекты. На него влияют свойства, которые приводят к сдвигу объектов или созданию картинки конечного размера: 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.
stack_render <name> [<operator>] --
выполнить в этом месте последовательность шагов, сохраненных ранее с
помощью свойства save_to_stack. Используется указанный оператор
рисования (по умолчанию "over"), операторы, указанные в шагах
игнорируются. Если оператор - "dest_over", то шаги выполняются в
обратном порядке. После команды stack_render в этот стек можно
продолжить добавлять объекты и потом опять его использовать.
stack_clear <name> -- очистить стек с указанным именем.
Возможность отключать в интерфейсы свойства move_to, rotate_to, а, может, и любые свойства.
Более разверyтый интерфейс команды ms2render: параметры для задания привязки и масштаба линий, исключения заданных групп шагов рисования и т.п.
Объекты имеют параметр "наклон" (angle). Наклон применяется только к тексту, растровым картинкам или картинкам, нарисованным с помощью свойств lines и circles, но не к координатам объекта. Наклон может отсутствовать, в этом случае картинка объекта ориентируется на верх карты. Если наклон задан, то он отсчитывается от географического севера, по часовой стрелке.
Свойство рисования rotate_to ориентирует картинку объекта по указанной линии, игнорируя его собственный наклон.
Свойство рисования rotate добавляет к наклону (собственному или возникшему из-за использования rotate_to) фиксированный угол (в градусах, по часовой стрелке).
В старом формате VMAP параметр наклон объектов и текста определялся весьма странно: angle = atan2(dlat, dlon), где отрезок с координатами (dlat, dlon) определяет направление объекта в географических координатах. Поскольку координаты имеют разных масштаб по lat и lon, эта величина сильно отличается от настоящего угла поворота. При экспорте/импорте объектов из vmap наклоны объектов пересчитываются. Надо ли делать так при работе с MP (куда такие наклоны тоже попадали) - непонятно. Можно, наверное, сделать специальный параметр в конфигурационных файлах для импорта/экспорта...
# Примеры объектов с наклонами. Из трех точечных и трех текстовых
# объектов левые не имеют собственного наклона, они ориентированы на верх
# карты; центральные имеют наклон 0, они ориентированы на север. правые
# имеют собственный наклон 20 градусов.
# площадной и линейный объекты
area:1 stroke 0xFF00FF00 1
+ fill 0xFFAAFFAA
line:1 stroke 0xFF0000FF 1
# точка:1 -- картинка и точка поверх
point:1 img ohotn.png 0.4
point:1 stroke 0xFFFF0000 3
# шаг5: текст
text:1 font 10 "DejaVu Sans:Bold:semicondensed:rgba=none"
+ write 0xFF0000FF
+ stroke 0xFFFFFFFF 4
# Тут используется свойство rotate_to. Все точечные
# объекты ориентируются по линии.
# площадной и линейный объекты
area:1 stroke 0xFF00FF00 1
+ fill 0xFFAAFFAA
line:1 stroke 0xFF0000FF 1
# точка:1 -- картинка
point:1 img ohotn.png 0.4
+ rotate_to 30 line:1
point:1 stroke 0xFFFF0000 3
+ rotate_to 30 line:1
# шаг5: текст
text:1 font 10 "DejaVu Sans:Bold:semicondensed:rgba=none"
+ write 0xFF0000FF
+ stroke 0xFFFFFFFF 4
# То же, но с картинками, нарисованными с помощью
# свойства lines вместо растровой картинки.
# площадной и линейный объекты
area:1 stroke 0xFF00FF00 1
+ fill 0xFFAAFFAA
line:1 stroke 0xFF0000FF 1
# точка:1 -- картинка
# ось x направлена вправо, ось y - вниз
point:1 stroke 0xFF000000 2
+ lines [[0,0],[0,10],[6,8],[0,6]]
point:1 stroke 0xFFFF0000 3
# шаг5: текст
text:1 font 10 "DejaVu Sans:Bold:semicondensed:rgba=none"
+ write 0xFF0000FF
+ stroke 0xFFFFFFFF 4
# площадной и линейный объекты
area:1 stroke 0xFF00FF00 1
+ fill 0xFFAAFFAA
line:1 stroke 0xFF0000FF 1
# точка:1 -- картинка
point:1 stroke 0xFF000000 2
+ lines [[0,0],[0,10],[6,8],[0,6]]
+ rotate_to 30 line:1
point:1 stroke 0xFFFF0000 3
+ rotate_to 30 line:1
# шаг5: текст
text:1 font 10 "DejaVu Sans:Bold:semicondensed:rgba=none"
+ write 0xFF0000FF
+ stroke 0xFFFFFFFF 4
# Точки дополнительно повернуты на фиксированный
# угол 10 градусов
# площадной и линейный объекты
area:1 stroke 0xFF00FF00 1
+ fill 0xFFAAFFAA
line:1 stroke 0xFF0000FF 1
# точка:1 -- картинка
point:1 stroke 0xFF000000 2
+ lines [[0,0],[0,10],[6,8],[0,6]]
+ rotate 10
point:1 stroke 0xFFFF0000 3
+ rotate 10
# шаг5: текст
text:1 font 10 "DejaVu Sans:Bold:semicondensed:rgba=none"
+ write 0xFF0000FF
+ stroke 0xFFFFFFFF 4
+ rotate 10
Привязка карты может быть установлена через конфигурационный файл (команда set_ref), из файла или по номенклатурному листу. При этом также устанавливается граница (которую потом можно нарисовать командой brd). Также, границу можно изменить командой set_brd, из файла с треком (трек может быть многосегментным).
Такая, установленная через конфигурационный файл привязка не обязательно будет использована для рисования карты: при отрисовке используется свой механизм преобразований в разные системы координат и ничто не мешает нарисовать карту в любой другой системе. Например, при рисовании карты через ms2render используется связка функций geo_mkref (задание привязки с помощью набора параметров) и write_geoimg - рисование картинки в соответствии с привязкой. По умолчанию используется собственная привязка карты, но ее можно поменять с помощью параметров --mkref. Отдельно можно добавить "внешнюю" границу с помощью переметров --border_wgs или --border_file. Можно использовать параметр --tmap или файл с расширением mbtiles, чтобы сгенерировать набор плиток (они, разумеется, рисуются в своей собственной системе координат).
При установке привязки через конфигурационный файл запоминается ее "естественный" масштаб, размер точки растра в метрах. Он важен при выборе толщины линий, размер шрифтов и т.п. Если карта рисуется в другой системе координат, то все эти величины будут перемасштабироваться. Кроме того, может быть удобно использовать параметр --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 - дополнительно обрезать все по внешней границе.