Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable multi-layer GetMap, GetFeatureInfo to return text/mapml structured to request multi-layer vector tiles #72

Open
prushforth opened this issue May 1, 2024 · 2 comments
Labels
documentation Improvements or additions to documentation enhancement New feature or request GetMap GetTile help wanted Extra attention is needed idea
Milestone

Comments

@prushforth
Copy link
Member

prushforth commented May 1, 2024

Currently with the GeoServer MapML extension, there is no possibility of generating a text/mapml response containing a single-extent, multi-layer request template i.e. a <map-link rel="features" tref="...GetMap&layers=layer1,layer2,layer3...">. For one thing, this is because each layer has its own "Use Features" setting that is not driven by a WMS parameter. What's more, it was unclear how to serialize layers in such a request that are not "vector-capable" such as image layers.

If the GeoServer MapML extension were modified to examine the request mapmlusefeatures:true|false token, it would be possible for a request for text/mapml to generate a single <map-extent> containing a <map-link rel="features" tref="...GetMap&layers=layer1,layer2,layer3&format_options=mapmlfeatures:true..."> (wherein the tref attribute contains a WMS GetMap URL template containing the mapmlfeatures:true format_options parameter token and also contains a multi-layer layers= parameter list value).

This requirement is to establish the behaviour of the GeoServer MapML extension when it processes a multi-layer GetMap request when the format_options parameter token mapmlmultiextent is set to false.

MapML document types available from GeoServer form a conceptual tree structure, in which the nodes are document types and the edges are links, either complete URLs or templated via the MapML <map-link tref="..."> URL template. The root node in the tree is the HTML preview document, which contains a link to a GeoServer layer in text/mapml format. GeoServer's Layer and Layer Group settings pages affect the how the HTML preview document root node is configured and serialized. In particular, the "Use Tiles", "Use Features" and "Multiple Extent Elements" settings for the Layer and Layer Group editing pages will dictate the values format_options= parameter tokens that are serialized into the HTML preview in the GetMap URL in the <layer- src="..."></layer-> src URL.
Screenshot 2024-06-06 114742-resized

Inner node parameters

The middle, or internal node in the above diagram is the first level of text/mapml document available from GeoServer, linked to by the <layer- src="...request=GetMap..."> src URL in the root node, and its configuration, or state, is controled by three tokens for the format_options GeoServer 'vendor' parameter. The tokens' values control, and only apply to the internal node (middle tier from diagram above) state:

(The default value, or the value if the token is omitted, is false)

Table describing different combinations of mapmlmultiextent, mapmlusefeatures, and mapmlusetiles

  mapmlmultiextent  
FALSE TRUE
mapmlusefeatures FALSE create singleton map-extent
traditional WMS image client
rel=image
for each layer in request
-> expand / de-nest layer groups in order
for each layer:
-> create a map-extent for layer
traditional WMS image client
rel=image
FALSE mapmlusetiles
create singleton map-extent
if no tile cache
-> use tile-shaped WMS GetMap for image format
-> rel=image
-> rel=query uses WMS GetFeatureInfo
else
-> use GetTile URL template rel=tile
-> rel=query WMTS GetFeatureInfo for text/mapml infoformat
for each layer in request
-> expand / de-nest layer groups in order
for each layer:
if no tile cache
-> use tile-shaped WMS GetMap for image format
-> rel=image
-> rel=query uses WMS GetFeatureInfo
else
-> use GetTile URL template rel=tile
-> rel=query WMTS GetFeatureInfo for text/mapml infoformat
TRUE
TRUE create singleton map-extent
traditional WMS image client
URL template rel=features type=text/mapml
query link if queryable
for each layer in request
-> expand / de-nest layer groups in order
for each layer:
-> create a map-extent for layer
if layer is raster
-> query link
-> traditional WMS image client
-> rel=image
else
-> rel=features type=text/mapml
-> no query link (features)
-> URL template contains mapmlfeatures:true
FALSE mapmlusetiles
create singleton map-extent
if no tile cache
-> use tile-shaped GetMap as URL template
-> rel=tile type=text/mapml
-> URL template contains mapmlfeatures:true
-> generate rel=query map-link over WMS GetFeatureInfo, infoformat=text/mapml
else
-> use GetTile for text/mapml
-> generate rel=query map-link over WMTS GetFeatureInfo, infoformat=text/mapml
for each layer in request
-> expand / de-nest layer groups in order
for each layer:
-> create a map-extent for layer
if layer is raster
-> if no tile cache
-> -> use tile-shaped GetMap rel=tile, format=image/*
-> else
->-> use GetTile, WMTS GetFeatureInfo for image type
-> -> query link WMTS GetFeatureInfo if layer is queryable
else
-> if no tile cache
-> -> use tile-shaped GetMap rel=tile type=text/mapml
-> -> URL template contains mapmlfeatures:true
-> else
-> -> use GetTile, WMTS GetFeatureInfo for text/mapml
-> -> query link WMTS GetFeatureInfo if layer is queryable
TRUE

mapmlmultiextent:false | true

mapmlmultiextent:false | true - controls the number and state of <map-extent> elements generated in the document, depending on the layers referenced by the layers= WMS parameter. If false (the default), a singleton <map-extent> element will be serialized, and that map-extent will be populated with child <map-input> and associated <map-link rel="..."> elements that conform to the mapmlusefeatures:false | true and mapmlusetiles:false | true values. In the following listing, the document was generated with neither parameter, so they default to false.

Inner node created according to mapmlmultiextent:false, mapmlusefeatures:false, mapmlustiles:false parameter

<mapml- xmlns="http://www.w3.org/1999/xhtml">
  <map-head>
    <map-title>Spearfish</map-title>
    <map-base href="http://localhost:8080/geoserver/wms"/>
    <map-meta charset="utf-8"/>
    <map-meta content="text/mapml;projection=OSMTILE" http-equiv="Content-Type"/>
    <map-link href="http://localhost:8080/geoserver/wms?format_options=mapmlmultiextent:false&amp;request=GetMap&amp;crs=MapML%3AOSMTILE&amp;service=WMS&amp;bbox=-1.1563633841554081E7%2C5522909.350493801%2C-1.1535183234733827E7%2C5543493.457347733&amp;format=text%2Fmapml&amp;layers=spearfish&amp;width=555&amp;styles=&amp;version=1.3.0&amp;height=768" rel="self style" title=""/>
    <map-link href="http://localhost:8080/geoserver/wms?format_options=mapmlmultiextent:false&amp;request=GetMap&amp;crs=MapML%3ACBMTILE&amp;service=WMS&amp;bbox=-719810.8197533418%2C-472267.3616737803%2C-697195.1218560776%2C-454594.08500773815&amp;format=text%2Fmapml&amp;layers=spearfish&amp;width=555&amp;version=1.3.0&amp;height=768" rel="alternate" projection="CBMTILE"/>
    <map-link href="http://localhost:8080/geoserver/wms?format_options=mapmlmultiextent:false&amp;request=GetMap&amp;crs=MapML%3AAPSTILE&amp;service=WMS&amp;bbox=5837588.126624491%2C-1702029.8481186293%2C5866425.6870730845%2C-1672987.582881113&amp;format=text%2Fmapml&amp;layers=spearfish&amp;width=555&amp;version=1.3.0&amp;height=768" rel="alternate" projection="APSTILE"/>
    <map-link href="http://localhost:8080/geoserver/wms?format_options=mapmlmultiextent:false&amp;request=GetMap&amp;crs=MapML%3AWGS84&amp;service=WMS&amp;bbox=-103.87789019829768%2C44.37018707413261%2C-103.62231404880659%2C44.502218486214794&amp;format=text%2Fmapml&amp;layers=spearfish&amp;width=555&amp;version=1.3.0&amp;height=768" rel="alternate" projection="WGS84"/>
  </map-head>
  <map-body>
    <map-extent units="OSMTILE" checked="checked" hidden="hidden">
      <map-input name="z" type="zoom" min="0" max="18"/>
      <map-input name="xmin" type="location" rel="map" position="top-left" axis="easting" units="pcrs" min="-1.1563633841554081E7" max="-1.1535183234733827E7"/>
      <map-input name="ymin" type="location" rel="map" position="bottom-left" axis="northing" units="pcrs" min="5522909.350493801" max="5543493.457347733"/>
      <map-input name="xmax" type="location" rel="map" position="top-right" axis="easting" units="pcrs" min="-1.1563633841554081E7" max="-1.1535183234733827E7"/>
      <map-input name="ymax" type="location" rel="map" position="top-left" axis="northing" units="pcrs" min="5522909.350493801" max="5543493.457347733"/>
      <map-input name="w" type="width" min="1" max="4079"/>
      <map-input name="h" type="height" min="1" max="4079"/>
      <map-link  rel="image" tref="http://localhost:8080/geoserver/wms?request=GetMap&amp;crs=MapML:OSMTILE&amp;service=WMS&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;layers=spearfish&amp;format=image/jpeg&amp;width={w}&amp;styles=&amp;language=en&amp;version=1.3.0&amp;transparent=true&amp;height={h}"/>
      <map-input name="i" type="location" axis="i" units="map"/>
      <map-input name="j" type="location" axis="j" units="map"/>
      <map-link  rel="query" tref="http://localhost:8080/geoserver/wms?request=GetFeatureInfo&amp;query_layers=spearfish&amp;crs=MapML:OSMTILE&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;language=en&amp;cql_filter=&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=spearfish&amp;width={w}&amp;x={i}&amp;feature_count=50&amp;y={j}&amp;styles=&amp;info_format=text/mapml&amp;height={h}"/>
    </map-extent>
  </map-body>
</mapml->

In the following listing of a single layer (LayerGroup) request, the document was generated with the inner node parameters
mapmlusefeatures:false | true and mapmlusetiles:false | true values set to true. Note that the fact that the configuration uses the "GetTile" WMTS request implies that a tile cache with an appropriate GridSet has been set up by the administrator. Had no tile cache been previously configured, the generated <map-extent> would use "tile-shaped" GetMap request templates and associated <map-input>s.

Inner node created according to mapmlmultiextent:false; mapmlusefeatures:true; mapmlusetiles:true, tile cache previously established

<mapml- xmlns="http://www.w3.org/1999/xhtml">
  <map-head>
    <map-title>Spearfish</map-title>
    <map-base href="http://localhost:8080/geoserver/wms"/>
    <map-meta charset="utf-8"/>
    <map-meta content="text/mapml;projection=OSMTILE" http-equiv="Content-Type"/>
    <map-link href="http://localhost:8080/geoserver/wms?format_options=mapmlmultiextent:false;mapmlusefeatures:true;mapmlusetiles:true&amp;request=GetMap&amp;crs=MapML%3AOSMTILE&amp;service=WMS&amp;bbox=-1.1563633841554081E7%2C5522909.350493801%2C-1.1535183234733827E7%2C5543493.457347733&amp;format=text%2Fmapml&amp;layers=spearfish&amp;width=555&amp;styles=&amp;version=1.3.0&amp;height=768" rel="self style" title=""/>
    <map-link href="http://localhost:8080/geoserver/wms?format_options=mapmlmultiextent:false;mapmlusefeatures:true;mapmlusetiles:true&amp;request=GetMap&amp;crs=MapML%3ACBMTILE&amp;service=WMS&amp;bbox=-719810.8197533418%2C-472267.3616737803%2C-697195.1218560776%2C-454594.08500773815&amp;format=text%2Fmapml&amp;layers=spearfish&amp;width=555&amp;version=1.3.0&amp;height=768" rel="alternate" projection="CBMTILE"/>
    <map-link href="http://localhost:8080/geoserver/wms?format_options=mapmlmultiextent:false;mapmlusefeatures:true;mapmlusetiles:true&amp;request=GetMap&amp;crs=MapML%3AAPSTILE&amp;service=WMS&amp;bbox=5837588.126624491%2C-1702029.8481186293%2C5866425.6870730845%2C-1672987.582881113&amp;format=text%2Fmapml&amp;layers=spearfish&amp;width=555&amp;version=1.3.0&amp;height=768" rel="alternate" projection="APSTILE"/>
    <map-link href="http://localhost:8080/geoserver/wms?format_options=mapmlmultiextent:false;mapmlusefeatures:true;mapmlusetiles:true&amp;request=GetMap&amp;crs=MapML%3AWGS84&amp;service=WMS&amp;bbox=-103.87789019829768%2C44.37018707413261%2C-103.62231404880659%2C44.502218486214794&amp;format=text%2Fmapml&amp;layers=spearfish&amp;width=555&amp;version=1.3.0&amp;height=768" rel="alternate" projection="WGS84"/>
  </map-head>
  <map-body>
    <map-extent units="OSMTILE" checked="checked" hidden="hidden">
      <map-input name="z" type="zoom" value="18" min="0" max="18"/>
      <map-input name="x" type="location" axis="column" units="tilematrix" min="55430" max="55616"/>
      <map-input name="y" type="location" axis="row" units="tilematrix" min="94810" max="94944"/>
      <map-link rel="tile" type="text/mapml" tref="http://localhost:8080/geoserver/gwc/service/wmts?request=GetTile&amp;tilematrixset=OSMTILE&amp;tilematrix={z}&amp;TileRow={y}&amp;service=WMTS&amp;format=text/mapml&amp;style=&amp;TileCol={x}&amp;version=1.0.0&amp;layer=spearfish" />
      <map-input name="i" type="location" axis="i" units="tile"/>
      <map-input name="j" type="location" axis="j" units="tile"/>
      <map-link rel="query" tref="http://localhost:8080/geoserver/gwc/service/wmts?request=GetFeatureInfo&amp;format=text/mapml&amp;i={i}&amp;j={j}&amp;TileCol={x}&amp;version=1.0.0&amp;layer=spearfish&amp;tilematrixset=OSMTILE&amp;tilematrix={z}&amp;TileRow={y}&amp;service=WMTS&amp;infoformat=text/mapml&amp;feature_count=50&amp;style=" />
    </map-extent>
  </map-body>
</mapml->

For a format_options=mapmlmultiextent:true value passed to the inner node generator, if the layers parameter is list-valued, that is, references more than a single layer in a comma-separated list OR the layers parameter names a single GeoServer LayerGroup, the resulting text/mapml inner node document will contain one <map-extent> element per layer in the layers list OR per layer in the LayerGroup, with the <map-extent>s serialized according to the values of the mapmlusefeatures and mapmlusetiles format_options values. In the following listing, both of those options' values have defaulted (to false), so each generated <map-extent> is configured to be a "traditional" WMS GetMap / GetFeature client:

Inner node created according to mapmlmultiextent:true, mapmlusefeatures:false, mapmlusetiles:false

<mapml- xmlns="http://www.w3.org/1999/xhtml">
  <map-head>
    <map-title>Spearfish layer group layers</map-title>
    <map-base href="http://localhost:8080/geoserver/wms"/>
    <map-meta charset="utf-8"/>
    <map-meta content="text/mapml;projection=OSMTILE" http-equiv="Content-Type"/>
    <map-link href="http://localhost:8080/geoserver/sf/wms?format_options=mapmlmultiextent:true&amp;request=GetMap&amp;crs=MapML%3AOSMTILE&amp;service=WMS&amp;bbox=-1.1563633841554081E7%2C5522909.350493801%2C-1.1535183234733827E7%2C5543493.457347733&amp;format=text%2Fmapml&amp;layers=sfdem%2Cstreams%2Croads%2Crestricted%2Cbugsites%2Carchsites&amp;width=555&amp;styles=dem%2Csimple_streams%2Csimple_roads%2Crestricted%2Ccapitals%2Cpoint&amp;version=1.3.0&amp;height=768" rel="self style" title="dem,simple_streams,simple_roads,restricted,capitals,point"/>
    <map-link href="http://localhost:8080/geoserver/sf/wms?format_options=mapmlmultiextent:true&amp;request=GetMap&amp;crs=MapML%3ACBMTILE&amp;service=WMS&amp;bbox=-719810.8197533418%2C-472267.3616737803%2C-697195.1218560776%2C-454594.08500773815&amp;format=text%2Fmapml&amp;layers=sfdem%2Cstreams%2Croads%2Crestricted%2Cbugsites%2Carchsites&amp;width=555&amp;version=1.3.0&amp;height=768" rel="alternate" projection="CBMTILE"/>
    <map-link href="http://localhost:8080/geoserver/sf/wms?format_options=mapmlmultiextent:true&amp;request=GetMap&amp;crs=MapML%3AAPSTILE&amp;service=WMS&amp;bbox=5837588.126624491%2C-1702029.8481186293%2C5866425.6870730845%2C-1672987.582881113&amp;format=text%2Fmapml&amp;layers=sfdem%2Cstreams%2Croads%2Crestricted%2Cbugsites%2Carchsites&amp;width=555&amp;version=1.3.0&amp;height=768" rel="alternate" projection="APSTILE"/>
    <map-link href="http://localhost:8080/geoserver/sf/wms?format_options=mapmlmultiextent:true&amp;request=GetMap&amp;crs=MapML%3AWGS84&amp;service=WMS&amp;bbox=-103.87789019829768%2C44.37018707413261%2C-103.62231404880659%2C44.502218486214794&amp;format=text%2Fmapml&amp;layers=sfdem%2Cstreams%2Croads%2Crestricted%2Cbugsites%2Carchsites&amp;width=555&amp;version=1.3.0&amp;height=768" rel="alternate" projection="WGS84"/>
  </map-head>
  <map-body>
    <map-extent units="OSMTILE" label="Spearfish elevation" checked="checked">
      <map-input name="z" type="zoom" min="0" max="18"/>
      <map-input name="xmin" type="location" rel="map" position="top-left" axis="easting" units="pcrs" min="-1.1562867513204884E7" max="-1.1535963887183946E7"/>
      <map-input name="ymin" type="location" rel="map" position="bottom-left" axis="northing" units="pcrs" min="5522913.211891563" max="5543400.923533295"/>
      <map-input name="xmax" type="location" rel="map" position="top-right" axis="easting" units="pcrs" min="-1.1562867513204884E7" max="-1.1535963887183946E7"/>
      <map-input name="ymax" type="location" rel="map" position="top-left" axis="northing" units="pcrs" min="5522913.211891563" max="5543400.923533295"/>
      <map-input name="w" type="width" min="1" max="4079"/>
      <map-input name="h" type="height" min="1" max="4079"/>
      <map-link  rel="image" tref="http://localhost:8080/geoserver/sf/wms?request=GetMap&amp;crs=MapML:OSMTILE&amp;service=WMS&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;layers=sfdem&amp;format=image/png&amp;width={w}&amp;styles=dem&amp;language=en&amp;version=1.3.0&amp;transparent=true&amp;height={h}"/>
      <map-input name="i" type="location" axis="i" units="map"/>
      <map-input name="j" type="location" axis="j" units="map"/>
      <map-link  rel="query" tref="http://localhost:8080/geoserver/sf/wms?request=GetFeatureInfo&amp;query_layers=sfdem&amp;crs=MapML:OSMTILE&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;language=en&amp;cql_filter=&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=sfdem&amp;width={w}&amp;x={i}&amp;feature_count=50&amp;y={j}&amp;styles=dem&amp;info_format=text/mapml&amp;height={h}"/>
    </map-extent>
    <map-extent units="OSMTILE" label="Spearfish streams" checked="checked">
      <map-input name="z" type="zoom" min="0" max="18"/>
      <map-input name="xmin" type="location" rel="map" position="top-left" axis="easting" units="pcrs" min="-1.1563624839736426E7" max="-1.1535237023686884E7"/>
      <map-input name="ymin" type="location" rel="map" position="bottom-left" axis="northing" units="pcrs" min="5523247.73970007" max="5543497.265261071"/>
      <map-input name="xmax" type="location" rel="map" position="top-right" axis="easting" units="pcrs" min="-1.1563624839736426E7" max="-1.1535237023686884E7"/>
      <map-input name="ymax" type="location" rel="map" position="top-left" axis="northing" units="pcrs" min="5523247.73970007" max="5543497.265261071"/>
      <map-input name="w" type="width" min="1" max="4079"/>
      <map-input name="h" type="height" min="1" max="4079"/>
      <map-link  rel="image" tref="http://localhost:8080/geoserver/sf/wms?request=GetMap&amp;crs=MapML:OSMTILE&amp;service=WMS&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;layers=streams&amp;format=image/png&amp;width={w}&amp;styles=simple_streams&amp;language=en&amp;version=1.3.0&amp;transparent=true&amp;height={h}"/>
      <map-input name="i" type="location" axis="i" units="map"/>
      <map-input name="j" type="location" axis="j" units="map"/>
      <map-link  rel="query" tref="http://localhost:8080/geoserver/sf/wms?request=GetFeatureInfo&amp;query_layers=streams&amp;crs=MapML:OSMTILE&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;language=en&amp;cql_filter=&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=streams&amp;width={w}&amp;x={i}&amp;feature_count=50&amp;y={j}&amp;styles=simple_streams&amp;info_format=text/mapml&amp;height={h}" />
    </map-extent>
    <map-extent units="OSMTILE" label="Spearfish roads" checked="checked">
      <map-input name="z" type="zoom" min="0" max="18"/>
      <map-input name="xmin" type="location" rel="map" position="top-left" axis="easting" units="pcrs" min="-1.156362320885788E7" max="-1.153522460748034E7"/>
      <map-input name="ymin" type="location" rel="map" position="bottom-left" axis="northing" units="pcrs" min="5523330.219611262" max="5543486.508318696"/>
      <map-input name="xmax" type="location" rel="map" position="top-right" axis="easting" units="pcrs" min="-1.156362320885788E7" max="-1.153522460748034E7"/>
      <map-input name="ymax" type="location" rel="map" position="top-left" axis="northing" units="pcrs" min="5523330.219611262" max="5543486.508318696"/>
      <map-input name="w" type="width" min="1" max="4079"/>
      <map-input name="h" type="height" min="1" max="4079"/>
      <map-link  rel="image" tref="http://localhost:8080/geoserver/sf/wms?request=GetMap&amp;crs=MapML:OSMTILE&amp;service=WMS&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;layers=roads&amp;format=image/png&amp;width={w}&amp;styles=simple_roads&amp;language=en&amp;version=1.3.0&amp;transparent=true&amp;height={h}" />
      <map-input name="i" type="location" axis="i" units="map"/>
      <map-input name="j" type="location" axis="j" units="map"/>
      <map-link  rel="query" tref="http://localhost:8080/geoserver/sf/wms?request=GetFeatureInfo&amp;query_layers=roads&amp;crs=MapML:OSMTILE&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;language=en&amp;cql_filter=&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=roads&amp;width={w}&amp;x={i}&amp;feature_count=50&amp;y={j}&amp;styles=simple_roads&amp;info_format=text/mapml&amp;height={h}" />
    </map-extent>
    <map-extent units="OSMTILE" label="Spearfish restricted areas" checked="checked">
      <map-input name="z" type="zoom" min="0" max="18"/>
      <map-input name="xmin" type="location" rel="map" position="top-left" axis="easting" units="pcrs" min="-1.1560583766353529E7" max="-1.1549100426349973E7"/>
      <map-input name="ymin" type="location" rel="map" position="bottom-left" axis="northing" units="pcrs" min="5526678.940140986" max="5540366.703552546"/>
      <map-input name="xmax" type="location" rel="map" position="top-right" axis="easting" units="pcrs" min="-1.1560583766353529E7" max="-1.1549100426349973E7"/>
      <map-input name="ymax" type="location" rel="map" position="top-left" axis="northing" units="pcrs" min="5526678.940140986" max="5540366.703552546"/>
      <map-input name="w" type="width" min="1" max="4079"/>
      <map-input name="h" type="height" min="1" max="4079"/>
      <map-link  rel="image" tref="http://localhost:8080/geoserver/sf/wms?request=GetMap&amp;crs=MapML:OSMTILE&amp;service=WMS&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;layers=restricted&amp;format=image/png&amp;width={w}&amp;styles=restricted&amp;language=en&amp;version=1.3.0&amp;transparent=true&amp;height={h}" />
      <map-input name="i" type="location" axis="i" units="map"/>
      <map-input name="j" type="location" axis="j" units="map"/>
      <map-link  rel="query" tref="http://localhost:8080/geoserver/sf/wms?request=GetFeatureInfo&amp;query_layers=restricted&amp;crs=MapML:OSMTILE&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;language=en&amp;cql_filter=&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=restricted&amp;width={w}&amp;x={i}&amp;feature_count=50&amp;y={j}&amp;styles=restricted&amp;info_format=text/mapml&amp;height={h}" />
    </map-extent>
    <map-extent units="OSMTILE" label="Spearfish bug locations" checked="checked">
      <map-input name="z" type="zoom" min="0" max="18"/>
      <map-input name="xmin" type="location" rel="map" position="top-left" axis="easting" units="pcrs" min="-1.1562516830408584E7" max="-1.1536888247576693E7"/>
      <map-input name="ymin" type="location" rel="map" position="bottom-left" axis="northing" units="pcrs" min="5523476.7521918705" max="5532864.657335962"/>
      <map-input name="xmax" type="location" rel="map" position="top-right" axis="easting" units="pcrs" min="-1.1562516830408584E7" max="-1.1536888247576693E7"/>
      <map-input name="ymax" type="location" rel="map" position="top-left" axis="northing" units="pcrs" min="5523476.7521918705" max="5532864.657335962"/>
      <map-input name="w" type="width" min="1" max="4079"/>
      <map-input name="h" type="height" min="1" max="4079"/>
      <map-link  rel="image" tref="http://localhost:8080/geoserver/sf/wms?request=GetMap&amp;crs=MapML:OSMTILE&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;format=text/mapml&amp;language=en&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=bugsites&amp;width={w}&amp;styles=capitals&amp;height={h}"/>
      <map-input name="i" type="location" axis="i" units="map"/>
      <map-input name="j" type="location" axis="j" units="map"/>
      <map-link  rel="query" tref="http://localhost:8080/geoserver/sf/wms?request=GetFeatureInfo&amp;crs=MapML:OSMTILE&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;format=text/mapml&amp;language=en&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=bugsites&amp;width={w}&amp;styles=capitals&amp;height={h}"/>
    </map-extent>
    <map-extent units="OSMTILE" label="Spearfish archeological sites" checked="checked">
      <map-input name="z" type="zoom" min="0" max="18"/>
      <map-input name="xmin" type="location" rel="map" position="top-left" axis="easting" units="pcrs" min="-1.1563031907938445E7" max="-1.1536913929529054E7"/>
      <map-input name="ymin" type="location" rel="map" position="bottom-left" axis="northing" units="pcrs" min="5524037.032890486" max="5541285.002383663"/>
      <map-input name="xmax" type="location" rel="map" position="top-right" axis="easting" units="pcrs" min="-1.1563031907938445E7" max="-1.1536913929529054E7"/>
      <map-input name="ymax" type="location" rel="map" position="top-left" axis="northing" units="pcrs" min="5524037.032890486" max="5541285.002383663"/>
      <map-input name="w" type="width" min="1" max="4079"/>
      <map-input name="h" type="height" min="1" max="4079"/>
      <map-link  rel="image" tref="http://localhost:8080/geoserver/sf/wms?request=GetMap&amp;crs=MapML:OSMTILE&amp;service=WMS&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;layers=archsites&amp;format=image/png&amp;width={w}&amp;styles=point&amp;language=en&amp;version=1.3.0&amp;transparent=true&amp;height={h}" />
      <map-input name="i" type="location" axis="i" units="map"/>
      <map-input name="j" type="location" axis="j" units="map"/>
      <map-link  rel="query" tref="http://localhost:8080/geoserver/sf/wms?request=GetFeatureInfo&amp;query_layers=archsites&amp;crs=MapML:OSMTILE&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;language=en&amp;cql_filter=&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=archsites&amp;width={w}&amp;x={i}&amp;feature_count=50&amp;y={j}&amp;styles=point&amp;info_format=text/mapml&amp;height={h}" />
    </map-extent>
  </map-body>
</mapml->

Inner node created according to mapmlmultiextent:true; mapmlusefeatures:true, mapmlusetiles:false

<mapml- xmlns="http://www.w3.org/1999/xhtml">
  <map-head>
    <map-title>Spearfish, format_options=mapmlmultiextent:true; mapmlusefeatures:true; mapmlusetiles:false</map-title>
    <map-base href="http://localhost:8080/geoserver/wms"/>
    <map-meta charset="utf-8"/>
    <map-meta content="text/mapml;projection=OSMTILE" http-equiv="Content-Type"/>
    <map-link href="http://localhost:8080/geoserver/sf/wms?format_options=mapmlmultiextent:true;mapmlusefeatures:true&amp;request=GetMap&amp;crs=MapML%3AOSMTILE&amp;service=WMS&amp;bbox=-1.1563633841554081E7%2C5522909.350493801%2C-1.1535183234733827E7%2C5543493.457347733&amp;format=text%2Fmapml&amp;layers=sfdem%2Cstreams%2Croads%2Crestricted%2Cbugsites%2Carchsites&amp;width=555&amp;styles=dem%2Csimple_streams%2Csimple_roads%2Crestricted%2Ccapitals%2Cpoint&amp;version=1.3.0&amp;height=768" rel="self style" title="dem,simple_streams,simple_roads,restricted,capitals,point"/>
    <map-link href="http://localhost:8080/geoserver/sf/wms?format_options=mapmlmultiextent:true;mapmlusefeatures:true&amp;request=GetMap&amp;crs=MapML%3ACBMTILE&amp;service=WMS&amp;bbox=-719810.8197533418%2C-472267.3616737803%2C-697195.1218560776%2C-454594.08500773815&amp;format=text%2Fmapml&amp;layers=sfdem%2Cstreams%2Croads%2Crestricted%2Cbugsites%2Carchsites&amp;width=555&amp;version=1.3.0&amp;height=768" rel="alternate" projection="CBMTILE"/>
    <map-link href="http://localhost:8080/geoserver/sf/wms?format_options=mapmlmultiextent:true;mapmlusefeatures:true&amp;request=GetMap&amp;crs=MapML%3AAPSTILE&amp;service=WMS&amp;bbox=5837588.126624491%2C-1702029.8481186293%2C5866425.6870730845%2C-1672987.582881113&amp;format=text%2Fmapml&amp;layers=sfdem%2Cstreams%2Croads%2Crestricted%2Cbugsites%2Carchsites&amp;width=555&amp;version=1.3.0&amp;height=768" rel="alternate" projection="APSTILE"/>
    <map-link href="http://localhost:8080/geoserver/sf/wms?format_options=mapmlmultiextent:true;mapmlusefeatures:true&amp;request=GetMap&amp;crs=MapML%3AWGS84&amp;service=WMS&amp;bbox=-103.87789019829768%2C44.37018707413261%2C-103.62231404880659%2C44.502218486214794&amp;format=text%2Fmapml&amp;layers=sfdem%2Cstreams%2Croads%2Crestricted%2Cbugsites%2Carchsites&amp;width=555&amp;version=1.3.0&amp;height=768" rel="alternate" projection="WGS84"/>
    <map-style>.bbox {display:none}  .simple_streams-r1-s1{stroke-opacity:1.0; stroke-dashoffset:0; stroke-width:2.0; stroke:#003EBA; stroke-linecap:butt} .simple_roads-r1-s1{stroke-opacity:1.0; stroke-dashoffset:0; stroke-width:2.0; stroke:#AA3333; stroke-linecap:butt} .restricted-r1-s1{stroke-opacity:1.0; stroke-dashoffset:0; stroke-width:1.0; fill:#FF0000; fill-opacity:0.7; stroke:#AA0000; stroke-linecap:butt} .capitals-r1-s1{r:48.0; stroke-opacity:1.0; stroke-dashoffset:0; well-known-name:circle; stroke-width:2.0; opacity:1.0; fill:#000000; fill-opacity:1.0; stroke:#000000; stroke-linecap:butt} .point-r1-s1{r:48.0; well-known-name:square; opacity:1.0; fill:#FF0000; fill-opacity:1.0}</map-style>
  </map-head>
  <map-body>
    <map-extent units="OSMTILE" label="Spearfish elevation" checked="checked">
      <map-input name="z" type="zoom" min="0" max="18"/>
      <map-input name="xmin" type="location" rel="map" position="top-left" axis="easting" units="pcrs" min="-1.1562867513204884E7" max="-1.1535963887183946E7"/>
      <map-input name="ymin" type="location" rel="map" position="bottom-left" axis="northing" units="pcrs" min="5522913.211891563" max="5543400.923533295"/>
      <map-input name="xmax" type="location" rel="map" position="top-right" axis="easting" units="pcrs" min="-1.1562867513204884E7" max="-1.1535963887183946E7"/>
      <map-input name="ymax" type="location" rel="map" position="top-left" axis="northing" units="pcrs" min="5522913.211891563" max="5543400.923533295"/>
      <map-input name="w" type="width" min="1" max="4079"/>
      <map-input name="h" type="height" min="1" max="4079"/>
      <map-link  rel="image" tref="http://localhost:8080/geoserver/sf/wms?request=GetMap&amp;crs=MapML:OSMTILE&amp;service=WMS&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;layers=sfdem&amp;format=image/png&amp;width={w}&amp;styles=dem&amp;language=en&amp;version=1.3.0&amp;transparent=true&amp;height={h}"/>
      <map-input name="i" type="location" axis="i" units="map"/>
      <map-input name="j" type="location" axis="j" units="map"/>
      <map-link  rel="query" tref="http://localhost:8080/geoserver/sf/wms?request=GetFeatureInfo&amp;query_layers=sfdem&amp;crs=MapML:OSMTILE&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;language=en&amp;cql_filter=&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=sfdem&amp;width={w}&amp;x={i}&amp;feature_count=50&amp;y={j}&amp;styles=dem&amp;info_format=text/mapml&amp;height={h}"/>
    </map-extent>
    <map-extent units="OSMTILE" label="Spearfish streams" checked="checked">
      <map-input name="z" type="zoom" min="0" max="18"/>
      <map-input name="xmin" type="location" rel="map" position="top-left" axis="easting" units="pcrs" min="-1.1563624839736426E7" max="-1.1535237023686884E7"/>
      <map-input name="ymin" type="location" rel="map" position="bottom-left" axis="northing" units="pcrs" min="5523247.73970007" max="5543497.265261071"/>
      <map-input name="xmax" type="location" rel="map" position="top-right" axis="easting" units="pcrs" min="-1.1563624839736426E7" max="-1.1535237023686884E7"/>
      <map-input name="ymax" type="location" rel="map" position="top-left" axis="northing" units="pcrs" min="5523247.73970007" max="5543497.265261071"/>
      <map-input name="w" type="width" min="1" max="4079"/>
      <map-input name="h" type="height" min="1" max="4079"/>
      <map-link  rel="features" tref="http://localhost:8080/geoserver/sf/wms?format_options=mapmlfeatures:true&amp;request=GetMap&amp;crs=MapML:OSMTILE&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;format=text/mapml&amp;language=en&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=streams&amp;width={w}&amp;styles=simple_streams&amp;height={h}"/>
    </map-extent>
    <map-extent units="OSMTILE" label="Spearfish roads" checked="checked">
      <map-input name="z" type="zoom" min="0" max="18"/>
      <map-input name="xmin" type="location" rel="map" position="top-left" axis="easting" units="pcrs" min="-1.156362320885788E7" max="-1.153522460748034E7"/>
      <map-input name="ymin" type="location" rel="map" position="bottom-left" axis="northing" units="pcrs" min="5523330.219611262" max="5543486.508318696"/>
      <map-input name="xmax" type="location" rel="map" position="top-right" axis="easting" units="pcrs" min="-1.156362320885788E7" max="-1.153522460748034E7"/>
      <map-input name="ymax" type="location" rel="map" position="top-left" axis="northing" units="pcrs" min="5523330.219611262" max="5543486.508318696"/>
      <map-input name="w" type="width" min="1" max="4079"/>
      <map-input name="h" type="height" min="1" max="4079"/>
      <map-link  rel="features" tref="http://localhost:8080/geoserver/sf/wms?format_options=mapmlfeatures:true&amp;request=GetMap&amp;crs=MapML:OSMTILE&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;format=text/mapml&amp;language=en&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=roads&amp;width={w}&amp;styles=simple_roads&amp;height={h}"/>
    </map-extent>
    <map-extent units="OSMTILE" label="Spearfish restricted areas" checked="checked">
      <map-input name="z" type="zoom" min="0" max="18"/>
      <map-input name="xmin" type="location" rel="map" position="top-left" axis="easting" units="pcrs" min="-1.1560583766353529E7" max="-1.1549100426349973E7"/>
      <map-input name="ymin" type="location" rel="map" position="bottom-left" axis="northing" units="pcrs" min="5526678.940140986" max="5540366.703552546"/>
      <map-input name="xmax" type="location" rel="map" position="top-right" axis="easting" units="pcrs" min="-1.1560583766353529E7" max="-1.1549100426349973E7"/>
      <map-input name="ymax" type="location" rel="map" position="top-left" axis="northing" units="pcrs" min="5526678.940140986" max="5540366.703552546"/>
      <map-input name="w" type="width" min="1" max="4079"/>
      <map-input name="h" type="height" min="1" max="4079"/>
      <map-link  rel="features" tref="http://localhost:8080/geoserver/sf/wms?format_options=mapmlfeatures:true&amp;request=GetMap&amp;crs=MapML:OSMTILE&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;format=text/mapml&amp;language=en&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=restricted&amp;width={w}&amp;styles=restricted&amp;height={h}"/>
    </map-extent>
    <map-extent units="OSMTILE" label="Spearfish bug locations" checked="checked">
      <map-input name="z" type="zoom" min="0" max="18"/>
      <map-input name="xmin" type="location" rel="map" position="top-left" axis="easting" units="pcrs" min="-1.1562516830408584E7" max="-1.1536888247576693E7"/>
      <map-input name="ymin" type="location" rel="map" position="bottom-left" axis="northing" units="pcrs" min="5523476.7521918705" max="5532864.657335962"/>
      <map-input name="xmax" type="location" rel="map" position="top-right" axis="easting" units="pcrs" min="-1.1562516830408584E7" max="-1.1536888247576693E7"/>
      <map-input name="ymax" type="location" rel="map" position="top-left" axis="northing" units="pcrs" min="5523476.7521918705" max="5532864.657335962"/>
      <map-input name="w" type="width" min="1" max="4079"/>
      <map-input name="h" type="height" min="1" max="4079"/>
      <map-link tref="http://localhost:8080/geoserver/sf/wms?format_options=mapmlfeatures:true&amp;request=GetMap&amp;crs=MapML:OSMTILE&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;format=text/mapml&amp;language=en&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=bugsites&amp;width={w}&amp;styles=capitals&amp;height={h}"/>
    </map-extent>
    <map-extent units="OSMTILE" label="Spearfish archeological sites" checked="checked">
      <map-input name="z" type="zoom" min="0" max="18"/>
      <map-input name="xmin" type="location" rel="map" position="top-left" axis="easting" units="pcrs" min="-1.1563031907938445E7" max="-1.1536913929529054E7"/>
      <map-input name="ymin" type="location" rel="map" position="bottom-left" axis="northing" units="pcrs" min="5524037.032890486" max="5541285.002383663"/>
      <map-input name="xmax" type="location" rel="map" position="top-right" axis="easting" units="pcrs" min="-1.1563031907938445E7" max="-1.1536913929529054E7"/>
      <map-input name="ymax" type="location" rel="map" position="top-left" axis="northing" units="pcrs" min="5524037.032890486" max="5541285.002383663"/>
      <map-input name="w" type="width" min="1" max="4079"/>
      <map-input name="h" type="height" min="1" max="4079"/>
      <map-link  rel="features" tref="http://localhost:8080/geoserver/sf/wms?format_options=mapmlfeatures:true&amp;request=GetMap&amp;crs=MapML:OSMTILE&amp;bbox={xmin},{ymin},{xmax},{ymax}&amp;format=text/mapml&amp;language=en&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=archsites&amp;width={w}&amp;styles=point&amp;height={h}"/>
    </map-extent>
  </map-body>
</mapml->

Inner node created according to mapmlmultiextent:true; mapmlusefeatures:true; mapmlusetiles:true

<mapml- xmlns="http://www.w3.org/1999/xhtml">
  <map-head>
    <map-title>Spearfish elevation,Spearfish streams,Spearfish roads,Spearfish restricted areas,Spearfish bug locations,Spearfish archeological sites</map-title>
    <map-base href="http://localhost:8080/geoserver/wms"/>
    <map-meta charset="utf-8"/>
    <map-meta content="text/mapml;projection=OSMTILE" http-equiv="Content-Type"/>
    <map-link href="http://localhost:8080/geoserver/sf/wms?format_options=mapmlmultiextent:true;mapmlusetiles:true;mapmlusefeatures:true&amp;request=GetMap&amp;crs=MapML%3AOSMTILE&amp;service=WMS&amp;bbox=-1.1563633841554081E7%2C5522909.350493801%2C-1.1535183234733827E7%2C5543493.457347733&amp;format=text%2Fmapml&amp;layers=sfdem%2Cstreams%2Croads%2Crestricted%2Cbugsites%2Carchsites&amp;width=555&amp;styles=dem%2Csimple_streams%2Csimple_roads%2Crestricted%2Ccapitals%2Cpoint&amp;version=1.3.0&amp;height=768" rel="self style" title="dem,simple_streams,simple_roads,restricted,capitals,point"/>
    <map-link href="http://localhost:8080/geoserver/sf/wms?format_options=mapmlmultiextent:true;mapmlusetiles:true;mapmlusefeatures:true&amp;request=GetMap&amp;crs=MapML%3ACBMTILE&amp;service=WMS&amp;bbox=-719810.8197533418%2C-472267.3616737803%2C-697195.1218560776%2C-454594.08500773815&amp;format=text%2Fmapml&amp;layers=sfdem%2Cstreams%2Croads%2Crestricted%2Cbugsites%2Carchsites&amp;width=555&amp;version=1.3.0&amp;height=768" rel="alternate" projection="CBMTILE"/>
    <map-link href="http://localhost:8080/geoserver/sf/wms?format_options=mapmlmultiextent:true;mapmlusetiles:true;mapmlusefeatures:true&amp;request=GetMap&amp;crs=MapML%3AAPSTILE&amp;service=WMS&amp;bbox=5837588.126624491%2C-1702029.8481186293%2C5866425.6870730845%2C-1672987.582881113&amp;format=text%2Fmapml&amp;layers=sfdem%2Cstreams%2Croads%2Crestricted%2Cbugsites%2Carchsites&amp;width=555&amp;version=1.3.0&amp;height=768" rel="alternate" projection="APSTILE"/>
    <map-link href="http://localhost:8080/geoserver/sf/wms?format_options=mapmlmultiextent:true;mapmlusetiles:true;mapmlusefeatures:true&amp;request=GetMap&amp;crs=MapML%3AWGS84&amp;service=WMS&amp;bbox=-103.87789019829768%2C44.37018707413261%2C-103.62231404880659%2C44.502218486214794&amp;format=text%2Fmapml&amp;layers=sfdem%2Cstreams%2Croads%2Crestricted%2Cbugsites%2Carchsites&amp;width=555&amp;version=1.3.0&amp;height=768" rel="alternate" projection="WGS84"/>
    <map-style>.bbox {display:none}  .simple_streams-r1-s1{stroke-opacity:1.0; stroke-dashoffset:0; stroke-width:2.0; stroke:#003EBA; stroke-linecap:butt} .simple_roads-r1-s1{stroke-opacity:1.0; stroke-dashoffset:0; stroke-width:2.0; stroke:#AA3333; stroke-linecap:butt} .restricted-r1-s1{stroke-opacity:1.0; stroke-dashoffset:0; stroke-width:1.0; fill:#FF0000; fill-opacity:0.7; stroke:#AA0000; stroke-linecap:butt} .capitals-r1-s1{r:48.0; stroke-opacity:1.0; stroke-dashoffset:0; well-known-name:circle; stroke-width:2.0; opacity:1.0; fill:#000000; fill-opacity:1.0; stroke:#000000; stroke-linecap:butt} .point-r1-s1{r:48.0; well-known-name:square; opacity:1.0; fill:#FF0000; fill-opacity:1.0}</map-style>
  </map-head>
  <map-body>
    <map-extent units="OSMTILE" label="Spearfish elevation" checked="checked">
      <map-input name="z" type="zoom" min="0" max="18"/>
      <map-input name="txmin" type="location" rel="tile" position="top-left" axis="easting" units="tilematrix" min="-1.1562867513204884E7" max="-1.1535963887183946E7"/>
      <map-input name="tymin" type="location" rel="tile" position="bottom-left" axis="northing" units="tilematrix" min="5522913.211891563" max="5543400.923533295"/>
      <map-input name="txmax" type="location" rel="tile" position="top-right" axis="easting" units="tilematrix" min="-1.1562867513204884E7" max="-1.1535963887183946E7"/>
      <map-input name="tymax" type="location" rel="tile" position="top-left" axis="northing" units="tilematrix" min="5522913.211891563" max="5543400.923533295"/>
      <map-link rel="tile" tref="http://localhost:8080/geoserver/sf/wms?request=GetMap&amp;crs=MapML:OSMTILE&amp;service=WMS&amp;bbox={txmin},{tymin},{txmax},{tymax}&amp;layers=sfdem&amp;format=image/png&amp;width=256&amp;language=en&amp;styles=dem&amp;version=1.3.0&amp;transparent=true&amp;height=256" />
      <map-input name="i" type="location" axis="i" units="tile"/>
      <map-input name="j" type="location" axis="j" units="tile"/>
      <map-link rel="query" tref="http://localhost:8080/geoserver/sf/wms?request=GetFeatureInfo&amp;query_layers=sfdem&amp;crs=MapML:OSMTILE&amp;bbox={txmin},{tymin},{txmax},{tymax}&amp;language=en&amp;cql_filter=&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=sfdem&amp;width=256&amp;x={i}&amp;feature_count=50&amp;y={j}&amp;styles=dem&amp;info_format=text/mapml&amp;height=256" />
    </map-extent>
    <map-extent units="OSMTILE" label="Spearfish streams" checked="checked">
      <map-input name="z" type="zoom" min="0" max="18"/>
      <map-input name="txmin" type="location" rel="tile" position="top-left" axis="easting" units="tilematrix" min="-1.1563624839736426E7" max="-1.1535237023686884E7"/>
      <map-input name="tymin" type="location" rel="tile" position="bottom-left" axis="northing" units="tilematrix" min="5523247.73970007" max="5543497.265261071"/>
      <map-input name="txmax" type="location" rel="tile" position="top-right" axis="easting" units="tilematrix" min="-1.1563624839736426E7" max="-1.1535237023686884E7"/>
      <map-input name="tymax" type="location" rel="tile" position="top-left" axis="northing" units="tilematrix" min="5523247.73970007" max="5543497.265261071"/>
      <map-link rel="tile" type="text/mapml" tref="http://localhost:8080/geoserver/sf/wms?format_options=mapmlfeatures:true;mapmlskipattributes:true;mapmlskipheadstyles:true&amp;request=GetMap&amp;crs=MapML:OSMTILE&amp;bbox={txmin},{tymin},{txmax},{tymax}&amp;format=text/mapml&amp;language=en&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=streams&amp;width=256&amp;styles=simple_streams&amp;height=256" />
      <map-input name="i" type="location" axis="i" units="tile"/>
      <map-input name="j" type="location" axis="j" units="tile"/>
      <map-link rel="query" tref="http://localhost:8080/geoserver/sf/wms?request=GetFeatureInfo&amp;query_layers=streams&amp;crs=MapML:OSMTILE&amp;bbox={txmin},{tymin},{txmax},{tymax}&amp;language=en&amp;cql_filter=&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=streams&amp;width=256&amp;x={i}&amp;feature_count=50&amp;y={j}&amp;styles=simple_streams&amp;info_format=text/mapml&amp;height=256" />
    </map-extent>
    <map-extent units="OSMTILE" label="Spearfish roads" checked="checked">
      <map-input name="z" type="zoom" min="0" max="18"/>
      <map-input name="txmin" type="location" rel="tile" position="top-left" axis="easting" units="tilematrix" min="-1.156362320885788E7" max="-1.153522460748034E7"/>
      <map-input name="tymin" type="location" rel="tile" position="bottom-left" axis="northing" units="tilematrix" min="5523330.219611262" max="5543486.508318696"/>
      <map-input name="txmax" type="location" rel="tile" position="top-right" axis="easting" units="tilematrix" min="-1.156362320885788E7" max="-1.153522460748034E7"/>
      <map-input name="tymax" type="location" rel="tile" position="top-left" axis="northing" units="tilematrix" min="5523330.219611262" max="5543486.508318696"/>
      <map-link rel="tile" type="text/mapml" tref="http://localhost:8080/geoserver/sf/wms?format_options=mapmlfeatures:true;mapmlskipattributes:true;mapmlskipheadstyles:true&amp;request=GetMap&amp;crs=MapML:OSMTILE&amp;bbox={txmin},{tymin},{txmax},{tymax}&amp;format=text/mapml&amp;language=en&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=roads&amp;width=256&amp;styles=simple_roads&amp;height=256" />
      <map-input name="i" type="location" axis="i" units="tile"/>
      <map-input name="j" type="location" axis="j" units="tile"/>
      <map-link rel="query" tref="http://localhost:8080/geoserver/sf/wms?request=GetFeatureInfo&amp;query_layers=roads&amp;crs=MapML:OSMTILE&amp;bbox={txmin},{tymin},{txmax},{tymax}&amp;language=en&amp;cql_filter=&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=roads&amp;width=256&amp;x={i}&amp;feature_count=50&amp;y={j}&amp;styles=simple_roads&amp;info_format=text/mapml&amp;height=256" />
    </map-extent>
    <map-extent units="OSMTILE" label="Spearfish restricted areas" checked="checked">
      <map-input name="z" type="zoom" min="0" max="18"/>
      <map-input name="txmin" type="location" rel="tile" position="top-left" axis="easting" units="tilematrix" min="-1.1560583766353529E7" max="-1.1549100426349973E7"/>
      <map-input name="tymin" type="location" rel="tile" position="bottom-left" axis="northing" units="tilematrix" min="5526678.940140986" max="5540366.703552546"/>
      <map-input name="txmax" type="location" rel="tile" position="top-right" axis="easting" units="tilematrix" min="-1.1560583766353529E7" max="-1.1549100426349973E7"/>
      <map-input name="tymax" type="location" rel="tile" position="top-left" axis="northing" units="tilematrix" min="5526678.940140986" max="5540366.703552546"/>
      <map-link rel="tile" type="text/mapml" tref="http://localhost:8080/geoserver/sf/wms?format_options=mapmlfeatures:true;mapmlskipattributes:true;mapmlskipheadstyles:true&amp;request=GetMap&amp;crs=MapML:OSMTILE&amp;bbox={txmin},{tymin},{txmax},{tymax}&amp;format=text/mapml&amp;language=en&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=restricted&amp;width=256&amp;styles=restricted&amp;height=256" />
      <map-input name="i" type="location" axis="i" units="tile"/>
      <map-input name="j" type="location" axis="j" units="tile"/>
      <map-link rel="query" tref="http://localhost:8080/geoserver/sf/wms?request=GetFeatureInfo&amp;query_layers=restricted&amp;crs=MapML:OSMTILE&amp;bbox={txmin},{tymin},{txmax},{tymax}&amp;language=en&amp;cql_filter=&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=restricted&amp;width=256&amp;x={i}&amp;feature_count=50&amp;y={j}&amp;styles=restricted&amp;info_format=text/mapml&amp;height=256" />
    </map-extent>
    <map-extent units="OSMTILE" label="Spearfish bug locations" checked="checked">
      <map-input name="z" type="zoom" min="0" max="18"/>
      <map-input name="txmin" type="location" rel="tile" position="top-left" axis="easting" units="tilematrix" min="-1.1562516830408584E7" max="-1.1536888247576693E7"/>
      <map-input name="tymin" type="location" rel="tile" position="bottom-left" axis="northing" units="tilematrix" min="5523476.7521918705" max="5532864.657335962"/>
      <map-input name="txmax" type="location" rel="tile" position="top-right" axis="easting" units="tilematrix" min="-1.1562516830408584E7" max="-1.1536888247576693E7"/>
      <map-input name="tymax" type="location" rel="tile" position="top-left" axis="northing" units="tilematrix" min="5523476.7521918705" max="5532864.657335962"/>
      <map-link rel="tile" type="text/mapml" tref="http://localhost:8080/geoserver/sf/wms?format_options=mapmlfeatures:true;mapmlskipattributes:true;mapmlskipheadstyles:true&amp;request=GetMap&amp;crs=MapML:OSMTILE&amp;bbox={txmin},{tymin},{txmax},{tymax}&amp;format=text/mapml&amp;language=en&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=bugsites&amp;width=256&amp;styles=capitals&amp;height=256" />
      <map-input name="i" type="location" axis="i" units="tile"/>
      <map-input name="j" type="location" axis="j" units="tile"/>
      <map-link rel="query" tref="http://localhost:8080/geoserver/sf/wms?request=GetFeatureInfo&amp;query_layers=bugsites&amp;crs=MapML:OSMTILE&amp;bbox={txmin},{tymin},{txmax},{tymax}&amp;language=en&amp;cql_filter=&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=bugsites&amp;width=256&amp;x={i}&amp;feature_count=50&amp;y={j}&amp;styles=capitals&amp;info_format=text/mapml&amp;height=256" />
    </map-extent>
    <map-extent units="OSMTILE" label="Spearfish archeological sites" checked="checked">
      <map-input name="z" type="zoom" min="0" max="18"/>
      <map-input name="txmin" type="location" rel="tile" position="top-left" axis="easting" units="tilematrix" min="-1.1563031907938445E7" max="-1.1536913929529054E7"/>
      <map-input name="tymin" type="location" rel="tile" position="bottom-left" axis="northing" units="tilematrix" min="5524037.032890486" max="5541285.002383663"/>
      <map-input name="txmax" type="location" rel="tile" position="top-right" axis="easting" units="tilematrix" min="-1.1563031907938445E7" max="-1.1536913929529054E7"/>
      <map-input name="tymax" type="location" rel="tile" position="top-left" axis="northing" units="tilematrix" min="5524037.032890486" max="5541285.002383663"/>
      <map-link rel="tile" type="text/mapml" tref="http://localhost:8080/geoserver/sf/wms?format_options=mapmlfeatures:true;mapmlskipattributes:true;mapmlskipheadstyles:true&amp;request=GetMap&amp;crs=MapML:OSMTILE&amp;bbox={txmin},{tymin},{txmax},{tymax}&amp;format=text/mapml&amp;language=en&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=archsites&amp;width=256&amp;styles=point&amp;height=256" />
      <map-input name="i" type="location" axis="i" units="tile"/>
      <map-input name="j" type="location" axis="j" units="tile"/>
      <map-link rel="query" tref="http://localhost:8080/geoserver/sf/wms?request=GetFeatureInfo&amp;query_layers=archsites&amp;crs=MapML:OSMTILE&amp;bbox={txmin},{tymin},{txmax},{tymax}&amp;language=en&amp;cql_filter=&amp;version=1.3.0&amp;transparent=true&amp;service=WMS&amp;layers=archsites&amp;width=256&amp;x={i}&amp;feature_count=50&amp;y={j}&amp;styles=point&amp;info_format=text/mapml&amp;height=256" />
    </map-extent>
  </map-body>
</mapml->

Leaf node parameters

mapmlfeatures:false | true

The mapmlfeatures format_options token value drives the creation of the leaf node document type. The middle tier node in the diagram will generate templated links embedded in <map-extent>s in the document. The <map-link tref> URL template to the leaf node text/mapml document will accordingly sometimes contain the mapmlfeatures:true token value, which will cause GeoServer to serialize the layer and layer group content as MapML feature and/or image tile data according to the individual layer's underlying data type.

mapmlfeatures:false | true

An example leaf node document is:

<mapml- xmlns="...">
  <map-head>
   <map-title>Layer Group ZZZ Example of interleaved features and tiles</map-title>
  </map-head>
  <map-body>
    <map-feature>
      <map-featurecaption>A feature from Layer A</map-featurecaption>
      <map-geometry><map-point><map-coordinates>-72 43.5</map-coordinates></map-point></map-geometry>
    </map-feature>
   <!-- Layer B is imagery must be represented by the tile that covers the bbox of the GetMap -->
    <map-tile row="13" col="13" zoom="3" src="tile-shaped non-templated GetMap resource URL"></map-tile>
   <map-feature>
      <map-featurecaption>A feature from Layer C</map-featurecaption>
      <map-geometry><map-linestring><map-coordinates>...</map-coordinates></map-linestring></map-geometry>
   </map-feature
  </map-body>
</mapml->
@prushforth prushforth added documentation Improvements or additions to documentation enhancement New feature or request GetMap GetTile idea help wanted Extra attention is needed labels May 1, 2024
@prushforth prushforth changed the title Enable multi-layer GetMap with rel="features" to return text/mapml containing styled <map-feature>s from all layers in parameter Enable multi-layer GetMap with rel="features", GetFeatureInfo to return text/mapml containing styled <map-feature>s from all layers in parameter May 3, 2024
@prushforth prushforth changed the title Enable multi-layer GetMap with rel="features", GetFeatureInfo to return text/mapml containing styled <map-feature>s from all layers in parameter Enable multi-layer GetMap, GetFeatureInfo to return text/mapml containing styled <map-feature>s +/- <map-tile>s from all requested layers Jun 5, 2024
@prushforth prushforth added this to the Vector Tiles milestone Jun 7, 2024
@prushforth prushforth changed the title Enable multi-layer GetMap, GetFeatureInfo to return text/mapml containing styled <map-feature>s +/- <map-tile>s from all requested layers Enable multi-layer GetMap, GetFeatureInfo to return text/mapml structured to support multi-layer vector tiles Jun 7, 2024
@prushforth prushforth changed the title Enable multi-layer GetMap, GetFeatureInfo to return text/mapml structured to support multi-layer vector tiles Enable multi-layer GetMap, GetFeatureInfo to return text/mapml structured to request multi-layer vector tiles Jun 7, 2024
@aaime
Copy link

aaime commented Jul 9, 2024

Just a clarification for the case "mapmlmultiextent: false; mapmlusefeatures:true; mapmlusetiles:true", specifically for the situation where multiple layers have been requested (not a single layer group).
In this case, one cannot use WMTS, even if each single layer is cached, because the protocol only allows one tile at a time, one cannot ask for a list of layers. This forces falling back to tiled WMS.

However, if the request is a group, and the group is tile cached, then yes, it can be handled as a single WMTS request instead.

@prushforth
Copy link
Member Author

However, if the request is a group, and the group is tile cached, then yes, it can be handled as a single WMTS request instead.

Say a request comes in as follows: request=GetMap&format_options=mapmlmultiextent: false; mapmlusefeatures:true; mapmlusetiles:true&layers=a,b,c (your scenario above, basically)

where b is a layer group. I believe that I've specified that b should be de-nested and rendered as features within the one tile in order in the a,b,c stack, just as it would be if it was being rendered to a bitmap in a traditional WMS request (that was being cached as a tile).

What I wrote above for this situation is:

create singleton map-extent
if no tile cache
-> use tile-shaped GetMap as URL template
-> rel=tile type=text/mapml
-> URL template contains mapmlfeatures:true
-> generate rel=query map-link over WMS GetFeatureInfo, infoformat=text/mapml
else
-> use GetTile for text/mapml
-> generate rel=query map-link over WMTS GetFeatureInfo, infoformat=text/mapml

The map-extent would be generated to create 'tile-shaped GetMap requests'

<map-link rel=tile type=text/mapml tref="...GetMap&layers=a,b,c&format_options:mapmlfeatures:true...">

but I see that there is an 'else' above that says to use GetTile and I believe that is your concern. I think I could clarify that with further logic to clarify that using GetTile is only possible in the single-layer case. Am I correct, that's what you're saying?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request GetMap GetTile help wanted Extra attention is needed idea
Projects
None yet
Development

No branches or pull requests

2 participants