index.rst 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. .. _community_graticule:
  2. Graticule Extension
  3. ===================
  4. This module allows GeoServer to add graticules or grids to a WMS (or to allow them to be downloaded as WFS).
  5. The extension includes a vector process that can transform the grid lines to label points based on a bounding box, to allow
  6. adding labels in WMS images (this reqiures the WPS module to be present).
  7. Installing the graticule extension
  8. -----------------------------------
  9. #. Download the graticule extension from the `nightly GeoServer community module builds <https://build.geoserver.org/geoserver/main/community-latest/>`_.
  10. .. warning:: Make sure to match the version of the extension to the version of the GeoServer instance!
  11. #. Extract the contents of the archive into the ``WEB-INF/lib`` directory of the GeoServer installation.
  12. Checking if the extension is enabled
  13. ------------------------------------
  14. Once the extension is installed, the new graticule store should show up in the ``New data source`` page:
  15. .. figure:: images/graticule-store.png
  16. :align: center
  17. Creating a Graticule Data Source
  18. --------------------------------
  19. A new graticule store is created by providing a name, optional description and the a bounding box (which can be calculated automatically from the CRS),
  20. a Coordinate Reference System and a series of steps separated by commas.
  21. The bounding box will set the limits of the grid when the user has zoomed out to small scales, while the CRS will be used to determine the values of
  22. the grid lines. The list of steps will be used to provide a more detailed grid as the user zooms in to larger scale maps. Each step is used to define
  23. a level of grid with a gap of *step* units between the gaps.
  24. .. figure:: images/completed-graticule-store.png
  25. :align: center
  26. Creating a new style for graticule
  27. ----------------------------------
  28. Displaying a graticule in a sensible way will require creating a custom style to control
  29. the line appearance, the labels, and the visualization hierarchy if multiple levels of
  30. graticule are used. This can lead to complex styles, which can be tamed by leveraging
  31. the available attributes along with filter functions.
  32. Let's assume one has a graticule with 5 levels of lines at different resolutions (e.g., 1, 5, 10, 20 and 30 degrees spacing),
  33. and wants to display them as follows:
  34. * level 0: scale denominator lower than 1M
  35. * level 1: scale denominator between 1M and 20M
  36. * level 2: scale denominator between 20M and 100M
  37. * level 3: scale denominator between 10M and 400M
  38. * level 4: scale denominator higher than 400M
  39. The following style would be used, using a single Rule, by leveraging the ``Categorize`` function
  40. along with the ``wms_scale_denominator`` environment variable (:ref:`sld_variable_substitution`):
  41. .. code-block:: xml
  42. <?xml version="1.0" encoding="ISO-8859-1"?>
  43. <StyledLayerDescriptor version="1.0.0"
  44. xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd"
  45. xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc"
  46. xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  47. <NamedLayer>
  48. <Name>graticule</Name>
  49. <UserStyle>
  50. <FeatureTypeStyle>
  51. <Name>name</Name>
  52. <Rule>
  53. <ogc:Filter>
  54. <ogc:PropertyIsEqualTo>
  55. <ogc:PropertyName>level</ogc:PropertyName>
  56. <ogc:Function name="Categorize">
  57. <ogc:Function name="env"><ogc:Literal>wms_scale_denominator</ogc:Literal></ogc:Function>
  58. <ogc:Literal>0</ogc:Literal>
  59. <ogc:Literal>1000000</ogc:Literal>
  60. <ogc:Literal>1</ogc:Literal>
  61. <ogc:Literal>20000000</ogc:Literal>
  62. <ogc:Literal>2</ogc:Literal>
  63. <ogc:Literal>100000000</ogc:Literal>
  64. <ogc:Literal>3</ogc:Literal>
  65. <ogc:Literal>400000000</ogc:Literal>
  66. <ogc:Literal>4</ogc:Literal>
  67. </ogc:Function>
  68. </ogc:PropertyIsEqualTo>
  69. </ogc:Filter>
  70. <LineSymbolizer>
  71. <Stroke>
  72. <CssParameter name="stroke">#666666</CssParameter>
  73. <CssParameter name="stroke-dasharray">2.0 2.0</CssParameter>
  74. </Stroke>
  75. </LineSymbolizer>
  76. </Rule>
  77. </FeatureTypeStyle>
  78. </UserStyle>
  79. </NamedLayer>
  80. </StyledLayerDescriptor>
  81. If some important lines are meant to be displayed with solid line rather than dashed, it's possible
  82. to use a function to keep the style compact, rather than duplicating the whole rule. The following
  83. example makes the equator and the prime meridian solid lines, while keeping the rest dashed:
  84. .. code-block:: xml
  85. <LineSymbolizer>
  86. <Stroke>
  87. <CssParameter name="stroke">#666666</CssParameter>
  88. <CssParameter name="stroke-dasharray">
  89. <ogc:Function name="if_then_else">
  90. <ogc:Function name="equalTo">
  91. <ogc:PropertyName>value</ogc:PropertyName>
  92. <ogc:Literal>0</ogc:Literal>
  93. </ogc:Function>
  94. <ogc:Literal>0</ogc:Literal>
  95. <ogc:Literal>3 3</ogc:Literal>
  96. </ogc:Function>
  97. </CssParameter>
  98. </Stroke>
  99. </LineSymbolizer>
  100. Finally, labelling can be a tricky job. A rendering transform is provided to help with this,
  101. ``vec:GraticuleLabelPoint``, which will take the grid lines and return a point at ends of each
  102. gridline, preserving the attributes of the original line, but adding extra ones that can be used
  103. to simplify the labelling process:
  104. * "top" indicates if a label is at the top of the line (true) or at the bottom (false) of a vertical line
  105. * "left" indicates if a label is at the left of the line (true) or at the right (false) of a horizontal line
  106. * "anchorX", "anchorY" provides a suitable value to anchor the label inside the grid
  107. * "offsetX" and "offsetY" provides a suitable value to offset the label from the anchor point, again to keep labels inside the grid
  108. The process itself takes the following parameters:
  109. * "grid" is the grid lines being processed (the graticule layer).
  110. * "boundingBox" is the bounding box of the map being rendered, which is used to clip lines and to calculate the label points. This parameter is optional, if missing the labels will be generated at the end of the graticule lines no matter what the display area is. For un-tiled maps, the usage of "boundingBox" helps having the labels as a reference in every map, while for tiled maps it's better to omit it, or the labels will be repeated at the border of every (meta)tile.
  111. * "offset" is the offset of the label from the grid line (used to compute the values of "offsetX" and "offsetY"), which can be provided using the current request bounding box using the ``wms_bbox`` environment variable (:ref:`sld_variable_substitution`).
  112. * "positions" indicates which groups of labels should be generated, and can be one of "top", "bottom", "left", "right" or "topleft", "topright", "bottomleft", "bottomright", or the default value "both" which generates labels on all four sides of the map.
  113. Leveraging this process, the labels can be generated using the following style:
  114. .. code-block:: xml
  115. <FeatureTypeStyle>
  116. <Name>label</Name>
  117. <Transformation>
  118. <ogc:Function name="vec:GraticuleLabelPoint">
  119. <ogc:Function name="parameter">
  120. <ogc:Literal>grid</ogc:Literal>
  121. </ogc:Function>
  122. <ogc:Function name="parameter">
  123. <ogc:Literal>boundingBox</ogc:Literal>
  124. <ogc:Function name="env">
  125. <ogc:Literal>wms_bbox</ogc:Literal>
  126. </ogc:Function>
  127. </ogc:Function>
  128. <ogc:Function name="parameter">
  129. <ogc:Literal>offset</ogc:Literal>
  130. <ogc:Literal>4</ogc:Literal>
  131. </ogc:Function>
  132. </ogc:Function>
  133. </Transformation>
  134. <Rule>
  135. <TextSymbolizer>
  136. <Label>
  137. <ogc:PropertyName>label</ogc:PropertyName>
  138. </Label>
  139. <Font>
  140. <CssParameter name="font-family">Noto Sans</CssParameter>
  141. <CssParameter name="font-size">12</CssParameter>
  142. <CssParameter name="font-style">normal</CssParameter>
  143. </Font>
  144. <LabelPlacement>
  145. <PointPlacement>
  146. <AnchorPoint>
  147. <AnchorPointX><ogc:PropertyName>anchorX</ogc:PropertyName></AnchorPointX>
  148. <AnchorPointY><ogc:PropertyName>anchorY</ogc:PropertyName></AnchorPointY>
  149. </AnchorPoint>
  150. <Displacement>
  151. <DisplacementX><ogc:PropertyName>offsetX</ogc:PropertyName></DisplacementX>
  152. <DisplacementY><ogc:PropertyName>offsetY</ogc:PropertyName></DisplacementY>
  153. </Displacement>
  154. </PointPlacement>
  155. </LabelPlacement>
  156. <Halo>
  157. <Radius>1</Radius>
  158. <Fill>
  159. <CssParameter name="fill">#FFFFFF</CssParameter>
  160. </Fill>
  161. </Halo>
  162. <Fill>
  163. <CssParameter name="fill">#000000</CssParameter>
  164. </Fill>
  165. <VendorOption name="partials">true</VendorOption>
  166. </TextSymbolizer>
  167. </Rule>
  168. </FeatureTypeStyle>