Template-Driven Output¶
- Author:
Chris Hodgson
- Contact:
chodgson at refractions.net
- Author:
Seth Girvin
- Contact:
sethg at geographika.co.uk
- Last Updated:
2019-10-04
Introduction¶
RFC 36 added support for defining template-driven OUTPUTFORMATs for use with feature queries, including WMS GetFeatureInfo and WFS GetFeature. This allows for custom text-oriented output such as GeoJSON, KML, or XML. The templates are essentially the same as with the standard MapServer query Templating, however there are some additional tags to allow for template definition in a single file instead of the standard header/template/footer.
Note
There are other, simpler, ways to output some of these formats using MapServer. However, template-driven output provides maximal flexibility and customization of the output, at the cost of additional complexity and configuration.
Note
In order for template-driven output to work, layers that are to be output need to have the TEMPLATE key word included:
TEMPLATE "dummy"
Note
In order for template-driven output to work through WFS, the format needs to be listed in wfs_getfeature_formatlist in the WEB METATDATA section or the LAYER METATDATA section (the geojson format from the example below):
"wfs_getfeature_formatlist" "gml,geojson"
OUTPUTFORMAT Declarations¶
Details of template-driven output formats are controlled by an OUTPUTFORMAT declaration. The declarations define the template file to be used, as well as other standard OUTPUTFORMAT options.
Examples:
OUTPUTFORMAT
NAME "kayml"
DRIVER "TEMPLATE"
MIMETYPE "application/vnd.google-earth.kml+xml"
FORMATOPTION "FILE=myTemplate.kml"
FORMATOPTION "ATTACHMENT=queryResults.kml"
END
OUTPUTFORMAT
NAME "geojson"
DRIVER "TEMPLATE"
FORMATOPTION "FILE=myTemplate.js"
END
OUTPUTFORMAT
NAME "customxml"
DRIVER "TEMPLATE"
FORMATOPTION "FILE=myTemplate.xml"
END
The template file to be used is determined by the “FILE=…” FORMATOPTION. The template filename is relative to the mapfile’s path. As is standard with MapServer template files, the file must contain the magic string ‘mapserver template’ in the first line of the file, usually within a comment, but this line is not output to the client.
Note
Valid suffixes for the template file are: .xml, .wml, .html, .htm, .svg, .kml, .gml, .js, .tmpl.
The MIMETYPE and FORMATOPTION “ATTACHMENT=…” parameters are very useful for controlling how a web browser handles the output file.
Examples¶
Below are some examples of the different kind of outputs that can be achieved with templates.
GML3¶
<!-- mapserver template -->
<?xml version="1.0" encoding="ISO-8859-1"?>
[resultset layer=mums]
<MapServerUserMeetings xmlns="http://localhost/ms_ogc_workshop"
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gml="http://www.opengis.net/gml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://localhost/ms_ogc_workshop ./mums.xsd">
<gml:description>This is a GML document which provides locations of
all MapServer User Meeting that have taken place</gml:description>
<gml:name>MapServer User Meetings</gml:name>
<gml:boundedBy>
<gml:Envelope>
<gml:coordinates>-93.093055556,44.944444444 -75.7,45.4166667</gml:coordinates>
</gml:Envelope>
</gml:boundedBy>
[feature]
<gml:featureMember>
<Meeting>
<gml:description>[desc]</gml:description>
<gml:name>[name]</gml:name>
<gml:location>
<gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
<gml:pos>[x] [y]</gml:pos>
</gml:Point>
</gml:location>
<year>[year]</year>
<venue>[venue]</venue>
<website>[url]</website>
</Meeting>
</gml:featureMember>
[/feature]
<dateCreated>2007-08-13T17:17:32Z</dateCreated>
</MapServerUserMeetings>
[resultset]
GeoJSON¶
Could be called using …&layer=mums&mode=nquery&qformat=geojson
Or by adding &outputformat=geojson to a WFS getfeature request:
// mapserver template
[resultset layer=mums]
{
"type": "FeatureCollection",
"features": [
[feature trimlast=","]
{
"type": "Feature",
"id": "[myuniqueid]",
"geometry": {
"type": "PointLineString",
"coordinates": [
{
"type": "Point",
"coordinates": [[x], [y]]
}
]
},
"properties": {
"description": "[description]",
"venue": "[venue]",
"year": "[year]"
}
},
[/feature]
]
}
[/resultset]
KML¶
A more complicated KML example. Note the use of [shpxy] to support multipolygons with holes, and also that a point placemark is included with each feature using [shplabel]:
<!--MapServer Template-->
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2"
xmlns:gx="http://www.google.com/kml/ext/2.2"
xmlns:kml="http://www.opengis.net/kml/2.2"
xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
<Style id="parks_highlight">
<IconStyle>
<scale>1.4</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/shapes/parks.png</href>
</Icon>
<hotSpot x="0.5" y="0" xunits="fraction" yunits="fraction"/>
</IconStyle>
<LineStyle>
<color>ffff5500</color>
<width>4.2</width>
</LineStyle>
<PolyStyle>
<color>aaaaaaaa</color>
</PolyStyle>
<BalloonStyle>
<text>
<![CDATA[
<p ALIGN="center"><b>$[name]</b></p>
$[description]
]]>
</text>
</BalloonStyle>
</Style>
<Style id="parks_normal">
<IconStyle>
<scale>1.2</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/shapes/parks.png</href>
</Icon>
<hotSpot x="0.5" y="0" xunits="fraction" yunits="fraction"/>
</IconStyle>
<LineStyle>
<color>ffff5500</color>
<width>4.2</width>
</LineStyle>
<PolyStyle>
<color>ff7fff55</color>
</PolyStyle>
<BalloonStyle>
<text>
<![CDATA[
<p ALIGN="center"><b>$[name]</b></p>
$[description]
]]>
</text>
</BalloonStyle>
</Style>
<StyleMap id="parks_map">
<Pair>
<key>normal</key>
<styleUrl>#parks_normal</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#parks_highlight</styleUrl>
</Pair>
</StyleMap>
[resultset layer=parks]
<Folder>
<name>Parks</name>
[feature trimlast="," limit=1]
<Placemark>
<name>[NAME]</name>
<Snippet/>
<description>
<![CDATA[
<p>Year Established: [YEAR_ESTABLISHED]</p>
<p>Area: [AREA_KILOMETERS_SQUARED] sq km</p>
]]>
</description>
<styleUrl>#parks_map</styleUrl>
<ExtendedData>
<Data name="Year Established">[YEAR_ESTABLISHED]</Data>
<Data name="Area">[AREA_KILOMETERS_SQUARED]</Data>
</ExtendedData>
<MultiGeometry>
<Point>
<coordinates>[shplabel proj=epsg:4326 precision=10],0</coordinates>
</Point>
[shpxy ph="<Polygon><tessellate>1</tessellate>" pf="</Polygon>"
xf="," xh=" " yh=" " yf=",0 "
orh="<outerBoundaryIs><LinearRing><coordinates>"
orf="</coordinates></LinearRing></outerBoundaryIs>"
irh="<innerBoundaryIs><LinearRing><coordinates>"
irf="</coordinates></LinearRing></innerBoundaryIs>"
proj=epsg:4326 precision=10]
</MultiGeometry>
</Placemark>
[/feature]
</Folder>
[/resultset]
</Document>
</kml>
reStructuredText Table¶
This example creates a reStructuredText table from feature records, making use of the padding formatting option. To test from the command line use syntax similar to below:
mapserv -nh "QUERY_STRING=map=./msautotest/query/query.map&mode=nquery&qlayer=bdry_counpy2&qformat=formattmpl"
# MapServer Template
[resultset layer=bdry_counpy2]
==================== ============
City Name Abbreviation
==================== ============
[feature][item name="cty_name" padding="20"] [item name="cty_abbr" uc="true" padding="12"]
[/feature]
==================== ============
[/resultset]
The RST output can then be rendered as a table.
City Name |
Abbreviation |
---|---|
Lake of the Woods |
LOTW |
Kittson |
KITT |
Roseau |
ROSE |
Koochiching |
KOOC |
Marshall |
MARS |
St. Louis |
STLO |
Warning
For templates (Templating), there are a number of reserved words. If you have want to expose an attribute with a name that is equal to a reserved word, you can not use the shorthand [attribute_name], but will have to use construct [item name=attribute_name] instead. For example, in a template, [id] is a system generated unique session id (see Templating). So if you have an attribute named “id” that you want to expose, you will either have to rename it or use the construct [item name=id].