RU:MapCSS/0.2

From OpenStreetMap Wiki
Jump to navigation Jump to search

MapCSS - это CSS-подобный язык для таблиц стилей карт.

На этой странице представлен второй вариант формата MapCSS. Смотрите MapCSS/0.1 для первого проекта, [[[Talk:MapCSS/0.2|страницe обсуждения]] и Предложения для предлагаемых улучшений. Существует список рассылки MapCSS.

Установите расширение VS Code, чтобы добавить визуальную подсветку для синтаксиса MapCSS и валидатора. Проверьте также BNF и грамматику antlr.

При вычислениях в MapCSS используется синтаксис оценки.


Структура языка

Таблица стилей MapCSS состоит из ряда правил, описывающих, как стилизовать элементы карты. Каждое правило состоит из двух частей:

  • один или несколько селекторов, используемых для определения того, к каким элементам карты применима инструкция;
  • одно или несколько объявлений, используемых для определения стиля, которын должны быть применены к соответствующим элементам.

Кроме того, можно добавлять комментарии, используя "//", чтобы закомментировать оставшуюся часть строки, или используя "/*" и "*/", чтобы закомментировать все, что находится между этими конечными точками.

broom icon

Эта страница предлагается для очистки. Пожалуйста посетите страницу страницу обсуждения.
Термин "селектор" на самом деле означает "правило", а "тест" - "селектор". Смотрите [1]. Пожалуйста, обновите все соответствующие страницы. Смотрите также Грамматика CSS2.1 и Кандидат на CSS3


Селекторы

Селекторы определяют, применимо ли правило к конкретному объекту или нет. Они могут проверять несколько параметров: тип объекта; уровень масштабирования при визуализации; теги, применяемые к объекту; псевдоклассы и классы, применяемые к объекту.


Типы

Типом селектора может быть любой из основных типов объектов OSM,

  • node
  • way
  • relation

плюс еще несколько интересных кейсов,

  • 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 // ... - +
  1. все, кроме line
  2. 2.0 2.1 начиная с r7166

Декларация

Декларации записываются путем заключения набора спецификаторов стиля в фигурные скобки:

{
   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 - -
  1. устанавливает не tag, а класс вместо него

Vocabulary

The following abbreviations will be used:

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: lightgreen
fill-color: #8F8
fill-color: #88FF88
fill-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: #88FF8880
fill-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') - - + + + - +
  1. since version 7110, called background-color before
  2. But opacity is supported as alpha component of corresponding color attribute (e.g. fill-color: #FF000080" implies fill-opacity: 0.5)
  3. You may set an alpha channel on the fill-color instead, e.g fill-color: #FF000080"

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: blue
color: #00F
color: #0000FF
color: 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: #0000FF80
color: 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) - + - - - - -
  1. Halcyon supports values of 0-10
  2. 2.0 2.1 2.2 But opacity is supported as alpha component of corresponding color attribute (e.g. fill-color: #FF000080" implies fill-opacity: 0.5)

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 - - - + + + +
  1. slightly different syntax than shown here, see JOSM/Help/Styles/Images
  2. 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 + + + + + + +
  1. List of supported fonts is hard-coded
  2. But opacity is supported as alpha component of corresponding color attribute (e.g. fill-color: #FF000080" implies fill-opacity: 0.5)

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: blue
shield-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):

  1. Objects with lower layer should always be rendered first.
  2. Within a layer, first all fills are rendered, then all casings, then all strokes, then all icons and labels.
  3. Within each of those categories, objects are ordered according to z-index.
  4. 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]
  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.