RU:MapCSS/0.2
MapCSS - это CSS-подобный язык для таблиц стилей карт.
На этой странице представлен второй вариант формата MapCSS. Смотрите MapCSS/0.1 для первого проекта, [[[Talk:MapCSS/0.2|страницe обсуждения]] и Предложения для предлагаемых улучшений. Существует список рассылки MapCSS.
Установите расширение VS Code, чтобы добавить визуальную подсветку для синтаксиса MapCSS и валидатора. Проверьте также BNF и грамматику antlr.
При вычислениях в MapCSS используется синтаксис оценки.
Структура языка
Таблица стилей MapCSS состоит из ряда правил, описывающих, как стилизовать элементы карты. Каждое правило состоит из двух частей:
- один или несколько селекторов, используемых для определения того, к каким элементам карты применима инструкция;
- одно или несколько объявлений, используемых для определения стиля, которын должны быть применены к соответствующим элементам.
Кроме того, можно добавлять комментарии, используя "//", чтобы закомментировать оставшуюся часть строки, или используя "/*" и "*/", чтобы закомментировать все, что находится между этими конечными точками.
Селекторы
Селекторы определяют, применимо ли правило к конкретному объекту или нет. Они могут проверять несколько параметров: тип объекта; уровень масштабирования при визуализации; теги, применяемые к объекту; псевдоклассы и классы, применяемые к объекту.
Типы
Типом селектора может быть любой из основных типов объектов OSM,
nodewayrelation
плюс еще несколько интересных кейсов,
area(способ, при котором начальная и конечная точка являются одной и той же точкой, или был установленarea=yes)line(способ, при котором начальная и конечная точка не являются одной и той же точкой, или был установленarea=no)canvas(фон для визуализации)*(любое из вышеперечисленных)
Тесты
Чтобы проверить, какие теги применяются к объекту, вы можете записать условие в квадратных скобках после типа объекта, в этих бинарных тестах может использоваться любой из этих операторов: =, !=, =~, >, <, >=, <=.
way[highway=primary] /* сопоставляется со всеми линиями с тегом highway' с установленным значением primary */ way[highway=~/.*ary/] /* сопоставляется со всеми линиями с тегом highway, соответствующими регулярному выражению .*ary */
Обратите внимание, что используемые здесь строки должны начинаться с буквы или символа '-' и содержать только буквы, цифры и символы '-'. Если вам нужно использовать имя тега или значение, содержащее какие-либо другие символы, строка должна быть заключена в кавычки:
way[highway="~/.*ary/"] /* сопоставляется со всеми линиями с тегом highway с установленным значениеь ~/.*ary/ (не является регулярным выражением). */ way[highway='a"b'] /* сопоставляется со всеми линиями с тегом highway с установленным значением a"b */ way[highway="a\"b"] /* сопоставляется со всеми линиями с тегом highway с установленным значением a"b */
Вы также можете использовать унарные тесты, чтобы узнать, установлен тег или нет:
way[highway] /* сопоставляется со всеми линиями с установленным тегом highway */ way[!highway] /* сопоставляется со всеми линиями, для которых не установлен тег highway (или установлено значение no/false). */ way.highway /* сопоставляется со всеми линиями с установленным классом тега highway */
Чтобы протестировать более одного условия для пути, просто добавьте дополнительные условия после типа. Для соответствия этому правилу должны быть выполнены все условия.
node[place=city][population<50000] /* сопоставляется со всеми точками, помеченными тегом place=city, значение тега population которых меньше 50000 */ node[place=city][population>=50000] /* сопоставляется со всеми точками, помеченными тегом place=city, значение тега population которых больше или равно 50000 */
Вы можете ограничить действие правил только теми элементами, которые отображаются при определенных уровнях масштабирования. Если это не указано, правило применяется ко всем уровням масштабирования:
way|z12[population<50000] /* сопоставляется со всеми линиями, у которых тег population имеет значение менее 50000, при условии, что средство визуализации в данный момент работает с уровнем масштабирования 12 */ way|z1-11[population>50000] /* сопоставляется со всеми линиями, у которых тег population имеет значение менее 50000, при условии, что средство визуализации в данный момент работает с любым уровнем масштабирования между 1 и 11 */
Теоретически это можно было бы расширить, чтобы использовать другие единицы измерения, например, way|s50000 для печатной карты формата 1:50000.
Комбинирование селекторов
Вы можете создать условие ИЛИ, сгруппировав селекторы через запятую:
way[highway=primary], way[highway=trunk] /* сопоставляется со всеми линиями с тегом highway, установленной в значение primary или trunk */
Группируя селекторы без запятой между ними, вы создаете селектор-потомок. Это соответствует последнему селектору, если и только если объект найден как часть другого объекта, соответствующего первому селектору:
way[highway=footpath] node[barrier=gate] /* сопоставляется с точкой с установленным barrier=gate, которые находятся на линиях с установленным highway=footpath */ relation[type=route] way[highway] /* сопоставляется с линиями с установленным тегом highway, которые находятся в отношении с установленным type=route */
При подобном объединении селекторов к элементам добавляются псевдотеги, позволяющие получить доступ к дополнительным данным. Здесь псевдотег role добавляется к объекту way, чтобы указать его роль в родительском отношении:
relation[type=route] way[role=proposed] /* сопоставляет линии внутри отношения с установленным type=route, с тегом role с установленным значением proposed */
(это пока не поддерживается Halcyon и Overpass Tubo. Также предлагается другой синтаксис, использующий дочерние селекторы ">" между элементом relation и дочерним элементом child, без добавления какого-либо псевдотега в дочерний элемент)
Синтаксические примечания
Пробелы в селекторах имеют большое значение
Вы можете быть снисходительны к тому, как мы относимся к пробелам. Количество пробелов не имеет значения (1 пробел по сравнению с тремя символами табуляции, CR и пробелом), но наличие или отсутствие пробелов в селекторах имеет значение. Это означает, что мы можем, например, записать приведенный выше селектор следующим образом:
relation[type=route] way[highway]
Но если бы мы написали его так (с пробелом между типом объекта и тестами), он бы не разобрался:
relation [type=route] way [highway]
Поддержка различных библиотек для вышеприведенных селекторов
| Selector-Part | Пример | JOSM | pgm |
|---|---|---|---|
| Type | node, way, relation, area, line, canvas, *
|
+[1] | + |
| Tag match | way[highway=primary]
|
+ | + |
| Tag match (quoted) | way["highway"="primary"]
|
+ | + |
| Tag regexp match | way[highway=~/.ary/]
|
+ | + |
| Tag is set? | way[highway]
|
+ | + |
| Tag is not set? | way[!highway]
|
+ | + |
| Class is set? | way.highway
|
+ | + |
| Numeric comparision | node[population<50000]
|
+ | + |
| Zoom selector | node|z12-
|
+ | + |
| Link selector, relation members | relation member
|
+ [2] | + |
| Link selector, way nodes | way node
|
+ [2] | + |
| Comment block style | /* ... */ | + | + |
| Comment inline style | // ... | - | + |
Декларация
Декларации записываются путем заключения набора спецификаторов стиля в фигурные скобки:
{
opacity: 0.5;
color: rgb(1.0, 0.0, 0.0);
}
Смотрите раздел #Vocabulary для получения списка всех доступных спецификаторов и того, какие средства визуализации их поддерживают.
Декларации также могут использоваться для установки значений определенных тегов для объекта:
{ set tag=value; } /* установить для tag */
{ set tag; } /* установить для tag значение yes */
Наконец, вы можете вычислить значения, используя инструкцию eval:
{ opacity: eval("tag('population')/100000"); }
{ set width_in_metres=eval("tag('lanes')*3"); }
Классы
Вы можете установить теги, начинающиеся с полной точки, для имитации классов:
{ set .minor_road; }
Затем вы можете использовать тест .minor_road (как указано выше) в селекторе:
way.minor_road
Это открывает новые возможности при использовании правила @import и типа носителя. У вас может быть набор правил для каждого носителя (например, непосредственно из базы данных OSM или из продукта osm2pgsql), каждое из которых устанавливает псевдоклассы. Затем к этим стилям применяется основная таблица стилей:
@import url("osmtags.css") osmtags;
@import url("osmpostgis.css") osmpostgis;
(Правило @import еще не поддерживается Halcyon.)
Псевдоклассы
Интерактивные клиенты могут поддерживать псевдоклассы :hover и :active.
Поддержка различных библиотек для различных деклараций
| Описание | Примеры | JOSM | pgm |
|---|---|---|---|
| Назначить свойство | opacity: 0.5;
|
+ | + |
| Установить tag в значение value | set tag=value;
|
- | + |
| Установить tag в значение yes | set tag;
|
-[1] | + |
| Назначить вычисление | width: eval(2*3)
|
+ | + |
| Установить класс | set .class;
|
+ | + |
Объявить @import |
@import url("tags.css");
|
- | + |
Псевдокласс из объявленого @import |
@import url("tags.css") osmtags;
|
- | - |
Псевдокласс :hover |
way:hover
|
- | - |
Псевдокласс :active |
way:active
|
- | - |
- ↑ устанавливает не tag, а класс вместо него
Vocabulary
The following abbreviations will be used:
- OSPad: OpenStreetPad
- pgm: pgmapcss
Canvas properties
| definition | example | Halcyon | Kothic | Ceyx | OSPad | alaCarte | JOSM | pgm | |
|---|---|---|---|---|---|---|---|---|---|
antialiasing
|
How to antialias map: full (default), text (lines aren't smooth, text is), none (no antialiasing performed)
|
- | - | +* | - | - | - | - | |
fill-color
|
Colour of the canvas - either a 3-digit or 6-digit hex value or a CSS colour name or an rgb colour specifier | fill-color: lightgreenfill-color: #8F8fill-color: #88FF88fill-color: rgb(0.53, 1, 0.53)
|
- | + | + | + | + | + [1] | + |
| Colour of the canvas with alpha component - an 8-digit hex value, or an rgba colour specifier (CSS level 3) (the alpha component normally combines with the transparency attribute when supported simultaneously). |
fill-color: #88FF8880fill-color: rgba(0.53, 1, 0.53, 0.5)
|
? | ? | ? | ? | + | ? | + | |
fill-opacity
|
How transparent the fill is, from 0 (transparent) to 1 (opaque) | fill-opacity: 0.2
|
- | + | + | + | - [2] | - | - [3] |
fill-image
|
The URL (absolute or relative) of an image with which to fill the canvas | fill-image: url('fills/grass.png')
|
- | - | + | + | + | - | + |
Line properties
| definition | example | Halcyon | Kothic | Ceyx | OSPad | alaCarte | JOSM | pgm | |
|---|---|---|---|---|---|---|---|---|---|
z-index
|
Specifies a sublayer within an OSM layer | +[1] | + | + | + | + | + | + | |
width
|
The line width in pixels. | width: 5
|
+ | + | + | + | + | + | + |
color
|
Colour of the line - a 3-digit or 6-digit hex value, a CSS colour name or an rgb colour specifier | color: bluecolor: #00Fcolor: #0000FFcolor: rgb(0.0, 0.0, 1.0)
|
+ | + | + | + | + | + | + |
| Colour of the line with alpha component - an 8-digit hex value, or an rgba colour specifier (CSS level 3) (the alpha component normally combines with the transparency attribute when supported simultaneously). |
color: #0000FF80color: rgba(0.0, 0.0, 1.0, 0.5)
|
? | ? | ? | ? | + | ? | ? | |
opacity
|
How transparent the line is, from 0 (transparent) to 1 (opaque) | opacity: 0.5
|
+ | + | + | + | - [2] | + | + |
dashes
|
An array of alternating on/off lengths | dashes: 2,2,4,2
|
+ | + | + | + | + | + | + |
image
|
The URL of an image to use for filling the line | - | + | - | + | + | - | + | |
linecap
|
The style for the end of the line: none (default), round or square
|
+ | + | + | + | + | + | + | |
linejoin
|
The style for line corners: round (default), miter or bevel
|
+ | + | + | + | + | + | + | |
fill-color
|
Colour in which to fill the area, if closed - hex value or CSS colour | fill-color: lightgreen
|
+ | + | + | + | + | + | + |
fill-opacity
|
How transparent the fill is, from 0 (transparent) to 1 (opaque) | fill-opacity: 0.2
|
+ | + | + | + | - [2] | + | + |
fill-image
|
The URL (absolute or relative) of an image with which to fill the area | fill-image: url('fills/grass.png')
|
+ | + | + | + | + | + | + |
casing-width
|
Width of the casing (border) of the line. For example, a 1 pixel wide casing on either side would be specified as casing-width:1 (change from MapCSS 0.1)
|
casing-width: 3
|
- | + | + | + | + | + | + |
casing-color
|
The colour (hex or CSS name) of the casing | + | + | + | + | + | + | + | |
casing-opacity
|
The transparency of the casing | + | + | + | + | - [2] | + | + | |
casing-dashes
|
An array of alternating on/off lengths | + | + | + | + | + | + | + | |
casing-linecap
|
Style for the end of the casing line (defaults to value of linecap)
|
- | + | + | + | + | + | + | |
casing-linejoin
|
The style for casing line corners (defaults to value of linejoin)
|
- | + | + | + | + | + | + | |
extrude
|
Height of extruded line. | extrude: eval('zmetric(tag("height"))')
|
- | + | - | - | - | - | - |
extrude-edge-color
|
Color of edges of 3D object (defaults to value of color)
|
- | + | - | - | - | - | - | |
extrude-edge-opacity
|
Opacity of extruded edges (defaults to value of opacity)
|
- | + | - | - | - | - | - | |
extrude-face-color
|
Color of extruded faces (defaults to value of fill-color)
|
- | + | - | - | - | - | - | |
extrude-face-opacity
|
How transparent extruded faces are (defaults to value of fill-opacity)
|
- | + | - | - | - | - | - |
Point/icon properties
These can apply to nodes or to areas (closed ways). In case of areas, it is up to the renderer to decide where to place the icon within the area.
| definition | example | Halcyon | Kothic | Ceyx | OSPad | alaCarte | JOSM | pgm | |
|---|---|---|---|---|---|---|---|---|---|
icon-image
|
URL (absolute or relative) of an image to use as an icon. | icon-image: url('icons/pharmacy.png')
|
+ | - | +* | + | + | +[1] | + |
icon-width
|
Either a unit specification or a scaling facor in %. If only one of icon-width and icon-height is given, a aspect-ratio-preserving scaling is applied in both directions.
|
icon-width: 25, icon-width: 70%
|
- | - | - | + | + | +[2] | - |
icon-height
|
Either a unit specification or a scaling facor in %. If only one of icon-width and icon-height is given, a aspect-ratio-preserving scaling is applied in both directions.
|
icon-height: 25; icon-height: 70%
|
- | - | - | + | + | +[2] | - |
icon-opacity
|
Opacity of the icon image | icon-opacity: 0.3
|
- | - | - | + | + | + | + |
- ↑ slightly different syntax than shown here, see JOSM/Help/Styles/Images
- ↑ 2.0 2.1 only absolute number of pixels, no percentage
Label properties
| definition | example | Halcyon | Kothic | Ceyx | OSPad | alaCarte | JOSM | pgm | |
|---|---|---|---|---|---|---|---|---|---|
font-family
|
Name of the font to use | font-family: DejaVu
|
+ | - | + | + | + | + | +[1] |
font-size
|
Size of the text (integer number) | font-size: 12
|
+ | + | + | + | + | + | + |
font-weight
|
bold or normal
|
font-weight: bold
|
+ | - | + | + | + | + | + |
font-style
|
italic or normal
|
font-style: italic
|
+ | - | + | + | + | + | + |
font-variant
|
normal (default) or small-caps (new in MapCSS 0.2)
|
font-style: small-caps
|
- | - | +* | - | - | - | - |
text-decoration
|
none or underline
|
text-decoration: underline
|
+ | - | + | + | - | - | - |
text-transform
|
none, uppercase, lowercase or capitalize
|
text-transform: uppercase
|
+ | - | + | + | - | - | + |
text-color
|
A hex value or CSS colour name | text-color: #07CF20
|
+ | + | + | + | + | + | + |
text-opacity
|
How transparent the text is, from 0 (transparent) to 1 (opaque) | text-opacity: 0.75
|
- | - | - | + | - [2] | + | + |
text-position
|
Whether the text follows the path of the way (line) or is centred on the area (center)
|
text-position: center
|
+ | + | - | + | + | + | + |
text-offset
|
The vertical offset from the centre of the way or point. An offset of 5, on a line of width 3, would put the text "along" the line rather than within it. Similarly, an offset of 8, on a point with a 16-high icon, would put the text below the icon. | text-offset: -5
|
+ | - | + | + | + | + | + |
max-width
|
The maximum width of a text label for a point, after which it should wrap onto the next line | max-width: 30
|
+ | - | +* | + | - | - | + |
text
|
The tag key whose value is used for the label. For example, text: name would render the name tag
|
text: name
|
+ | + | + | + | + | + | + |
text-halo-color
|
The colour (hex or CSS) of the 'halo' or 'pull-out' used to make the text stand out from features underneath it | text-halo-color: white
|
+ | + | + | + | + | + | + |
text-halo-radius
|
The radius of the halo | text-halo-radius: 2
|
+ | + | + | + | + | + | + |
Shield properties
| definition | example | Halcyon | Kothic | Ceyx | alaCarte | JOSM | pgm | |
|---|---|---|---|---|---|---|---|---|
shield-color
|
Colour of the shield - either a hex value or a CSS colour name | shield-color: blueshield-color: #0000FF
|
- | - | - | + | - | - |
shield-opacity
|
How transparent the shield is, from 0 (transparent) to 1 (opaque) | shield-opacity: 0.5
|
- | - | - | + | - | + |
shield-frame-color
|
Color of shield's frame | - | - | - | + | - | - | |
shield-frame-width
|
Width of the frame. If 0, no frame is rendered | - | - | - | + | - | - | |
shield-casing-color
|
Color of shield's casing. | - | - | - | + | - | - | |
shield-casing-width
|
Width of shield's casing | - | - | - | + | - | - | |
shield-text
|
Text to render on shield. | - | - | - | + | - | + | |
shield-image
|
The URL (absolute or relative) of an image to use as a background for text. | fill-image: url('fills/grass.png')
|
- | - | - | + | - | + |
shield-shape
|
Shape of the shield. Can be rounded or rectangular
|
- | - | - | + | - | - |
Application of Styles
Rendered Objects
Only ways and nodes should be rendered. Relations should be used only for applying a different style to a way or node. For example, to colour a route red, you could use the following style:
relation[type=route] way[highway] { color: red; }
But not this style:
relation[type=route] { color: red; }
The one possible exception to this rule is multipolygon relations, which some renderers may interpret as area primitives.
Rendering Order
Objects should be rendered in the following order (from front to back):
- Objects with lower layer should always be rendered first.
- Within a layer, first all fills are rendered, then all casings, then all strokes, then all icons and labels.
- Within each of those categories, objects are ordered according to z-index.
- If all of the above are equal, the order is undefined.
Support of the different libraries for the rendering order
| Description | JOSM | pgm |
|---|---|---|
| Use layer of objects for rendering order | - | + |
| within a layer, render fills then casings then strokes then icons and labels | + | +[1] |
- ↑ pgmapcss ignores the layer for icons and labels and renders them on top of everything else.
Order of Application
A stylesheet describes how to determine the style for any given way or node. To determine the style you must step through rules in order determining whether they apply to any given way or note, if a later rule provides a contradictory style to an earlier one, the later style overwrites the old one. Note, this means it is not valid to process descendant selectors at the time that the parent is matched, as this can lead to the incorrect style being generated as shown below:
Take for example the following style sheet:
node
{
width: 2;
color: blue;
}
way node
{
width: 2;
color: red;
}
Applied to the following objects (most details omitted for conciseness):
<way id="1"> <nd id="2" /> </way> <node id="2" />
The correct style here is for the way not to be rendered, and for the node to be rendered as a 2px wide red dot. If we were to process descendant selectors at the time the parent would match we would instead, process the way, and add the 2px wide red dot style to the node, then process the node and incorrectly override red with blue.
