featurestyles.rst 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. .. _ysld_reference_featurestyles:
  2. Feature Styles
  3. ==============
  4. In YSLD, a Feature Style is a block of styling :ref:`Rules <ysld_reference_rules>`. The Feature Style is applied to a single feature type and drawn in an off-screen buffer.
  5. .. figure:: img/feature-style.*
  6. The feature style element
  7. **The purpose of a Feature Style is to specify drawing order.** The buffer for the first Feature Style will be drawn first, while buffer for the second Feature Style will be processed after that, etc. When drawing is complete the buffers will composed into the final drawn map.
  8. A Feature Style is a **top-level element** in a YSLD style.
  9. Consider the following hierarchy:
  10. * Feature Style 1
  11. * Rule 1a
  12. * Rule 1b
  13. * Feature Style 2
  14. * Rule 2a
  15. * Rule 2b
  16. * Rule 2c
  17. In this case, the rules contained inside Feature Style 1 will be processed and their :ref:`symbolizers <ysld_reference_symbolizers>` drawn first. After Rule 1a and 1b are processed, the renderer will move on to Feature Style 2, where Rule 2a, 2b, and 2c will then be processed and their symbolizers drawn.
  18. .. figure:: img/feature-style-order.*
  19. Feature style order
  20. Drawing order
  21. -------------
  22. The order of feature styles is significant, and also the order of rules inside feature styles is significant.
  23. Rules inside a feature style are all applied to each feature at once. After all of the rules in a feature style have been applied to each feature, the next feature style will start again, applying rules to each feature.
  24. The off-screen buffer for each feature style is merged together during composition. These buffers are merged in the order defined by the feature styles. In this way, **using multiple feature styles is a way of specifying z-order**.
  25. Consider the same hierarchy as above. Given a layer that contains three features, the rules will be applied as follows:
  26. Feature style 1 will draw an off-screen buffer:
  27. #. Rule 1a is applied to the first feature, followed by rule 1b
  28. #. Rule 1a is applied to the second feature, followed by rule 1b
  29. #. Rule 1a is applied to the third feature, followed by rule 1b
  30. .. figure:: img/draw-order-buffer1.*
  31. Feature style 1 buffer
  32. Feature style 2 will draw an off-screen buffer:
  33. #. Rule 2a is applied to the first feature, followed by rule 2b and then rule 2c
  34. #. Rule 2a is applied to the second feature, followed by rule 2b and then rule 2c
  35. #. Rule 2a is applied to the third feature, followed by rule 2b and then rule 2c
  36. .. figure:: img/draw-order-buffer2.*
  37. Feature style 2 buffer
  38. This final map is produced by composition:
  39. #. The buffer for feature style 1 is drawn
  40. #. The buffer for feature style 2 is drawn
  41. #. Any labeling is drawn on top
  42. .. figure:: img/draw-order-map.*
  43. Composition of both feature styles
  44. **If you need a rule to apply on top of other rules, use a second feature style.** A useful case for this is for lines representing bridges or overpasses. In order to ensure that the bridge lines always display on "top" of other lines (which in a display that includes, they would need to be applied using a second feature style.)
  45. Syntax
  46. ------
  47. The following is the basic syntax of a feature style. Note that the contents of the block are not all expanded here.
  48. .. code-block:: yaml
  49. feature-styles:
  50. - name: <text>
  51. title: <text>
  52. abstract: <text>
  53. transform:
  54. ...
  55. rules:
  56. - ...
  57. x-ruleEvaluation: <text>
  58. x-composite: <text>
  59. x-composite-base: <boolean>
  60. x-inclusion: <text>
  61. where:
  62. .. list-table::
  63. :class: non-responsive
  64. :header-rows: 1
  65. :stub-columns: 1
  66. :widths: 20 10 50 20
  67. * - Property
  68. - Required?
  69. - Description
  70. - Default value
  71. * - ``name``
  72. - No
  73. - Internal reference to the feature style. It is recommended that the value be **lower case** and contain **no spaces**.
  74. - Blank
  75. * - ``title``
  76. - No
  77. - Human-readable name of the feature style. Exposed as a name for the group of rules contained in the feature style.
  78. - Blank
  79. * - ``abstract``
  80. - No
  81. - Longer description of the feature style.
  82. - Blank
  83. * - ``transform``
  84. - No
  85. - :ref:`Rendering transformation <ysld_reference_transforms>` information.
  86. - N/A
  87. * - ``rules``
  88. - Yes
  89. - List of styling :ref:`rules <ysld_reference_rules>`.
  90. - N/A
  91. The following properties are equivalent to SLD "vendor options".
  92. .. list-table::
  93. :class: non-responsive
  94. :header-rows: 1
  95. :stub-columns: 1
  96. :widths: 20 10 50 20
  97. * - Property
  98. - Required?
  99. - Description
  100. - Default value
  101. * - ``x-ruleEvaluation``
  102. - No
  103. - When equals to ``first`` - stops rule evaluation after the first match. Can make the rendering more efficient by reducing the number of rules that need to be traversed by features, as well as simplyfing the rule filters.
  104. - ``all``
  105. * - ``x-composite``
  106. - No
  107. - Allows for both alpha compositing and color blending options between buffers. There are many options; :ref:`see below <ysld_reference_featurestyles_composite>`.
  108. - N/A
  109. * - ``x-composite-base``
  110. - No
  111. - Allows the rendering engine to use that feature-style as a "base", and will compose all subsequent feature-styles and layers on top of it, until another base is found. Once the full set of layers against a base is composed, then the base itself will be composed against the next set of composed layers using its own compositing operator, if present. This is useful to fine-tune the use of ``x-composite``, and to make sure that only the desired content is composited/blended and not all of the drawn content.
  112. - ``false``
  113. * - ``x-inclusion``
  114. - No
  115. - Define if rule should be included in style for ``legendOnly`` or ``mapOnly`` (see :ref:`rendering_selection`)
  116. - ``normal``
  117. .. _ysld_reference_featurestyles_composite:
  118. Compositing and blending
  119. ------------------------
  120. By default, multiple feature styles are drawn with one buffer on top of the other. However, using the ``x-composite`` and ``x-composite-base`` options, one can customize the way that buffers are displayed.
  121. The following two tables show the possible alpha compositing and color blending values for the ``x-composite`` option. Note that in the tables below, **source** refers to the buffer that is drawn on top, while **destination** refers to the buffer that the source is drawn on top of.
  122. .. todo:: Add image showing source and destination
  123. **Alpha compositing**
  124. Alpha compositing controls how buffers are merged using the transparent areas of each buffer.
  125. .. list-table::
  126. :class: non-responsive
  127. :header-rows: 1
  128. :stub-columns: 1
  129. :widths: 20 80
  130. * - Value
  131. - Description
  132. * - ``copy``
  133. - Only the source will be present in the output.
  134. .. image:: img/composite-source.*
  135. * - ``destination``
  136. - Only the destination will be present in the output.
  137. .. image:: img/composite-destination.*
  138. * - ``source-over``
  139. - The source is drawn over the destination, and the destination is visible where the source is transparent. Opposite of ``destination-over``. This is the default value for x-composite.
  140. .. image:: img/composite-source-over.*
  141. * - ``destination-over``
  142. - The source is drawn below the destination, and is visible only when the destination is transparent. Opposite of ``source-over``.
  143. .. image:: img/composite-destination-over.*
  144. * - ``source-in``
  145. - The source is visible only when overlapping some non-transparent pixel of the destination. This allows the background map to act as a mask for the layer/feature being drawn. Opposite of ``destination-in``.
  146. .. image:: img/composite-source-in.*
  147. * - ``destination-in``
  148. - The destination is retained only when overlapping some non transparent pixel in the source. This allows the layer/feature to be drawn to act as a mask for the background map. Opposite of ``source-in``.
  149. .. image:: img/composite-destination-in.*
  150. * - ``source-out``
  151. - The source is retained only in areas where the destination is transparent. This acts as a reverse mask when compared to ``source-in``.
  152. .. image:: img/composite-source-out.*
  153. * - ``destination-out``
  154. - The destination is retained only in areas where the source is transparent. This acts as a reverse mask when compared to ``destination-in``.
  155. .. image:: img/composite-destination-out.*
  156. * - ``source-atop``
  157. - The destination is drawn fully, while the source is drawn only where it intersects the destination.
  158. .. image:: img/composite-source-atop.*
  159. * - ``destination-atop``
  160. - The source is drawn fully, and the destination is drawn over the source only where it intersects it.
  161. .. image:: img/composite-destination-atop.*
  162. * - ``xor``
  163. - "Exclusive Or" mode. Each pixel is rendered only if either the source or the destination is not blank, but not both.
  164. .. image:: img/composite-xor.*
  165. **Color blending**
  166. Color blending allows buffers to be mixed during composition.
  167. .. list-table::
  168. :class: non-responsive
  169. :header-rows: 1
  170. :stub-columns: 1
  171. :widths: 20 80
  172. * - Value
  173. - Description
  174. * - ``multiply``
  175. - The source color is multiplied by the destination color and replaces the destination. The resulting color is always at least as dark as either the source or destination color. Multiplying any color with black results in black. Multiplying any color with white preserves the original color.
  176. .. image:: img/blend-multiply.png
  177. * - ``screen``
  178. - Multiplies the complements of the source and destination color values, then complements the result. The end result color is always at least as light as either of the two constituent colors. Screening any color with white produces white; screening with black leaves the original color unchanged.
  179. .. image:: img/blend-screen.png
  180. * - ``overlay``
  181. - Multiplies the colors depending on the destination color value. Source colors overlay the destination while preserving highlights and shadows. The backdrop color is not replaced but is mixed with the source color to reflect the lightness or darkness of the backdrop.
  182. .. image:: img/blend-overlay.png
  183. * - ``darken``
  184. - Selects the darker of the destination and source colors. The destination is replaced with the source only where the source is darker.
  185. .. image:: img/blend-darken.png
  186. * - ``lighten``
  187. - Selects the lighter of the destination and source colors. The destination is replaced with the source only where the source is lighter.
  188. .. image:: img/blend-lighten.png
  189. * - ``color-dodge``
  190. - Brightens the destination color to reflect the source color. Drawing with black produces no changes.
  191. .. image:: img/blend-color-dodge.png
  192. * - ``color-burn``
  193. - Darkens the destination color to reflect the source color. Drawing with white produces no change.
  194. .. image:: img/blend-color-burn.png
  195. * - ``hard-light``
  196. - Multiplies the colors, depending on the source color value. The effect is similar to shining a harsh spotlight on the destination.
  197. .. image:: img/blend-hard-light.png
  198. * - ``soft-light``
  199. - Darkens or lightens the colors, depending on the source color value. The effect is similar to a diffused spotlight on the destination.
  200. .. image:: img/blend-soft-light.png
  201. * - ``difference``
  202. - Subtracts the darker of the two constituent colors from the lighter color. White inverts the destination color; black produces no change.
  203. .. image:: img/blend-difference.png
  204. * - ``exclusion``
  205. - Produces an effect similar to that of difference but lower in contrast. White inverts the destination color; black produces no change.
  206. .. image:: img/blend-difference.png
  207. .. note:: For more details about the compositing and blending options, please see :ref:`sld-extensions_composite-blend_modes`.
  208. Short syntax
  209. ------------
  210. When a style has a single feature style, it is possible to omit the syntax for the feature style and start at the first parameter inside.
  211. So the following complete styles are both equivalent:
  212. .. code-block:: yaml
  213. feature-styles:
  214. - rules:
  215. - name: rule1
  216. scale: [min,50000]
  217. symbolizers:
  218. - line:
  219. stroke-color: '#000000'
  220. stroke-width: 2
  221. - name: rule2
  222. scale: [50000,max]
  223. symbolizers:
  224. - line:
  225. stroke-color: '#000000'
  226. stroke-width: 1
  227. .. code-block:: yaml
  228. rules:
  229. - name: rule1
  230. scale: [min,50000]
  231. symbolizers:
  232. - line:
  233. stroke-color: '#000000'
  234. stroke-width: 2
  235. - name: rule2
  236. scale: [50000,max]
  237. symbolizers:
  238. - line:
  239. stroke-color: '#000000'
  240. stroke-width: 1
  241. Examples
  242. --------
  243. Road casing
  244. ~~~~~~~~~~~
  245. This example shows how a smaller line can be drawn on top of a larger line, creating the effect of lines being drawn with a border or "casing":
  246. .. code-block:: yaml
  247. feature-styles:
  248. - name: outer
  249. title: Outer line
  250. rules:
  251. - name: outer_rule
  252. symbolizers:
  253. - line:
  254. stroke-color: '#808080'
  255. stroke-width: 8
  256. - name: inner
  257. title: Inner line
  258. rules:
  259. - name: inner_rule
  260. symbolizers:
  261. - line:
  262. stroke-color: '#44FF88'
  263. stroke-width: 6
  264. To draw the inner lines always on top of the outer lines we need to control the **z-order**. The ``outer_rule`` is encased in its own feature style and drawn into a distinct "Outer line" buffer. Next the ``inner_rule`` is encased in its own feature style and drawn into a distinct "Inner line" buffer.
  265. .. figure:: img/line-casing-buffers.*
  266. Feature style buffers
  267. During composition these two off-screen buffers are combined into the final map.
  268. .. figure:: img/line-casing-map.*
  269. Final map composition
  270. When drawn, the outer line has a width of 8 pixels and the inner line has a width of 6 pixels, so the line "border" is 1 pixel (on each side).
  271. .. figure:: img/fs_roadcasing.*
  272. Example showing road casing
  273. First match
  274. ~~~~~~~~~~~
  275. Given a style that has many rules with distinct outcomes, it may be advantageous to employ ``x-ruleEvaluation: first`` so as to improve rendering efficiency and simplify those rules.
  276. This first example shows the standard way of creating rules for a dataset. There are villages, towns, and cities (``type = 'village'``, ``type = 'town'`` or ``type = 'city'``) and they have an ``industry`` which could be either ``fishing`` or other values.
  277. .. note:: In order to simplify this example, the specifics of the point symbolizers have been replaced by :ref:`ysld_reference_variables`. In a real-world example, these would need to be defined in the YSLD as well.
  278. .. code-block:: yaml
  279. :linenos:
  280. :emphasize-lines: 15
  281. feature-styles:
  282. - name: without_first_match
  283. rules:
  284. - name: fishing_town
  285. filter: ${type = 'town' AND industry = 'fishing'}
  286. symbolizers:
  287. - point:
  288. <<: *fishingtown
  289. - name: fishing_city
  290. filter: ${type = 'city' AND industry = 'fishing'}
  291. symbolizers:
  292. - point:
  293. <<: *fishingcity
  294. - name: other_towns_cities
  295. filter: ${type IN ('town', 'city') AND industry <> 'fishing'}
  296. symbolizers:
  297. - point:
  298. <<: *othertownscities
  299. - name: other
  300. else: true
  301. symbolizers:
  302. - point:
  303. <<: *allotherplaces
  304. Using the ``x-ruleEvaluation: first`` parameter, the style is simplified:
  305. .. code-block:: yaml
  306. :linenos:
  307. :emphasize-lines: 3,16
  308. feature-styles:
  309. - name: with_first_match
  310. x-ruleEvaluation: first
  311. rules:
  312. - name: fishing_town
  313. filter: ${type = 'town' AND industry = 'fishing'}
  314. symbolizers:
  315. - point:
  316. <<: *fishingtown
  317. - name: fishing_city
  318. filter: ${type = 'city' AND industry = 'fishing'}
  319. symbolizers:
  320. - point:
  321. <<: *fishingcity
  322. - name: other_towns_cities
  323. filter: ${type IN ('town', 'city')}
  324. symbolizers:
  325. - point:
  326. <<: *othertownscities
  327. - name: other
  328. else: true
  329. symbolizers:
  330. - point:
  331. <<: *allotherplaces
  332. Specifically, the third rule no longer needs the extra ``AND industry <> 'fishing'``, because the previous two rules imply that any features remaining by this rule have that condition.
  333. Layer mask
  334. ~~~~~~~~~~
  335. Given two layers (in this case, two three-band rasters), one can mask or "knock out" the other, making visible what's beneath.
  336. .. figure:: img/fs_land.png
  337. Top/source layer
  338. .. figure:: img/fs_ocean.png
  339. Bottom/destination layer
  340. .. note:: Screenshots show data provided by `Natural Earth <http://naturalearthdata.com>`_.
  341. Layer 1 (top/source):
  342. .. code-block:: yaml
  343. :linenos:
  344. :emphasize-lines: 7
  345. feature-styles:
  346. - rules:
  347. - title: Top/source
  348. symbolizers:
  349. - raster:
  350. opacity: 1.0
  351. x-composite: xor
  352. Layer 2 (bottom/destination):
  353. .. code-block:: yaml
  354. :linenos:
  355. feature-styles:
  356. - rules:
  357. - title: Bottom/destination
  358. symbolizers:
  359. - raster:
  360. opacity: 1.0
  361. .. figure:: img/fs_xor.png
  362. Layer as mask
  363. Color inversion
  364. ~~~~~~~~~~~~~~~
  365. Given the same two layers as the previous example, one can display the difference of the colors of layers, which can have the effect of a color "inversion".
  366. Layer 1 (top/source):
  367. .. code-block:: yaml
  368. :linenos:
  369. :emphasize-lines: 7
  370. feature-styles:
  371. - rules:
  372. - title: Top/source
  373. symbolizers:
  374. - raster:
  375. opacity: 1.0
  376. x-composite: difference
  377. Layer 2 (bottom/destination):
  378. .. code-block:: yaml
  379. :linenos:
  380. feature-styles:
  381. - rules:
  382. - title: Bottom/destination
  383. symbolizers:
  384. - raster:
  385. opacity: 1.0
  386. .. figure:: img/fs_difference.png
  387. Layer as color inversion