Templates With FreeMarker ------------------------- MapML templates are written in `Freemarker `_ , a Java-based template engine. The templates below are feature type specific and will not be applied in multi-layer WMS requests. See :ref:`tutorial_freemarkertemplate` for general information about FreeMarker implementation in GeoServer. MapML supports the following template types: +----------------------------+--------------------------------------------------------------------------------------+ | Template File Name | Purpose | +============================+======================================================================================+ | ``mapml-preview-head.ftl`` | Used to insert stylesheet links or elements into the MapML HTML preview viewer. | +----------------------------+--------------------------------------------------------------------------------------+ | ``mapml-head.ftl`` | Used to insert ``mapml-link`` elements into the MapML map-head section. | +----------------------------+--------------------------------------------------------------------------------------+ | ``mapml-feature-head.ftl`` | Used to insert ``map-style`` elements into a MapML feature document. | +----------------------------+--------------------------------------------------------------------------------------+ | ``mapml-feature.ftl`` | Used to rewrite MapML features, with ability to change attributes, styles, | | | geometries, and add links | +----------------------------+--------------------------------------------------------------------------------------+ GetMap MapML HTML Preview/Layer Preview Head Stylesheet Templating ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The preview is returned when the format includes ``subtype=mapml``. The preview is an HTML document that includes a ``head`` section with a link to the stylesheet. The default preview viewer is a simple viewer that includes a link to the default stylesheet. A template can be created to insert links to whole stylesheet or actual stylesheet elements. We can do this by creating a file called ``mapml-preview-head.ftl`` in the GeoServer data directory in the directory for the layer that we wish to append links to. For example we could create this file under ``workspaces/topp/states_shapefile/states``. To add stylesheet links and stylesheet elements, we enter the following text inside this new file: .. code-block:: html This would result in a head section that would resemble: .. code-block:: html USA Population GetMap MapML Head Stylesheet Templating ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The MapML format includes a map-head element that includes map-link elements to link to other resources, including map style variants. Additional map-link elements can be added to the map-head element by creating a ``mapml-head.ftl`` template in the GeoServer data directory in the directory for the layer we wish to append map-links to. For example we could create the ``mapml-head.ftl`` file under ``workspaces/tiger/nyc/poly_landmarks_shapefile/poly_landmarks``: .. code-block:: bash .polygon-r1-s1{stroke-opacity:3.0; stroke-dashoffset:4; stroke-width:2.0; fill:#AAAAAA; fill-opacity:3.0; stroke:#DD0000; stroke-linecap:butt} This would result in a map-head section that would resemble (note the inserted css styles and map-link): .. code-block:: html Manhattan (NY) landmarks .bbox {display:none} .poly_landmarks-r1-s1{stroke-opacity:1.0; stroke-dashoffset:0; stroke-width:1.0; fill:#B4DFB4; fill-opacity:1.0; stroke:#88B588; stroke-linecap:butt} .poly_landmarks-r2-s1{stroke-opacity:1.0; stroke-dashoffset:0; stroke-width:1.0; fill:#8AA9D1; fill-opacity:1.0; stroke:#436C91; stroke-linecap:butt} .poly_landmarks-r3-s1{stroke-opacity:1.0; stroke-dashoffset:0; stroke-width:1.0; fill:#FDE5A5; fill-opacity:0.75; stroke:#6E6E6E; stroke-linecap:butt} .polygon-r1-s1{stroke-opacity:3.0; stroke-dashoffset:4; stroke-width:2.0; fill:#AAAAAA; fill-opacity:3.0; stroke:#DD0000; stroke-linecap:butt} GetMap Features Inline Style Class Templating ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ MapML in feature format (when the parameter format_options=mapmlfeatures:true is set) has a map-head element that includes map-style elements where the style classes are defined. Within the map-body, map-feature elements include map-geometry with map-coordinates. The ``mapml-feature-head.ftl`` is a file that can be used to insert map-style elements with the style class definitions. This file is placed in the GeoServer data directory in the directory for the layer we wish to append style classes to. For example we could create the file under ``workspaces/tiger/nyc/poly_landmarks_shapefile/poly_landmarks``. The ``mapml-feature-head.ftl`` file would look like:: .desired {stroke-dashoffset:3} This would result in a MapML feature output header that would resemble: .. code-block:: xml poi .bbox {display:none} .polygon-r1-s1{stroke-opacity:1.0; stroke-dashoffset:0; stroke-width:1.0; fill:#AAAAAA; fill-opacity:1.0; stroke:#000000; stroke-linecap:butt} .desired {stroke-dashoffset:3} The ``mapml-feature.ftl`` is a file can be used to insert map-style elements with the style class definitions into the map-head. Note that this section of the template adds the styles listed but does not remove any existing styles. It can be used to edit map-property names and values in a manner similar to :ref:`tutorials_getfeatureinfo_geojson`. Note that this template represents a full replacement of the feature. If there are attributes that need to be included without change, they need to be referenced in the template. It also can be used to add style class identifiers to map-feature elements based on the feature identifier or to wrap groupings of map-coordinates with spans that specify the style class based on an index of coordinate order (zero based index that starts at the first coordinate pair of each feature). This file is placed in the GeoServer data directory in the directory for the layer we wish to append style classes to. For example we could create the file under ``workspaces/tiger/poly_landmarks_shapefile/poly_landmarks``. An example ``mapml-feature.ftl`` file to modify a point layer would look like:: <#list attributes as attribute> <#if attribute.name == "MAINPAGE"> <#else> <#list attributes as gattribute> <#if gattribute.isGeometry> <#if attributes.NAME.value == "museam"> <#list gattribute.rawValue.coordinates as coord>${coord.x} ${coord.y} <#if attributes.NAME.value == "museam"> This would result in a MapML feature output body that would resemble this fragment:: poi .bbox {display:none} .poi-r1-s1{r:88.0; well-known-name:circle; opacity:1.0; fill:#FF0000; fill-opacity:1.0} .poi-r1-s2{r:56.0; well-known-name:circle; opacity:1.0; fill:#FFFFFF; fill-opacity:1.0} -74.01046109936 40.70758762626
Property name Property value
CHANGED MAINPAGE UPDATED pics/22037827-L.jpg
Note that in addition to tagging the coordinates with a style class, the template also changes the name of the MAINPAGE property to "UPDATED MAINPAGE" and the value to "CHANGED pics/22037827-L.jpg". For linestring features the template would look like:: <#list attributes as attribute> <#if attribute.isGeometry> <#if attributes.NAME.value == "Washington Sq W"> <#list attribute.rawValue.coordinates as coord> ${coord.x} ${coord.y} <#if attributes.NAME.value == "Washington Sq W"> For polygon features the template would look like:: <#list attributes as attribute> <#if attribute.isGeometry> <#assign shell = attribute.rawValue.getExteriorRing()> <#list shell.coordinates as coord> ${coord.x} ${coord.y} <#list 0 ..< attribute.rawValue.getNumInteriorRing() as index> <#assign hole = attribute.rawValue.getInteriorRingN(index)><#list hole.coordinates as coord> ${coord.x} ${coord.y} For multipoint features the template would look like:: <#list attributes as gattribute> <#if gattribute.isGeometry> <#list 0 ..< gattribute.rawValue.getNumGeometries() as index> <#assign point = gattribute.rawValue.getGeometryN(index)> <#list point.coordinates as coord> ${coord.x} ${coord.y} For multiline features the template would like:: <#list attributes as attribute> <#if attribute.isGeometry> <#list 0 ..< attribute.rawValue.getNumGeometries() as index> <#assign line = attribute.rawValue.getGeometryN(index)> <#list line.coordinates as coord> ${coord.x} ${coord.y} For multipolygon features the template would like:: <#if attributes.LAND.value == "72.0"> <#list attributes as attribute> <#if attribute.isGeometry> <#list 0 ..< attribute.rawValue.getNumGeometries() as index> <#assign polygon = attribute.rawValue.getGeometryN(index)> <#assign shell = polygon.getExteriorRing()> <#list shell.coordinates as coord> ${coord.x} ${coord.y} <#list 0 ..< polygon.getNumInteriorRing() as index> <#assign hole = polygon.getInteriorRingN(index)> <#list hole.coordinates as coord> ${coord.x} ${coord.y} <#else> <#list attributes as attribute> <#if attribute.isGeometry> <#list 0 ..< attribute.rawValue.getNumGeometries() as index> <#assign polygon = attribute.rawValue.getGeometryN(index)> <#assign shell = polygon.getExteriorRing()> <#list shell.coordinates as coord> ${coord.x} ${coord.y} <#list 0 ..< polygon.getNumInteriorRing() as index> <#assign hole = polygon.getInteriorRingN(index)> <#list hole.coordinates as coord> ${coord.x} ${coord.y} Templates can also be used to create MapML GeometryCollections that consist of multiple geometry types. For example, a template that creates a GeometryCollection that contains points and linestring representations of the NYC TIGER POI sample data would look like:: <#list attributes as attribute> <#if attribute.isGeometry> <#list attribute.rawValue.coordinates as coord> ${coord.x} ${coord.y} <#list attribute.rawValue.coordinates as coord> ${coord.x} ${coord.y} This would result in a MapML feature output body that would resemble:: poi .bbox {display:none} .poi-r1-s1{r:88.0; well-known-name:circle; opacity:1.0; fill:#FF0000; fill-opacity:1.0} .poi-r1-s2{r:56.0; well-known-name:circle; opacity:1.0; fill:#FFFFFF; fill-opacity:1.0} -74.00857344353 40.71194564907 -74.00857344353 40.71194564907
Property name Property value
NAME lox
THUMBNAIL pics/22037884-Ti.jpg
MAINPAGE pics/22037884-L.jpg