Changes between Initial Version and Version 1 of Ru:Help/Styles/MapCSSImplementation


Ignore:
Timestamp:
2018-03-30T09:01:12+02:00 (7 years ago)
Author:
ak099
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Ru:Help/Styles/MapCSSImplementation

    v1 v1  
     1[[TranslatedPages(revision=146,outdated=Страница в процессе перевода)]]
     2[[PageOutline(1-10,Содержание)]]
     3Эта страница документирует подробности реализации языка [osmwiki:MapCSS/0.2 MapCSS] в JOSM. Он используется в следующих элементах JOSM:
     4
     5* [wikitr:/Styles Стили отрисовки карты]
     6* [wikitr:/Rules Правила валидатора]
     7* [wikitr:/Help/Action/Search Диалог поиска]
     8
     9== Общая структура ==
     10Таблица стилей MapCSS содержит правила в следующей форме:
     11{{{
     12#!mapcss
     13selector {
     14    prop: value;
     15    /* ... */
     16    prop: value;
     17    /* and/or */
     18    set: class;
     19    set: .class;
     20}
     21}}}
     22Алгоритм поиска стилей для заданного объекта таков:
     23{{{
     24 - для каждого правила:
     25     если селектор применим к объекту, задать свойства из блока { }
     26 - проанализировать последний список свойств и сгенерировать стили из него
     27}}}
     28
     29MapCSS использует формат '''комментариев''' из CSS (`/* ... */`). Заметьте, что при комментировании больших частей файла MapCSS некоторые конструкции могут вызвать непредвиденный конец комментария, например:
     30{{{
     31#!mapcss
     32/*
     33*[highway][name =~ /^R(\.|:)? .*/] { /* группа символов в конце регулярного выражения приводит к непредвиденному завершению комментария */
     34        throwWarning: tr("foo");
     35}
     36*/
     37}}}
     38
     39== Селекторы ==
     40''Селекторы'' — это выражения для фильтрации правил MapCSS. Правило применяется к объекту карты, только если его селектор соответствует объекту.
     41
     42Селекторы в MapCSS отличаются от стандартных в CSS для WWW. MapCSS поддерживает лишь подмножество стандартных селекторов CSS, но в него добавлены дополнительные селекторы, требующиеся для данных OSM.
     43
     44Некоторые простые примеры:
     45{{{
     46#!mapcss
     47/* применяется к линиям с тегом highway=residential */
     48way[highway=residential] {  /*  the styles */}
     49
     50/* применяется к новым замкнутым линиям на слое 1, если они имеют тег amenity=parking и access=public, и если
     51 * уровень масштаба в диапазоне от 11 до 14
     52 */
     53way|z11-14[amenity=parking][access=public]:closed:new::layer_1 {...}
     54
     55
     56area[amenity=parking][access=public], area[amenity=parking][!access] {...}
     57relation[type=route][route=foot] > way::relation_underlay {..}
     58}}}
     59
     60
     61Другие элементы ('''type'''-, '''zoom'''- , '''condition''' selector, '''pseudo classes''', '''layer identifier''', '''grouping''' и '''child combinator''') поясняются ниже.
     62
     63
     64=== Селектор Type ===
     65
     66{{{#!th align=left valign=top
     67'''Selector'''
     68}}}
     69{{{#!th align=left valign=top
     70'''Description'''
     71}}}
     72|-------------------------------------------------------------------------------
     73{{{#!td align=left  valign=top
     74*
     75}}}
     76{{{#!td align=left  valign=top   
     77Matches with any object
     78}}}
     79|-------------------------------------------------------------------------------
     80{{{#!td align=left  valign=top
     81{{{node}}}, {{{way}}}, {{{relation}}}
     82}}}
     83{{{#!td align=left  valign=top   
     84Matches with the osm objects of the given type.
     85}}}
     86|-------------------------------------------------------------------------------
     87{{{#!td align=left  valign=top
     88{{{area}}}
     89}}}
     90{{{#!td align=left  valign=top   
     91Matches with any area regardless of whether the area border is only modelled with a single way or with a set of ways glued together with a relation.
     92{{{
     93#!mapcss
     94area[natural=beach] {...}
     95/* ... is equal to ... */
     96way[natural=beach], relation[type=multipolygon][natural=beach] {...}
     97}}}
     98Note that {{{area}}} selects unclosed ways as well, so it may be useful to add the {{{:closed}}} pseudo class. The JOSM Validator will give a warning for unclosed ways that have an area style.
     99}}}
     100|-------------------------------------------------------------------------------
     101{{{#!td align=left  valign=top
     102{{{meta}}}
     103}}}
     104{{{#!td align=left  valign=top   
     105The {{{meta}}} selector starts a special rule that should stand at the beginning of the file. It gives some general information on the style sheet. All software that supports MapCSS should be able to parse this sections without errors, so do not use exotic syntax extensions in this part.
     106{{{
     107#!mapcss
     108meta {
     109    title: "Parking lanes";   /* title shown in the menu */
     110    icon: "images/logo.png";  /* small icon shown in the menu next to the title */
     111    version: "1.2";           /* the version of the style */
     112    description: "...";       /* one or two sentences of describing the style */
     113    author: "...";            /* the author(s) of the style */
     114    link: "http://...";       /* URL to the web page of the style */
     115    min-josm-version: 6789;   /* the minimum JOSM version where this style works */
     116}
     117}}}
     118}}}
     119|-------------------------------------------------------------------------------
     120{{{#!td align=left  valign=top
     121{{{canvas}}}
     122}}}
     123{{{#!td align=left  valign=top   
     124Some style information not specific to nodes, ways or relations.
     125{{{
     126#!mapcss
     127canvas {
     128    fill-color: #ffffea; /* the former background-color is deprecated since r7110 */
     129    default-points: false;
     130    default-lines: false;
     131}
     132}}}
     133{{{#!th
     134'''Key'''
     135}}}
     136{{{#!th
     137'''Description'''
     138}}}
     139{{{#!th
     140'''Value Format'''
     141}}}
     142{{{#!th
     143'''Default Value'''
     144}}}
     145|-
     146{{{#!td
     147{{{fill-color}}}
     148}}}
     149{{{#!td
     150Specifies the overall fill/background color (`background-color` is deprecated since r7110).
     151}}}
     152{{{#!td
     153''Color''
     154}}}
     155{{{#!td align=center
     156{{{black}}}
     157}}}
     158|-
     159{{{#!td
     160{{{default-points}}}
     161}}}
     162{{{#!td
     163Whether default point style should be added to nodes where no style applies.
     164}}}
     165{{{#!td
     166''Boolean''
     167}}}
     168{{{#!td align=center
     169{{{true}}}
     170}}}
     171|-
     172{{{#!td
     173{{{default-lines}}}
     174}}}
     175{{{#!td
     176Whether default line style should be added to ways where no style applies.
     177}}}
     178{{{#!td
     179''Boolean''
     180}}}
     181{{{#!td align=center
     182{{{true}}}
     183}}}
     184}}}
     185
     186=== Child selector ===
     187If a node is part of a way, we say that it is a ''child'' of this way. Similarly, if a node, a way, or a relation is a member of a relation, we say, that it is a ''child'' of this relation.
     188
     189In MapCSS you can use a '''child selector''' which matches only if both the parent and the child object match.
     190
     191Example:
     192{{{
     193#!mapcss
     194/*
     195 * only matches for a way which is a child of a relation with tags
     196 * type=route and route=foot
     197 */
     198relation[type=route][route=foot] > way {...}
     199}}}
     200
     201Notes:
     202* Zoom selector and Layer identifier are only relevant for the part to the right of the > sign.
     203* The functions ''prop()'' and ''is_prop_set()'' are only supported on the right side of the > sign.
     204* The functions ''parent_tag'' and ''parent_tags'' (see below) can be used to access tags from the parent(s).
     205* For compatibility with the MapCSS 0.2 standard, `relation[type=route][route=foot] way {/*...*/}`, without the greather-than-sign `>` is supported, too. However, no [[#Linkselector]] may be specified in this case.
     206
     207
     208=== Parent selector ===
     209In addition to child selectors, JOSM supports the notion of a '''parent selector'''. Note, that parent selectors are a JOSM-specific extension of MapCSS not present in other MapCSS implementations.
     210
     211Similar to a child selector, a parent selector only matches if both the parent and the child object match. In contrast to the child selector, the character < is used.
     212
     213In contrast to the child selector, the parent object will be "selected". In other words, the properties in the {{{{...}}}}-Declaration Block apply to the object on the right hand side of the "<" sign.
     214
     215Example:
     216{{{
     217#!mapcss
     218/*
     219 * matches for a highway which has at least one node tagged as traffic_calming=*
     220 */
     221node[traffic_calming] < way[highway] {...}
     222}}}
     223
     224=== Condition selector ===
     225Selectors can include a set of conditions. If any of these conditions evaluates to false, the selector doesn't match and the style
     226rule isn't applied.
     227
     228An '''attribute condition''' specifies a condition on a tag of an OSM object.
     229
     230[=#condition_selector_operators]
     231{{{#!th align=left valign=top
     232'''Operator'''
     233}}}
     234{{{#!th align=left valign=top
     235'''Description'''
     236}}}
     237{{{#!th align=left valign=top
     238'''Example'''
     239}}}
     240|-------------------------------------------------------------------------------
     241{{{#!td align=left  valign=top
     242`=`
     243}}}
     244{{{#!td align=left  valign=top   
     245Exact match of the value.
     246}}}
     247{{{#!td align=left  valign=top   
     248{{{
     249#!mapcss
     250way[highway=residential]                   /* without quotes always case insensitive */
     251node[name="My name"]                       /* use quotes for if value includes spaces or if case sensitive matching is important */
     252node["MY_Special_TAG"="another value"]     /* use quotes for tag names if case sensitive matching is required */
     253node["ÖPVN"=tram]                          /* use quotes for tag keys with special characters */
     254                                           /*   note that these are not common in OSM at the moment */
     255}}}
     256}}}
     257|-------------------------------------------------------------------------------
     258{{{#!td align=left  valign=top
     259`!=`
     260}}}
     261{{{#!td align=left  valign=top   
     262Value not equal
     263}}}
     264{{{#!td align=left  valign=top   
     265{{{
     266#!mapcss
     267way[highway!=residential]                   /* without quotes always case insensitive */
     268node[name!="My name"]                       /* use quotes if value includes spaces or if case sensitive matching is important */
     269node["MY_Special_TAG"!="another value"]     /* use quotes for tag names if case sensitive matching is required */
     270node["name:fr"!="mon nome"]                 /* use quotes for tag names with special characters like colons*/
     271}}}
     272}}}
     273|-------------------------------------------------------------------------------
     274{{{#!td align=left  valign=top
     275`<`, `>`, `<=`, `>=`
     276}}}
     277{{{#!td align=left  valign=top   
     278Comparision for numeric values.
     279
     280}}}
     281{{{#!td align=left  valign=top   
     282{{{
     283#!mapcss
     284node[population >= 50000]                   /* population greater than or equal to 50000 */
     285node[ele = 3000]                            /* elevation with exactly 3000 meters */
     286}}}
     287}}}
     288|-------------------------------------------------------------------------------
     289{{{#!td align=left  valign=top
     290{{{^=}}}
     291}}}
     292{{{#!td align=left  valign=top   
     293Prefix match
     294}}}
     295{{{#!td align=left  valign=top   
     296{{{
     297#!mapcss
     298node[name ^= "myprefix"]                    /* value starts with 'myprefix' */
     299}}}
     300}}}
     301|-------------------------------------------------------------------------------
     302{{{#!td align=left  valign=top
     303`$=`
     304}}}
     305{{{#!td align=left  valign=top   
     306Postfix match
     307}}}
     308{{{#!td align=left  valign=top   
     309{{{
     310#!mapcss
     311node[name $= "mypostfix"]                   /* value ends with 'mypostfix' */
     312}}}
     313}}}
     314|-----------------------------------------------
     315{{{#!td align=left  valign=top
     316`*=`
     317}}}
     318{{{#!td align=left  valign=top   
     319Substring match
     320}}}
     321{{{#!td align=left  valign=top   
     322{{{
     323#!mapcss
     324node[name *= "my substring"]                 /* value contains the substring 'my substring' */
     325}}}
     326}}}
     327|-------------------------------------------------------------------------------
     328{{{#!td align=left  valign=top
     329`~=`
     330}}}
     331{{{#!td align=left  valign=top   
     332List membership
     333}}}
     334{{{#!td align=left  valign=top   
     335{{{
     336#!mapcss
     337*[vending~=stamps]                          /* the tag value for the tag 'vending' consists of a list of ;-separated values    */
     338                                            /* and one of these values is 'stamps'                                             */
     339}}}
     340}}}
     341|-------------------------------------------------------------------------------
     342{{{#!td align=left  valign=top
     343`=~`
     344}}}
     345{{{#!td align=left  valign=top   
     346[https://download.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html#sum Regular expression] match
     347
     348}}}
     349{{{#!td align=left  valign=top   
     350{{{
     351#!mapcss
     352*[name=~/^My_pattern.*/]                    /* the value of the tag 'name' matches with the regular expression '^My_pattern.*' */
     353                                            /* Note, that reqular expressions have to be enclosed in /.../                     */                 
     354}}}
     355Case-insensitive matching can be enabled via the embedded flag expression `(?i)` (see [https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#CASE_INSENSITIVE Pattern.CASE_INSENSITIVE]).
     356{{{
     357#!mapcss
     358*[name =~ /^(?U)(\p{Lower})+$/]              /* name consists of only lower case unicode characters */                 
     359}}}
     360}}}
     361|-------------------------------------------------------------------------------
     362{{{#!td align=left  valign=top
     363`!~` (since r6455)
     364}}}
     365{{{#!td align=left  valign=top   
     366negated [https://download.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html#sum Regular expression] match
     367
     368}}}
     369{{{#!td align=left  valign=top   
     370{{{
     371#!mapcss
     372*[surface!~/paved|unpaved/]
     373}}}
     374}}}
     375|-------------------------------------------------------------------------------
     376{{{#!td align=left  valign=top
     377`∈` ([http://www.fileformat.info/info/unicode/char/2208/index.htm U+2208], since r6609)
     378}}}
     379{{{#!td align=left  valign=top   
     380element of
     381
     382}}}
     383{{{#!td align=left  valign=top   
     384{{{
     385#!mapcss
     386node[amenity=parking] ∈ *[amenity=parking] {
     387  throwWarning: tr("{0} inside {1}", "amenity=parking", "amenity=parking");
     388}
     389}}}
     390}}}
     391|-------------------------------------------------------------------------------
     392{{{#!td align=left  valign=top
     393`⧉` ([http://www.fileformat.info/info/unicode/char/29c9/index.htm U+29C9], since r6613)
     394}}}
     395{{{#!td align=left  valign=top   
     396crossing
     397
     398}}}
     399{{{#!td align=left  valign=top   
     400{{{
     401#!mapcss
     402area:closed:areaStyle ⧉ area:closed:areaStyle {
     403  throwOther: tr("Overlapping Areas");
     404}
     405}}}
     406takes `layer` tag into account if set (since r12986)
     407}}}
     408
     409Since r6554, it is possible to prefix the "value" (i.e., expression after the operator) with a `*` in order to "de-reference" it (i.e., obtain consider it as another key and obtain its value). Thus, `[key1 = *key2]` or `[key1=*key2]` compares the value of `key1` with the value of `key2`, and `[key =~ */pattern/]` considers the value of the key `pattern` as a regular expression and matches it against the value of `key`.
     410
     411In addition, you can test whether a tag is present or not:
     412
     413{{{#!th align=left valign=top
     414'''Condition'''
     415}}}
     416{{{#!th align=left valign=top
     417'''Example'''
     418}}}
     419|-------------------------------------------------------------------------------
     420{{{#!td align=left  valign=top
     421Presence of tag
     422}}}
     423{{{#!td align=left  valign=top   
     424{{{
     425#!mapcss
     426way[highway]                     /* matches any way with a tag 'highway'                                              */
     427way["VALSOU"]                    /* use quotes if case sensitive matching is required                                 */
     428way["name:fr"]                   /* use quotes if the tag name includes special caracters (white space, colons, etc.) */
     429}}}
     430}}}
     431|-------------------------------------------------------------------------------
     432{{{#!td align=left  valign=top
     433Absence of tag
     434}}}
     435{{{#!td align=left  valign=top   
     436{{{
     437#!mapcss
     438way[!highway]                     /* matches any way which does not have a tag 'highway'                               */
     439way[!"VALSOU"]                    /* use quotes if case sensitive matching is required                                 */
     440way[!"name:fr"]                   /* use quotes if the tag name includes special caracters (white space, colons, etc.) */
     441}}}
     442}}}
     443|-------------------------------------------------------------------------------
     444{{{#!td align=left  valign=top
     445Presence of tag by [https://download.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html#sum Regular expression] match (since r6547)
     446}}}
     447{{{#!td align=left  valign=top   
     448{{{
     449#!mapcss
     450way[/^addr:/]                     /* matches any `addr:*` key */
     451}}}
     452}}}
     453|-------------------------------------------------------------------------------
     454{{{#!td align=left  valign=top
     455Absence of tag by Regular expression match
     456}}}
     457{{{#!td align=left  valign=top   
     458{{{
     459#!mapcss
     460way[!/^addr:/]                    /* matches any way which does not have a tag 'addr:*' */
     461}}}
     462}}}
     463
     464You can test whether the value of a tag is logical truth value. The value is evaluated to true, if it is either
     465"yes", "true", or "1". All other values are evaluated to false.
     466
     467{{{#!th align=left valign=top
     468'''Condition'''
     469}}}
     470{{{#!th align=left valign=top
     471'''Example'''
     472}}}
     473|-------------------------------------------------------------------------------
     474{{{#!td align=left  valign=top
     475Testing for truth value
     476}}}
     477{{{#!td align=left  valign=top   
     478{{{
     479#!mapcss
     480way[oneway?]                  /* matches any way with a truth value in the tag 'oneway'  */
     481}}}
     482}}}
     483|-------------------------------------------------------------------------------
     484{{{#!td align=left  valign=top
     485Testing for false value (since r6513)
     486}}}
     487{{{#!td align=left  valign=top   
     488{{{
     489#!mapcss
     490way[oneway?!]                  /* matches any way with a false value in the tag 'oneway'  */
     491}}}
     492}}}
     493
     494=== Territory selector ===
     495
     496You can test whether an object is located inside or outside of a specific territory. JOSM has an internal database for this. The territories file is an osm file and can be downloaded [/export/HEAD/josm/trunk/data/boundaries.osm here] and opened in JOSM to investigate it [attachment:boundaries.png (screenshot preview)]. It contains borders of all countries of the world. Due to performance reasons the borders are simplified. They can be refined for special cases on request. The territories are "tagged" with their [https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 ISO_3166-1_alpha-2 codes]. USA, Canada, China, India and Australia have additional boundaries for their subdivisions. See the following examples on how to use the territory selectors. Territory selectors are less useful in mappaint styles and can be very resource heavy there. However they are much more useful for [wiki:Help/Validator/MapCSSTagChecker mapcss based validator rules]. To select territories with left-hand-traffic or right-hand-traffic, there is a simpler way, see [#PseudoClasses]. See #10387 for main implementation of this feature.
     497
     498{{{
     499#!mapcss
     500node[inside("FR")]                    /* matches any node located inside of France (this includes all the overseas territories)                                     */
     501node[inside("FX")]                    /* matches any node located inside of Metropolitan France (i.e. only the mainland part with its near islands including Corse) */
     502node[inside("EU")]                    /* matches any node located inside of the European Union                                                                      */
     503node[inside("FR,DE")]                 /* matches any node located inside of France __OR__ inside of Germany                                                         */
     504node[inside("US-FL")]                 /* matches any node located inside of the US state Florida                                                                    */
     505
     506node[outside("FR")]                   /* matches any node located outside of France                                                                                 */
     507node[outside("FR,DE")]                /* matches any node located outside of France __AND__ outside of Germany                                                      */
     508node[inside("US")][outside("US-FL")]  /* matches any node located inside of the USA except the state Florida                                                        */
     509}}}
     510
     511=== Link selector ===
     512In a child selector, you can formulate conditions on the link between a parent and a child object.
     513
     514If the parent is a relation, you can formulate conditions for the ''role'' a member objects has in this relation.
     515{{{
     516#!mapcss
     517relation[type=route] >[role="link"] way {  /* matches any way which is a member of route relation with role 'link' */
     518   color: blue;
     519}
     520}}}
     521
     522{{{#!th align=left valign=top
     523'''Operator'''
     524}}}
     525{{{#!th align=left valign=top
     526'''Description'''
     527}}}
     528{{{#!th align=left valign=top
     529'''Example'''
     530}}}
     531|-------------------------------------------------------------------------------
     532{{{#!td align=left  valign=top
     533`=`
     534}}}
     535{{{#!td align=left  valign=top   
     536Exact match of the role name. The name name {{{role}}} is compulsory in this context.
     537}}}
     538{{{#!td align=left  valign=top   
     539{{{
     540#!mapcss
     541relation >[role=residential] way           /* without quotes always case insensitive */
     542relation >[role="My name"]   way           /* use quotes for if the role value includes spaces or if case sensitive matching is important */
     543}}}
     544}}}
     545
     546The operators {{{!=, ^=, $=, *=, and ~=}}} are supported too. Please refer to [#condition_selector_operators condition selector operators].
     547
     548Nodes in ways and members in relations are ordered. You can formulate conditions on the position of a node in a way or a member
     549object in a relation. Positive numbers count from first to last element, negative numbers (since r8236) count from last to first element.
     550
     551{{{
     552#!mapcss
     553relation[type=route] >[index=1] way {  /* matches the first way which is a member of route relation  */
     554   color: blue;
     555}
     556
     557way >[index=-1] node {  /* matches the last node of a way  */
     558   symbol-stroke-color: green;
     559}
     560
     561way!:closed >[index=1] node!:connection,
     562way!:closed >[index=-1] node!:connection {  /* matches all single way end nodes */
     563   symbol-stroke-color: green;
     564}
     565}}}
     566
     567
     568=== Zoom selector ===
     569You can decorate a type selector with a '''zoom selector'''. The zoom selector restricts the range of zoom levels
     570at which the respective MapCSS rule is applied.
     571
     572{{{#!th align=left valign=top
     573'''Example'''
     574}}}
     575{{{#!th align=left valign=top
     576'''Description'''
     577}}}
     578|-------------------------------------------------------------------------------
     579|| {{{way|z12 {...} }}} || At zoom level 12 ||
     580|| {{{way|z13-15 {...} }}} || From 13 to 15 ||
     581|| {{{way|z16- {...} }}} || 16 and above ||
     582|| {{{way|z-12 {...} }}} || 12 and below ||
     583|| {{{way {...} }}} || any zoom level ||
     584
     585The precise definition of scale ranges for each zoom level may change in the future. By rule of thumb you can expect to be approximately at zoom level ''n'' when imagery displays slippymap tiles of level ''n''.
     586
     587
     588=== Pseudo Classes ===
     589See [/doc/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.PseudoClasses.html Javadoc] for the up-to-date list of pseudo classes supported by JOSM's MapCSS implementation.
     590
     591|| {{{:closed}}} || true for ways where the first node is the same as the last and for any (completely downloaded) multipolygon relation ||
     592|| {{{:closed2}}} || same as above, but this one ignores if a mulipolygon is downloaded completely (since r9099) ||
     593|| {{{:completely_downloaded}}} || true for a relation whose members are all downloaded (since r9099) ||
     594|| {{{:new}}} || all new objects ||
     595|| {{{:connection}}} || true for nodes that are used by more than one way ||
     596|| {{{:unconnected}}} || true for nodes that are not used by any way (since r6687) ||
     597|| {{{:tagged}}} || What JOSM considers tagged, i.e. an object that with a tag key other than the following: {{{source*, source_ref, note, comment, converted_by, created_by, watch*, fixme, FIXME, description, attribution}}} (version r4008; in this list, {{{*}}} is a glob)
     598|| {{{:righthandtraffic}}} || true if there is right-hand traffic at the current location (since r7193); see [[left-right-hand-traffic]] for screenshot of areas ||
     599|| {{{:clockwise}}} || Whether the way is closed and oriented clockwise, or non-closed and the 1st, 2nd and last node are in clockwise order. ||
     600|| {{{:anticlockwise}}} || Whether the way is closed and oriented anticlockwise, or non-closed and the 1st, 2nd and last node are in anticlockwise order. ||
     601|| {{{:unclosed_multipolygon}}} || true for fully loaded unclosed multipolygon relations (since r8252) ||
     602|| {{{:open_end}}} || to select end nodes of unclosed multipolygon relations with `relation:unclosed_multipolygon >:open_end node` (since r8252) ||
     603|| {{{:in-downloaded-area}}} || true if an object is within source area and false if in the hatched area (since r8495). ||
     604|| {{{:selected}}} || true if an object is selected in the editor (since r9341). ||
     605|| {{{:modified}}} || changed objects (since r7193). ||
     606You can also negate pseudo classes. E.g. {{{!:new}}} for all old objects.
     607
     608=== Layer Identifier ===
     609
     610Layers can be used to create more than one style for a single object. Here is an example:
     611{{{
     612#!mapcss
     613way[highway=secondary] {
     614    width: 3;
     615    color: yellow;
     616}
     617
     618way[highway=tertiary] {
     619    width: 2;
     620    color: orange;
     621}
     622
     623way[access][access!=public]::non_public_access_layer {
     624    width: +2;
     625    color:red;
     626    dashes: 2;
     627    object-z-index:-1.0;
     628}
     629
     630way[bridge]::bridge_layer {
     631    width: +3;
     632    color:#000080;
     633    opacity:0.5;
     634    object-z-index:1.0;
     635}
     636}}}
     637This draws all secondary and tertiary roads in yellow and orange respectively. Any road with an access tag other than public will get an extra line style below ('''{{{object-z-index:-1.0;}}}''') the main line. If that part of the street happens to be a bridge, it will also get a half transparent blue overlay. The relative width value ('''{{{width: +2;}}}''') refers to the width on the default layer (2 or 3 in this case).
     638
     639The name for the layer can be any identifier.
     640
     641If you omit the layer in the selector, this is the same as using {{{::default}}}.
     642
     643One more example:
     644{{{
     645#!mapcss
     646node[amenity=parking] {
     647    icon-image: "presets/vehicle/parking/parking.svg";    /* displays the josm internal parking icon in the default layer */
     648    text: ref;                                            /* displays the value of the key ref as text in the default layer */
     649}
     650
     651node[amenity=parking][fee=yes]::fee {
     652    icon-image: "presets/money/exchange.svg";             /* displays the josm internal exchange icon in the fee layer */
     653    icon-offset-x: 14;                                    /* shift the icon */
     654    icon-offset-y: -12;                                   /* shift the icon */
     655    text: charge;                                         /* displays the value of the key charge as text in the fee layer */
     656    text-offset-x: 16;                                    /* shift the text */
     657    text-offset-y: 17;                                    /* shift the text */
     658}
     659}}}
     660The result looks this way:
     661
     662[[Image(multiple_icons_and_texts.png)]]
     663
     664In addition, you can use the * layer to override and initialize all layers.[[br]]
     665It overrides all existing subparts, so
     666
     667{{{
     668#!mapcss
     669way::A { a; }
     670way::B { b; }
     671way::* { c; }
     672}}}
     673is equivalent to
     674{{{
     675#!mapcss
     676way::A { a; }
     677way::B { b; }
     678way::A { c; }
     679way::B { c; }
     680}}}
     681And it initializes new subparts. In other words:
     682{{{
     683#!mapcss
     684way::* { a; }
     685way::A { b; }
     686}}}
     687is equivalent to
     688{{{
     689#!mapcss
     690way::A {}
     691way::* { a; }
     692way::A { b; }
     693}}}
     694which is in turn the same as
     695{{{
     696#!mapcss
     697way::A { a; }
     698way::A { b; }
     699}}}
     700or
     701{{{
     702#!mapcss
     703way::A { a; b; }
     704}}}
     705
     706
     707=== Grouping ===
     708
     709Rules with common declaration block can be grouped into one:
     710{{{
     711#!mapcss
     712area[landuse=forest] { color: green;   width: 2; }
     713area[natural=wood] { color: green;   width: 2; }
     714}}}
     715is the same as
     716{{{
     717#!mapcss
     718area[landuse=forest], area[natural=wood] { color: green;   width: 2; }
     719}}}
     720
     721=== Classes ===
     722You may assign classes to matched elements, and define other selectors using those classes:
     723
     724{{{
     725#!mapcss
     726/* assigning classes */
     727selector {
     728  set class;
     729  /* or equivalently */
     730  set .class;
     731}
     732
     733/* matching classes */
     734way.class, node[foo=bar].class {
     735  /* ... */
     736}
     737}}}
     738
     739
     740Example for assigning/matching a class named `path`:
     741{{{
     742#!mapcss
     743way[highway=footway] { set path; color: #FF6644; width: 2; }
     744way[highway=path]    { set path; color: brown; width: 2; }
     745way.path { text:auto; text-color: green; text-position: line; text-offset: 5; }
     746}}}
     747You can also negate classes. E.g. {{{way!.path}}} for all ways, which are not part of the class ''.path''.
     748
     749== @supports rule for conditional processing [''since 8087''] ==
     750
     751@supports rules are used to skip a section of the style under certain conditions. Typically you want to use a feature which is introduced in a newer version of JOSM, but like to have a fall back style for users of older JOSM clients. Example:
     752{{{
     753#!mapcss
     754@supports (min-josm-version: 9789) {
     755    way[highway] {
     756        width: 4;
     757        color: orange;
     758    }
     759    /* fancy new stuff */
     760    /* ... */
     761}
     762
     763@supports (max-josm-version: 9788) {
     764    way[highway] {
     765        width: 4;
     766        color: blue;
     767    }
     768    /* fall back mode, using more simple features */
     769    /* ... */
     770}
     771
     772@supports (icon-offset-x) {
     773    /* only if icon-offset-x property is supported */
     774    node[amenity] {
     775        icon-offset-x: 5;
     776    }
     777}
     778}}}
     779
     780The syntax closely matches the official [https://drafts.csswg.org/css-conditional/ css syntax]. The following conditions are supported:
     781
     782{{{#!th
     783'''Condition'''
     784}}}
     785{{{#!th
     786'''Description'''
     787}}}
     788|-
     789{{{#!td
     790(''<mapcsskey>'')
     791}}}
     792{{{#!td
     793Check if a certain mapcss key is supported, e.g. `repeat-image` or `icon-offset-x`.
     794}}}
     795|-
     796{{{#!td
     797(min-josm-version: ''<number>'')
     798}}}
     799{{{#!td
     800Only include {{{@supports}}} section when the current version of JOSM is greater than or equal to the specified number.
     801}}}
     802|-
     803{{{#!td
     804(max-josm-version: ''<number>'')
     805}}}
     806{{{#!td
     807Only include {{{@supports}}} section when the current version of JOSM is lower than or equal to the specified number.
     808}}}
     809|-
     810{{{#!td
     811(user-agent: ''<string>'')
     812}}}
     813{{{#!td
     814Only include {{{@supports}}} section when the name of the editor / renderer matches the given string. In JOSM, the only accepted value is {{{josm}}}.
     815}}}
     816
     817Conditions can be combined with {{{and}}}:
     818
     819{{{
     820#!mapcss
     821@supports (min-josm-version: 8087) and (max-josm-version: 8200) {
     822 /* only for JOSM versions 8087 to 8200 */
     823}
     824}}}
     825
     826Other logical operators like {{{or}}} and {{{not}}} can also be used. Parentheses are needed if you want to combine different logical operators:
     827
     828{{{
     829#!mapcss
     830@supports ((min-josm-version: 8087) and (max-josm-version: 8200)) or (user-agent: myEditor) {
     831  /* for JOSM version 8087 to 8200 and for the editor called "myEditor" */
     832}
     833}}}
     834
     835Since @supports rules are only supported in JOSM 8087 and later, you should also specify this as minimum JOSM version in the meta selector:
     836
     837{{{
     838#!mapcss
     839meta {
     840    min-josm-version: "8087"; /* This style uses @supports rules */
     841    /* ... */
     842}
     843}}}
     844
     845== Style settings ==
     846
     847[[Help/Dialog/MapPaint/StyleSettings|Styles settings]] are used to provide the user settings to customize a mappaint style. The user can use them in the MapPaint dialog. Style settings are availible since r7450. The internal style provides style settings since r7454. Note that there are plans to extend the implementation of style settings (currently there are only boolean values supported), so the mapcss syntax for style settings could change in the future (see #10435).
     848
     849create a setting:
     850{{{
     851#!mapcss
     852setting::highway_casing {
     853  type: boolean;
     854  label: tr("Draw highway casing");
     855  default: true;
     856}
     857}}}
     858use a setting:
     859{{{
     860#!mapcss
     861way[highway][setting("highway_casing")] {
     862  casing-width: 2;
     863  casing-color: white;
     864}
     865}}}
     866
     867== Properties ==
     868
     869=== General properties ===
     870
     871||=  '''Key''' =||= '''Description''' =||= '''Value Format''' =||= '''Default Value''' =||
     872|| {{{z-index}}}                                 || Specify the order the objects are drawn: The objects with higher z-index are drawn on top of objects with lower z-index || ''Number'' (can be negative) ||  0  ||
     873|| {{{major-z-index}}} || Similar to {{{z-index}}}, but it has higher priority than {{{z-index}}}. So if one object has a higher {{{major-z-index}}} than the other, it is drawn on top. If the {{{major-z-index}}} is the same, {{{z-index}}} decides. || ''Number'' (can be negative) ||  Depends on style element: area: 1, casing: 2, left-/right-casing: 2.1, line-pattern: 2.9, line: 3, point: 4, default-point: 4.1, line-text: 4.9, point-text: 5   ||
     874|| {{{object-z-index}}} || Similar to {{{z-index}}}, but has lower priority. Controls the painting order for overlapping objects. E.g. for two crossing ways with text: Use {{{z-index}}} or {{{major-z-index}}} if you first want to draw the two lines and then the two captions. Use {{{object-z-index}}} if one of the ways should be completely on top of the other. || ''Number'' (can be negative) ||  0  ||
     875|| {{{modifier}}} || Better control, whether a default line / node symbol is generated by JOSM. This happens when there is no proper style ({{{modifier=false}}}) found on any layer. || {{{false}}} or {{{true}}} || {{{false}}} for the default layer and {{{true}}} for any other layer ||
     876
     877Note that due to performance reasons the values for the three z-indexes are limited to 24 bit float values with max. 5 decimal digits. Currently the internal mappaint style uses values with max. 2 digits before and after the decimal separator. To avoid problems use values of z-indexes between -99.999 and +99.999. (See also #14485)
     878
     879
     880=== Icon and symbol styles ===
     881
     882||=  '''Key''' =||= '''Description''' =||= '''Value Format''' =||= '''Default Value''' =||
     883|| {{{icon-image}}} || The icon at node position. See also [wiki:Help/Styles/Images Images]. || ''Image'' ||  -  ||
     884|| {{{icon-opacity}}} || Opacity of the icon image || ''Opacity'' ||  1.0  ||
     885|| {{{icon-width}}} || Width of the icon. If only one of the properties {{{icon-width}}} and {{{icon-height}}} is given, the image will be scaled proportionally. The icon will keep the original size, if neither {{{icon-width}}} nor {{{icon-height}}} is set. || ''Number'' ||  -  ||
     886|| {{{icon-height}}} || Height of the icon. (See {{{icon-width}}}) || ''Number'' ||  -  ||
     887|| `icon-offset-x` || Shift the icon in horizontal direction (positive values to the right) (since r8085) || ''Number'' ||  0  ||
     888|| `icon-offset-y` || Shift the icon in vertical direction (positive values downwards) (since r8085) || ''Number'' ||  0  ||
     889|| `icon-rotation` || Rotate the icon clockwise or anti clockwise (negative value)(since r8260) || `[rad]`, `[rad]rad`, `[deg]°`, `[deg]deg`, `[grad]grad`, `[turn]turn` ([https://developer.mozilla.org/en/docs/Web/CSS/angle definition]) or a cardinal direction (e.g. `northeast` or `sw`); See also the functions `degree_to_radians`, `cardinal_to_radians`. ||  -  ||
     890|| `icon-position` || Define the position of the icon for areas. Same as `text-position` (since r11730). || {{{center}}}, {{{inside}}}, {{{line}}} || {{{center}}} ||
     891|| {{{symbol-shape}}}                               || Display a symbol at the position of the node || {{{square}}}, {{{circle}}}, {{{triangle}}}, {{{pentagon}}}, {{{hexagon}}}, {{{heptagon}}}, {{{octagon}}}, {{{nonagon}}}, {{{decagon}}} ||  -  ||
     892|| {{{symbol-size}}} || Size of the symbol || ''Number'', can be relative ("+4") ||  10  ||
     893|| {{{symbol-stroke-width}}} || outline stroke width || ''Width'' ||  1.0 if {{{symbol-stroke-color}}} is set  ||
     894|| {{{symbol-stroke-color}}} || line color || ''Color'' || {{{#FFC800}}} if {{{symbol-stroke-width}}} is set ||
     895|| {{{symbol-stroke-opacity}}} || line opacity || ''Opacity'' ||  1.0  ||
     896|| {{{symbol-fill-color}}} || fill color for the shape || ''Color'' || {{{blue}}}, unless either {{{symbol-stroke-width}}} or {{{symbol-stroke-color}}} is set ||
     897|| {{{symbol-fill-opacity}}} || fill opacity || ''Opacity'' || 1.0  ||
     898|| {{{text-...}}}, {{{font-...}}} ||||||  general text & font properties  ||
     899|| {{{text-anchor-horizontal}}} || horizontal text label placement || {{{left}}}, {{{center}}}, {{{right}}} ||  {{{right}}}  ||
     900|| {{{text-anchor-vertical}}} || vertical text label placement || {{{above}}}, {{{top}}}, {{{center}}}, {{{bottom}}}, {{{below}}} ||  {{{bottom}}}  ||
     901
     902Do not rely on the default values for {{{symbol-...}}} properties (except for {{{opacity}}}). They are intended for "quick & dirty" style sheets and should be set to an explicit value.
     903
     904
     905
     906
     907
     908=== Line styles ===
     909||=  '''Key''' =||= '''Description''' =||= '''Value Format''' =||= '''Default Value''' =||
     910|| {{{width}}} || Line width || ''Width'' ||  -  ||
     911|| {{{color}}} || Line color || ''Color'' ||  value of {{{fill-color}}} or (if unset) JOSM's default untagged color ({{{#808080}}}) ||
     912|| {{{opacity}}} || How transparent the line is. || ''Opacity'' ||  1.0  ||
     913|| {{{dashes}}} || An array of alternating on/off lengths || list of numbers, e.g. [[br]]> 15, 5 [[br]][[br]]may be written as expression: [[br]] > {{{list(3, 4, 5, 6)}}} [[br]][[br]]or the keyword {{{none}}}[[br]]to turn dashes off ||  -  ||
     914|| {{{dashes-offset}}} || shift the dash pattern by a certain amount || ''Number'' (>= 0) ||  0  ||
     915|| {{{dashes-background-color}}} || The color to use in between the dashes (optional) || ''Color'' ||  -  ||
     916|| {{{dashes-background-opacity}}} || Opacity value for the dashes background || ''Opacity'' ||  value of {{{opacity}}}  ||
     917|| {{{linecap}}} || Shape at the end of the line (see [https://www.w3.org/TR/SVG/painting.html#StrokeLinecapProperty here]) || {{{none}}}, {{{round}}}, {{{square}}} ||  {{{none}}}  ||
     918|| {{{linejoin}}} || Shape at the line corners || {{{round}}}, {{{miter}}}, {{{bevel}}} ||  {{{round}}}  ||
     919|| {{{miterlimit}}}                                   || Applies for {{{linejoin: miter}}}. Sets the maximum overshoot when line segments meet at a very small angle || ''Number'' (>= 1.0) ||  10.0  ||
     920|| {{{offset}}} || Move line to the left or right (when looking in way direction). This could be used to draw multiple lanes for one way or mark left and right side of a way differently. || ''Number'' (positive value moves line to the left, negative to the right) ||  0  ||
     921|| {{{text-position}}} || set to {{{line}}}, if text should be drawn along the line || {{{line}}}, {{{center}}} ||  -  ||
     922|| {{{text-...}}}, {{{font-...}}} ||||||  general text & font properties  ||
     923|| `repeat-image` || repeated image along a line ''[since 5801]'' || ''Image'' ||  -  ||
     924|| `repeat-image-width` || Width of the image (optional, see `icon-width`) ''[since 5811]'' || ''Number'' ||  -  ||
     925|| `repeat-image-height` || Height of the image (optional) ''[since 5811]'' || ''Number'' ||  -  ||
     926|| `repeat-image-align` || Alignment of the image. Top-, bottom edge or the (horizontal) center line of the image will be along the line ''[since 5801]'' || `top`, `center`, `bottom` ||  `center`  ||
     927|| `repeat-image-offset` || Offset from the line ''[since 5801]'' || ''Number'' ||  0  ||
     928|| `repeat-image-spacing` || Spacing between repeated images ''[since 5801]'' || ''Number'' ||  0  ||
     929|| `repeat-image-phase` || Initial spacing at the beginning of the line ''[since 5812]'' || ''Number'' ||  0  ||
     930
     931All these properties (except for {{{text-...}}} and {{{font-...}}}) exist also with the {{{casing-}}} prefix. The casing is a second independent line element, that is drawn below the normal line and can be used to draw a thin frame around the line in another color.
     932||=  '''Key''' =||= '''Description''' =||= '''Value Format''' =||= '''Default Value''' =||
     933|| {{{casing-width}}}               || Width of the border on both sides of the main line. In JOSM < 5214: Total width of the casing || ''Width'' (revers to {{{width}}} if relative width is specified) ||  -  ||
     934|| {{{casing-color}}} || Casing color || ''Color'' ||  value of {{{fill-color}}} or (if unset) JOSM's default untagged color ({{{#808080}}}) ||
     935|| {{{casing-opacity}}} || How transparent the casing is. || ''Opacity'' ||  1.0  ||
     936|| {{{casing-}}}... || ... || ... ||  ...  ||
     937Similar to {{{casing-}}}, there is also the {{{left-casing-}}} and {{{right-casing-}}} prefix. It draws additional lines to the left and to the right of the main line.
     938
     939=== Area styles ===
     940||=  '''Key''' =||= '''Description''' =||= '''Value Format''' =||= '''Default Value''' =||
     941|| {{{fill-color}}} || Color in which to fill the area. Until 11700, the alpha component was set to 50 to create a transparency effect. || ''Color'' ||  -  ||
     942|| {{{fill-image}}} || Image pattern || ''Image'' ||  -  ||
     943|| {{{fill-extent}}} || Set this property, to draw only the outline of the area. The number specifies, how far to fill from the border of the area towards the center. (If unset, the area will be filled completely) ''[since 9008]'' || ''Number'' ||  -  ||
     944|| {{{fill-opacity}}} || How transparent the fill is; applies to both color and image || ''Opacity'' || 0.2 ''[since 11700, 1.0 before that]'' (can be changed with the {{{mappaint.fillalpha}}} and {{{mappaint.fill-image-alpha}}} preferences)  ||
     945|| {{{text-position}}} || set to {{{center}}}, if text should be drawn in the center of the area. Set to {{{inside}}} to place the text completely inside the area (since r11722). || {{{line}}}, {{{center}}}, {{{inside}}} ||  -  ||
     946|| {{{text-...}}}, {{{font-...}}} ||||||  general text & font properties  ||
     947Required properties to create an Area style: {{{fill-color}}} or {{{fill-image}}}
     948
     949
     950=== Text & Font properties ===
     951{{{#!th align=left valign=top
     952'''Key'''
     953}}}
     954{{{#!th align=left valign=top
     955'''Description'''
     956}}}
     957{{{#!th align=left valign=top
     958'''Value Format'''
     959}}}
     960{{{#!th align=left valign=top
     961'''Default Value'''
     962}}}
     963|-------------------------------------------------------------------------------
     964{{{#!td align=left  valign=top
     965{{{text}}} 
     966}}}
     967{{{#!td align=left  valign=top
     968How to find the label text. No label is displayed, unless this instruction is present.
     969}}}
     970{{{#!td align=left  valign=top
     971{{{auto}}}
     972   Derive the text automatically. The default name tags are: "{{{name:}}}"+''<LANG>'', "{{{name}}}", "{{{int_name}}}", "{{{ref}}}", "{{{operator}}}", "{{{brand}}}" and "{{{addr:housenumber}}}".
     973
     974   Configure a list of tag names in the preference "{{{mappaint.nameOrder}}}" in order to change this list. (After changing the list, a restart of JOSM is required.)
     975
     976''String''
     977   Denotes the key of the tag whose value is used as text.
     978
     979''Expressions''
     980  You can enter an expression to compute the text to be displayed. Examples:
     981  * {{{eval("this is a static text")}}} - renderes a static text
     982  * {{{eval(concat(tag("first"), "-", tag("second")))}}} - displays the concatenated tags "first" and "second"
     983
     984{{{""}}}
     985   To delete a previous set text.
     986}}}
     987{{{#!td align=center  valign=top
     988-
     989}}}
     990|-------------------------------------------------------------------------------
     991|| {{{text-color}}} || the text color || ''Color'' ||  {{{white}}} for lines and nodes, {{{#c0c0c0}}} for areas (JOSM "{{{text}}}" and "{{{areatext}}}" color preferences) ||
     992|| {{{text-opacity}}} || how transparent the text is || ''Opacity'' ||  1.0  ||
     993|| {{{text-offset-x}}} || shift the text horizontally, (not supported for text along line) || ''Number'' ||  0  ||
     994|| {{{text-offset-y}}} (can also be written as {{{text-offset}}})  || shift the text vertically, positive values shift the text in upwards direction  || ''Number'' ||  0  ||
     995|| {{{text-halo-radius}}} || size of text background border (to make text visible on background with a similar color) || ''Number'' ||  -  ||
     996|| {{{text-halo-color}}} || color of the text halo || ''Color'' ||  complement of the text color  ||
     997|| {{{text-halo-opacity}}} || transparency for the text halo || ''Opacity'' ||  1.0  ||
     998|| {{{font-family}}} || font family || ''String'' ||  "Helvetica"[[br]](JOSM preference "mappaint.font")  ||
     999|| {{{font-size}}} || font size || ''Number'' ||  8[[br]](JOSM preference "mappaint.fontsize")  ||
     1000|| {{{font-weight}}} || bold or not || {{{bold}}}, {{{normal}}} ||  {{{normal}}}  ||
     1001|| {{{font-style}}} || italic or not || {{{italic}}}, {{{normal}}} ||  {{{normal}}}  ||
     1002
     1003'' '''Width''' ''
     1004 - 14.0 (any positive number)
     1005 - {{{default}}} (use JOSM's default line width, which is 2, but can be configured)
     1006 - {{{thinnest}}} (draws the line as thin as possible)
     1007 - +3 (with plus sign in front) adds the amount to the width on the default layer. This applies only for styles that are not on the default layer, e.g. highlights. Another way to write this would be {{{prop("width","default")+3}}}. For {{{casing-width}}}, this refers to the {{{width}}} value on the same layer.
     1008
     1009'' '''Image''' ''
     1010 See [wiki:Help/Styles/Images].
     1011
     1012'' '''Color''' ''
     1013 * named color as found in [https://www.w3.org/TR/css3-color/#svg-color this] list
     1014 * html style: '''{{{#RRGGBB}}}''', '''{{{#RGB}}}''', '''{{{#RRGGBBAA}}}'''
     1015 * '''{{{rgb(/*r*/, /*g*/, /*b*/)}}}''' - rgb value with arguments from 0.0 to 1.0
     1016 * '''{{{rgba(/*r*/, /*g*/, /*b*/, /*alpha*/)}}}''' - rgb value with alpha
     1017 * '''{{{hsb_color(/*hue*/, /*saturation*/, /*brightness*/)}}}''' - color from HSB color space
     1018
     1019'' '''Opacity''' ''
     1020 * from 0.0 (transparent) to 1.0 (opaque)
     1021
     1022'' '''String''' ''
     1023 * any character sequence, in quotes, e.g. {{{"images/fill.png"}}}. If the string is an identifier, quotes are optional. (Quote and backslash sign can be escaped.)
     1024
     1025'' '''Number''' ''
     1026 * integer or floating point (in simple form e.g. 0.3). In general can be negative, but most properties do not support negative numbers
     1027 * has a special meaning if you put a "+" sign in front (relative width)
     1028
     1029== Eval expressions ==
     1030
     1031
     1032See [/doc/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.Functions.html#method_summary Javadoc of Functions] for the up-to-date list of functions supported by JOSM's MapCSS implementation.
     1033
     1034 +, -, *, /::
     1035  arithmetic operations
     1036 ||, &&, !::
     1037  boolean operations
     1038 <, >, <=, >=, ==::
     1039  comparison operators
     1040 asin, atan, atan2, ceil, cos, cosh, exp, floor, log, max, min, random, round, signum, sin, sinh, sqrt, tan, tanh::
     1041  the usual meaning, [https://download.oracle.com/javase/8/docs/api/java/lang/Math.html details]
     1042 cond(b, fst, snd)::
     1043 b ? fst : snd::
     1044  if ('''b''') then '''fst''' else '''snd'''
     1045 list(a, b, ...)::
     1046  create list of values, e.g. for the {{{dashes}}} property
     1047 get(lst, n)::
     1048  get the ''n''th element of the list ''lst'' (counting starts at 0) [''since 5699'']
     1049 split(sep, str)::
     1050  splits string ''str'' at occurrences of the separator string ''sep'', returns a list [''since 5699'']
     1051 prop(''p_name'')::
     1052  value of the property ''p_name'' of the current layer, e.g. prop({{{"width"}}})
     1053 prop(''p_name'', ''layer_name'')::
     1054  property from the layer ''layer_name''
     1055 is_prop_set(''p_name'')::
     1056  true, if property ''p_name'' is set for the current layer
     1057 is_prop_set(''p_name'', ''layer_name'')::
     1058  true, if property ''p_name'' is set for the layer ''layer_name''
     1059 tag(''key_name'')::
     1060  get the value of the key ''key_name'' from the object in question
     1061 parent_tag(''key_name'')::
     1062  get the value of the key ''key_name'' from the object's parent
     1063 parent_tags(''key_name'')::
     1064  returns all parent's values for the key ''key_name'' as a list ordered by a natural ordering [''since 8775'']
     1065 has_tag_key(''key_name'')::
     1066  true, if the object has a tag with the given key
     1067 rgb(''r'', ''g'', ''b'')::
     1068  create color value (arguments from 0.0 to 1.0)
     1069 hsb_color(''h'', ''s'', ''b'')::
     1070  create color from hue, saturation and brightness (arguments from 0.0 to 1.0) [''since 6899'']
     1071 red(''clr''), green(''clr''), blue(''clr'')::
     1072  get value of color channels in rgb color model
     1073 alpha(''clr'')::
     1074  get the alpha value of the given color [''since 6749'']
     1075 length(''str'')::
     1076  length of a string
     1077 count(''lst'')::
     1078  length of a list, i.e., counts its elements [''since 7162'']
     1079 length(''lst'')::
     1080  length of a list [''since 5699''] – deprecated ''since 7162''
     1081 any(obj1, obj2, ...)::
     1082  returns the first object which is not null (formerly coalesce, [''since 7164''])
     1083 concat(''str1'', ''str2'', ...)::
     1084  assemble the strings to one
     1085 join(''sep'', ''str1'', ''str2'', ...)::
     1086  join strings, whith ''sep'' as separator [''since 6737'']
     1087 join_list(''sep'', ''list_name'')::
     1088   joins the elements of the list ''list_name'' to one string separated by the separator ''sep'' [''since 8775'']
     1089 upper(''str'')::
     1090   converts string to upper case [''since 11756'']
     1091 lower(''str'')::
     1092   converts string to lower case [''since 11756'']
     1093 trim(''str'')::
     1094   remove leading and trailing whitespace from string [''since 11756'']
     1095 JOSM_search("...")::
     1096  true, if JOSM search applies to the object
     1097 tr(str, arg0, arg1, ...)::
     1098  translate from English to the current language (only for strings in the JOSM user interface) [''since 6506'']
     1099 regexp_test(regexp, string)::
     1100  test if ''string'' matches pattern ''regexp'' [''since 5699'']
     1101 regexp_test(regexp, string, flags)::
     1102  test if ''string'' matches pattern ''regexp''; flags is a string that may contain "i" (case insensitive), "m" (multiline) and "s" ("dot all") [''since 5699'']
     1103 regexp_match(regexp, string)::
     1104  Tries to match ''string'' against pattern ''regexp''. Returns a list of capture groups in case of success. The first element (index 0) is the complete match (i.e. ''string''). Further elements correspond to the bracketed parts of the regular expression. [''since 5701'']
     1105 regexp_match(regexp, string, flags)::
     1106  Tries to match ''string'' against pattern ''regexp''. Returns a list of capture groups in case of success. The first element (index 0) is the complete match (i.e. ''string''). Further elements correspond to the bracketed parts of the regular expression. Flags is a string that may contain "i" (case insensitive), "m" (multiline) and "s" ("dot all") [''since 5701'']
     1107 substring(str, idx)::
     1108  return the substring of ''str'', starting at index ''idx'' (0-indexed) [''since 6534'']
     1109 substring(str, start, end)::
     1110  return the substring of ''str'', starting at index ''start'' (inclusive) up to ''end'' (exclusive) (0-indexed) [''since 6534'']
     1111 replace(string, old, new)::
     1112   Replaces any occurrence of the substring ''old'' within the string ''string'' with the text ''new''
     1113 osm_id()::
     1114  returns the OSM id of the current object [''since 5699'']
     1115 parent_osm_id()::
     1116  returns the OSM id of the object's parent (matched by child selector) [''since 13094'']
     1117 URL_encode(str)::
     1118  [https://en.wikipedia.org/wiki/Percent-encoding percent-encode] a string. May be useful for data URLs [''since 6805'']
     1119 URL_decode(str)::
     1120  [https://en.wikipedia.org/wiki/Percent-encoding percent-decode] a string. [''since 11756'']
     1121 XML_encode(str)::
     1122  escape special characters in xml. E.g. {{{<}}} becomes {{{&lt;}}}, other special characters: {{{>}}}, {{{"}}}, {{{'}}}, {{{&}}}, {{{\n}}}, {{{\t}}} and {{{\r}}} [''since 6809'']
     1123 CRC32_checksum(''str'')::
     1124  calculate the CRC32 checksum of a string (result is an integer from 0 to 2^32^-1) [''since 6908'']
     1125 is_right_hand_traffic()::
     1126  Check if there is left-hand or right-hand traffic at the current location. [''since 7193'']
     1127 number_of_tags()::
     1128  returns the number of tags for the current OSM object [''since 7237'']
     1129 print(o)::
     1130  prints a string representation of `o` to the command line (for debugging) [''since 7237'']
     1131 println(o)::
     1132  prints a string representation of `o` to the command line, followed by a new line (for debugging) [''since 7237'']
     1133 JOSM_pref(''key'', ''default'')::
     1134  Get value from the JOSM advanced preferences. This way you can offer certain options to the user and make the style customizable. It works with strings, numbers, colors and boolean values. [[br]][This function exists since version 3856, but with some restrictions. `JOSM_pref` always returns a string, but in version 7237 and earlier, the automatic conversion of string to boolean and color was not working. You can use the following workarounds for boolean values and color in version 7237 and earlier: `cond(JOSM_pref("myprefkey", "true")="true", "X", "O")` and `html2color(JOSM_pref("mycolor", "#FF345611"))`. These explicit conversions should be no longer necessary in version 7238 and later. Automatic conversion to a number works in any version.]
     1135 setting()::
     1136  to use a [[Help/Styles/MapCSSImplementation#Stylesettings|style setting]] [''since 7450'']
     1137 degree_to_radians()::
     1138  returns a in degree given direction in radians [''since 8260'']
     1139 cardinal_to_radians()::
     1140  returns a cardinal direction in radians [''since 8260'']
     1141 waylength()::
     1142  returns the length of the way in metres [''since 8253'']
     1143 areasize()::
     1144  returns the area of a closed way in square meters [''since 8253'']
     1145 at(lat,lon)::
     1146  returns true if the object centroid lies at given ''lat''/''lon'' coordinates, e.g. to check for nodes at "null island" `node[at(0.0,0.0)]` [''since 12514'']
     1147
     1148
     1149=== Examples ===
     1150
     1151* circle symbol for house number with size depending of the number of digits
     1152{{{
     1153#!mapcss
     1154node[addr:housenumber] {
     1155    symbol-shape: circle;
     1156    symbol-size: eval((min(length(tag("addr:housenumber")), 3) * 5) + 3);
     1157    symbol-fill-color: #B0E0E6;
     1158
     1159    text: "addr:housenumber";
     1160    text-anchor-horizontal: center;
     1161    text-anchor-vertical: center;
     1162    text-offset-x: -1;
     1163    text-offset-y: -1; }
     1164   
     1165node[addr:housenumber]::hn_casing {
     1166    z-index: -100;
     1167    symbol-shape: circle;
     1168    symbol-size: +2;
     1169    symbol-fill-color: blue;
     1170}
     1171}}}
     1172* invert colors
     1173{{{
     1174#!mapcss
     1175*::* {
     1176    color: eval(rgb(1 - red(prop(color)), 1 - green(prop(color)), 1 - blue(prop(color))));
     1177    fill-color: eval(rgb(1 - red(prop(fill-color)), 1 - green(prop(fill-color)), 1 - blue(prop(fill-color))));
     1178}
     1179}}}
     1180* random stuff
     1181{{{
     1182#!mapcss
     1183way {
     1184    width: eval(random() * 20);
     1185    color: eval(rgb(random(), random(), random()));
     1186}
     1187}}}
     1188
     1189* regexp matching example: change "nameXXXsubname" to "name::subname"
     1190{{{
     1191#!mapcss
     1192*[name=~/.+XXX.+/]
     1193{
     1194    _match: regexp_match("(.+?)XXX(.+)", tag("name"));
     1195    text: concat(get(prop("_match"),1), "::", get(prop("_match"),2));
     1196}
     1197}}}
     1198
     1199* paint buildings in different colors according to street in the address tags
     1200{{{
     1201#!mapcss
     1202area[building][addr:street] {
     1203    fill-color: hsb_color(CRC32_checksum(tag("addr:street"))/4294967296.0, 0.9, 0.7);
     1204    fill-opacity: 0.8;
     1205}
     1206}}}
     1207
     1208
     1209== Compatibility notes ==
     1210=== MapCSS 0.2 ===
     1211
     1212==== Grammar ====
     1213
     1214 * {{{way[oneway=yes]}}} does not have any magic, you can use {{{way[oneway?]}}} instead
     1215 * no {{{@import}}}
     1216 * JOSM does not require {{{eval(...)}}} to be wrapped around expressions, but for compatibility with other MapCSS implementations you should write it out.
     1217
     1218==== Properties ====
     1219At the moment, JOSM does ''not'' support the following properties:
     1220 line: ::
     1221  {{{image}}}
     1222 label: ::
     1223  {{{font-variant, text-decoration, text-transform, max-width}}}
     1224 shield: ::
     1225  not supported
     1226
     1227=== Halcyon (Potlatch 2) ===
     1228
     1229 * Text label is placed in the center of the icon. For compatibility with Halcyon put
     1230{{{
     1231#!mapcss
     1232node { text-anchor-vertical: center; text-anchor-horizontal: center; }
     1233}}}
     1234 at the beginning of your style sheet.
     1235 * standard z-index in Halcyon is 5, but it is 0 in JOSM
     1236 * '''{{{image: circle;}}}''' corresponds to '''{{{symbol-shape: circle;}}}'''
     1237
     1238=== Kothic ===
     1239
     1240 * Kothic has support for eval, which probably differs from JOSM's eval.
     1241 * Kothic understands units, whereas JOSM always calculates in pixel.
     1242 * The extrusion features are not available in JOSM
     1243
     1244=== Ceyx ===
     1245
     1246 * seems to have {{{[tunnel=1]}}} instead of {{{[tunnel=yes]}}} (Halcyon) or {{{[tunnel?]}}} (JOSM)
     1247
     1248== Media queries [''since 6970'']  (deprecated) ==
     1249
     1250{{{#!td style="background-color: #faa"
     1251Note: media queries are deprecated. You should use @supports rules instead (see above).
     1252}}}
     1253Media queries are used to skip a section of the style under certain conditions. Typically you want to use a feature which is introduced in a newer version of JOSM, but like to have a fall back style for users of older JOSM clients. Example:
     1254{{{
     1255#!mapcss
     1256@media (min-josm-version: 9789) {
     1257    way[highway] {
     1258        width: 4;
     1259        color: orange;
     1260    }
     1261    /* fancy new stuff */
     1262    /* ... */
     1263}
     1264
     1265@media (max-josm-version: 9788) {
     1266    way[highway] {
     1267        width: 4;
     1268        color: blue;
     1269    }
     1270    /* fall back mode, using more simple features */
     1271    /* ... */
     1272}
     1273}}}
     1274
     1275The syntax closely matches the official [https://www.w3.org/TR/css3-mediaqueries/#syntax css syntax]. The following conditions are supported:
     1276
     1277{{{#!th
     1278'''Media condition'''
     1279}}}
     1280{{{#!th
     1281'''Description'''
     1282}}}
     1283|-
     1284{{{#!td
     1285(min-josm-version: ''<number>'')
     1286}}}
     1287{{{#!td
     1288Only include {{{@media}}} section when the current version of JOSM is greater than or equal to the specified number.
     1289}}}
     1290|-
     1291{{{#!td
     1292(max-josm-version: ''<number>'')
     1293}}}
     1294{{{#!td
     1295Only include {{{@media}}} section when the current version of JOSM is lower than or equal to the specified number.
     1296}}}
     1297|-
     1298{{{#!td
     1299(user-agent: ''<string>'')
     1300}}}
     1301{{{#!td
     1302Only include {{{@media}}} section when the name of the editor / renderer matches the given string. In JOSM, the only accepted value is {{{josm}}}.
     1303}}}
     1304
     1305Conditions can be combined with {{{and}}}:
     1306
     1307{{{
     1308#!mapcss
     1309@media (min-josm-version: 6970) and (max-josm-version: 7014) {
     1310 /* only for JOSM versions 6970 to 7014 */
     1311}
     1312}}}
     1313
     1314Multiple combined conditions can be chained with a comma (logical ''or''):
     1315
     1316{{{
     1317#!mapcss
     1318@media (min-josm-version: 6970) and (max-josm-version: 7014), (user-agent: myEditor) {
     1319  /* for JOSM version 6970 to 7014 and for the editor called "myEditor" */
     1320}
     1321}}}
     1322
     1323Since media queries are only supported in JOSM 6970 and later, you should also specify this as minimum JOSM version in the meta selector:
     1324
     1325{{{
     1326#!mapcss
     1327meta {
     1328    min-josm-version: "6970"; /* This style uses media queries */
     1329    /* ... */
     1330}
     1331}}}
     1332
     1333
     1334{{{#!comment
     1335There is also the {{{not}}} keyword (see the linked css doc for details).
     1336This is implemented, but probably not very useful. Feel free to add documentation.
     1337}}}