[Tiling] WMTS vs TMS

Rushforth, Peter Peter.Rushforth at NRCan-RNCan.gc.ca
Tue Sep 14 08:03:50 EDT 2010


Hi,

I apologize for a long response to your email.  But it pertains to why WMTS vs. TMS,
in the end.  

I'm Peter Rushforth, and I work for GeoConnections at NRCan.  I'm interested in
a standardized tile management protocol that is web friendly.  

By web friendly, I mean RESTful.

Why is REST so important?  

1. the potential for web browsers, without OpenLayers, to use maps.
2. accessibility - tile metadata could support screen readers (alternate media type for a tile resource)
3. discovery - the ability of crawlers to index tile metadata
4. geosearch discovery - related to 1., the ability of crawlers to index pages which point to a map.
5. tile management - GET, PUT, POST, DELETE
6. performance - cacheability etc.

To achieve REST, we should look to Atom Syndication Format via the Atom Publishing Protocol, augmented with
a direct use of OpenSearch Geo + GeoRSS-GML.  Why?  To leverage existing standards.

REST does not says responses have to be XML, but hypertext is a core value.

I think WMTS is a good approach to tiling. I'm anxious to hear what other issues there
might be with it?

Here's what I think it could look like in nested Atom feeds.  First, a TileMatrxSet:
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en" 
      xmlns:os="http://a9.com/-/spec/opensearch/1.1/" 
      xmlns:geo="http://a9.com/-/opensearch/extensions/geo/1.0/"
      xmlns:georss="http://www.georss.org/georss"
      xmlns:wmts="http://www.opengis.net/wmts/1.0"
      xmlns:ows="http://www.opengis.net/ows/1.1"
      xmlns:gml="	http://www.opengis.net/gml">

  <!-- the atom:title element will be used to populate the layer control, if present -->
  <title>Blue Marble Next Generation</title>
  <subtitle>This feed represents a Tile Matrix Set.  Entries represent Tile Matrix resource.</subtitle>

  <!-- elements required by Atom format -->
  <id>urn:uuid:uuid_value_goes_here</id>
  <updated>2009-10-06T13:30:02Z</updated>
  <author>
    <name>Peter Rushforth</name>
    <email>peter.rushforth at nrcan.gc.ca</email>
  </author>
  
  <!-- bounding box of TileMatrixSet, in coords from identified CRS.  Suggest to limit possible
       values of srsName to "urn:ogc:def:crs:OGC:1.3:CRS84" or "urn:ogc:def:crs:EPSG::3857", to promote
       simplicity, alignment with WMTS spec.  Also coordinate order of both systems is x,y. -->
  <georss:where>
    <gml:Envelope srsName="urn:ogc:def:crs:OGC:1.3:CRS84">
      <gml:lowerCorner>180 -90</gml:lowerCorner>
      <gml:upperCorner>-180 90</gml:upperCorner>
    </gml:Envelope>
  </georss:where>
  <!-- aside: wish there was a way to establish the CRS of all coordinates in a document with a hierarchical,
       defaulting mechanism like XML Namespaces does for element names. Come to think of it, couldn't one
       just piggyback that on XML Namespaces?? -->
  
  <!-- 'foreign markup' from WMTS spec, describes TileMatrixSet resource represented by this feed -->
  <TileMatrixSet xmlns="http://www.opengis.net/wmts/1.0">
  
    <!-- bounding box regardless of projection of content -->
    <ows:WGS84BoundingBox>
      <ows:LowerCorner>-180 -90</ows:LowerCorner>
      <ows:UpperCorner>180 90</ows:UpperCorner>
    </ows:WGS84BoundingBox>
    
    <!-- suggest to limit the values supported for interoperability -->
    <ows:SupportedCRS>urn:ogc:def:crs:OGC:1.3:CRS84</ows:SupportedCRS>
    
    <!-- see WMTS spec Appendix E for details, the three possible values are: 
         GoogleMapsCompatible, GlobalCRS84Pixel, GlobalCRS84Scale
    -->
    <WellKnownScaleSet>urn:ogc:def:wkss:GlobalCRS84Pixel</WellKnownScaleSet>
    
  </TileMatrixSet>
  
  <link rel="self" type="application/atom+xml;type=feed" href="http://example.com/geomap/bmng/en/"/>
  
  <!-- following APP, this link identifies a translated representation of the this resource -->
  <!-- if the geomap client wants maps in a different language, it may find the appropriate language here -->
  <!-- unsure if the language code should even actually be in the URL, since the http Accept-Language request
       header could be driven by a) the language of this document (xml:lang) and the @hreflang value of alternate 
       links. Leave it in for now pending more discussion with informed persons. -->
  <link rel="alternate" hreflang="fr" href="http://example.com/geomap/bmng/fr/"/>
  
  <!-- there should be a standard way using AtomPub link at rel values to establish a hierarchy of feeds 
    and maybe this will become the std way: http://tools.ietf.org/html/draft-divilly-atom-hierarchy-03 -->
  <!-- this is one Tile Matrix Set, there could be many offered by the web site, would find them here: -->
  <link rel="up" type="application/atom+xml;type=feed" href="http://example.com/geomap/"/>

  <!-- an alternative to contravening the OpenSearch spec might be to relocate the OpenSearchDescription element below,
       and link to the OpenSearch description document, thusly -->
  <link rel="search" href="http://example.com/geomap/bmng/opensearchdescription.xml" type="application/opensearchdescription+xml" />
  
  <!-- The OpenSearch spec says this has to be the document root element, so it should be accessed via the link above -->
  <!-- this is considered 'foreign markup' in atom: acceptable, but passed over, only understood by a geomap processor -->
  <OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
     <ShortName>Search description document suitable for geomap client</ShortName>
     <Description>
     wmts:ZoomLevel should be initially driven by geomap at zoom, but from there, as the client changes state with map control events initiated by the user, and based on the set of actual values of the ZoomLevel elements found in the Tile Matrix Set feed, the geomap processor will query with one of the values found in the Tile Matrix Feed. The geo:box value will be set by the user agent based initially on the values of geomap at ul and geomap at lr.  
     </Description>
     
     <!-- the bbox parameter allows clients to filter the tiles in tile matrix feeds by *intersecting* box -->
     <!-- if the results were used to navigate to media entries for display, the client would still have  -->
     <!-- arrange the results and perform clipping itself, although there might be some way to sort the   -->
     <!-- query results canonically such that they are arranged left-to-right, top-to-bottom or in the    -->
     <!-- structure as the tile matrix itself in other words; there would have to be some metadata telling -->
     <!-- how many rows and columns were present in the result (?MatrixHeight, ?MatrixWidth) -->
     <!-- the response feed will contain media link entries only -->
     <!-- the response feed will be paged by the server using atompub paging link relations (first, next, last) -->
     <!-- there is no need for an equivalent media entry -->
    
     <!-- the wmts:tilematrix @rel value identifies the search results as representing a WMTS tile matrix -->
    <Url rel="wmts:tilematrix ogc:intersects results" type="application/atom+xml;type=feed" template="http://example.com/geomap/bmng/en/{wmts:ZoomLevel}?bbox={geo:box?}"/>
     <!-- note: box intersection is a little different than the OpenSearch-Geo extension, which specifies
          the semantic of results *within* the box.  Maybe this requires an extension to the 
          OpenSearch-Geo extension, allowing more OGC Simple Features operator semantics. --> 
          
     <!-- this template allows clients to access tile media link entries individually.  Useful for metadata. -->
    <Url rel="wmts:tile" type="application/atom+xml;type=entry" template="http://example.com/geomap/bmng/en/{wmts:ZoomLevel}/{wmts:TileRow}/{wmts:TileCol}"/>
          
     <!-- this template allows clients to by-pass the feeds and go directly to the tile media entries -->
    <Url rel="wmts:tile" type="image/png" template="http://example.com/geomap/bmng/en/{wmts:ZoomLevel}/{wmts:TileRow}/{wmts:TileCol}"/>

     <!-- featureinfo templates allows clients query the features at row(J), col(I) of a particular tile image -->
     <!-- could be more than one feature in a multi-layer Tile Matrix, so should expect a feed containing
          zero or more entry elements with gml, kml whatever content -->
    <Url rel="wmts:featureinfo results" type="application/atom+xml" template="http://example.com/geomap/bmng/en/{wmts:ZoomLevel}/{wmts:TileRow}/{wmts:TileCol}/{wmts:J}/{wmts:I}"/>
     
     <!-- J,I are pixel row,col in a tile image, same results as above formated for html -->
    <Url rel="wmts:featureinfo results" type="text/html" template="http://example.com/geomap/bmng/en/{wmts:ZoomLevel}/{wmts:TileRow}/{wmts:TileCol}/{wmts:J}/{wmts:I}"/>
  </OpenSearchDescription>

  <!-- each entry links to a TileMatrix media link entry feed -->
  <entry>
    <title>500m TileMatrix feed</title>
    <!-- since this entry is just one possible representation, some clients (eg crawlers) would look for this link 
         when looking for metadata about the tiles(media link entries); geomap clients would just use the 
         OpenSearch template to generate the requests for the media entries directly -->
    <link rel="alternate" type="application/atom+xml;type=feed" href="http://example.com/geomap/bmng/en/9"/>
    <id>urn:uuid:uuid_value_goes_here</id>
    <updated>2009-10-06T13:30:02Z</updated>
    <summary>126 tiles; pixels are 500m x 500m.</summary>
    <georss:where>
      <gml:Envelope srsName="urn:ogc:def:crs:OGC:1.3:CRS84">
        <gml:lowerCorner>180 -90</gml:lowerCorner>
        <gml:upperCorner>-180 90</gml:upperCorner>
      </gml:Envelope>
    </georss:where>
    <content type="text/xml">
      <TileMatrix xmlns="http://www.opengis.net/wmts/1.0">
        <ows:Identifier>9</ows:Identifier>
        <ZoomLevel>9</ZoomLevel>
        <ScaleDenominator>16565400.416</ScaleDenominator>
        <TopLeftCorner>-180 90</TopLeftCorner>
        <TileWidth>640</TileWidth>
        <TileHeight>480</TileHeight>
        <MatrixWidth>14</MatrixWidth>
        <MatrixHeight>9</MatrixHeight>
      </TileMatrix>
    </content>
  </entry>
  <entry>
    <title>10000m TileMatrix feed</title>
    <link rel="alternate" type="application/atom+xml;type=feed" href="http://example.com/geomap/bmng/en/5"/>
    <id>urn:uuid:uuid_value_goes_here</id>
    <updated>2009-10-06T13:30:02Z</updated>
    <summary>35 tiles, pixels are 10000m x 10000m</summary>
    <georss:where>
      <gml:Envelope srsName="urn:ogc:def:crs:OGC:1.3:CRS84">
        <gml:lowerCorner>180 -90</gml:lowerCorner>
        <gml:upperCorner>-180 90</gml:upperCorner>
      </gml:Envelope>
    </georss:where>
    <content type="text/xml">
      <TileMatrix xmlns="http://www.opengis.net/wmts/1.0">
        <ows:Identifier>5</ows:Identifier>
        <ZoomLevel>5</ZoomLevel>
        <ScaleDenominator>33130800.831</ScaleDenominator>
        <TopLeftCorner>-180 90</TopLeftCorner>
        <TileWidth>640</TileWidth>
        <TileHeight>480</TileHeight>
        <MatrixWidth>7</MatrixWidth>
        <MatrixHeight>5</MatrixHeight>
      </TileMatrix>
    </content>
  </entry>
  <entry>
    <title>20000m TileMatrix feed</title>
    <link rel="alternate" type="application/atom+xml;type=feed" href="http://example.com/geomap/bmng/en/4"/>
    <id>urn:uuid:uuid_value_goes_here</id>
    <updated>2009-10-06T13:30:02Z</updated>
    <summary>12 tiles, pixels 20000m x 20000m.</summary>
    <georss:where>
      <gml:Envelope srsName="urn:ogc:def:crs:OGC:1.3:CRS84">
        <gml:lowerCorner>180 -90</gml:lowerCorner>
        <gml:upperCorner>-180 90</gml:upperCorner>
      </gml:Envelope>
    </georss:where>
    <content type="text/xml">
      <TileMatrix xmlns="http://www.opengis.net/wmts/1.0">
        <ows:Identifier>4</ows:Identifier>
        <ZoomLevel>4</ZoomLevel>
        <ScaleDenominator>66261601.662</ScaleDenominator>
        <TopLeftCorner>-180 90</TopLeftCorner>
        <TileWidth>640</TileWidth>
        <TileHeight>480</TileHeight>
        <MatrixWidth>4</MatrixWidth>
        <MatrixHeight>3</MatrixHeight>
      </TileMatrix>
    </content>
  </entry>
  <entry>
    <title>40000m TileMatrix feed</title>
    <link rel="alternate" type="application/atom+xml;type=feed" href="http://example.com/geomap/bmng/en/3"/>
    <id>urn:uuid:uuid_value_goes_here</id>
    <updated>2009-10-06T13:30:02Z</updated>
    <summary>4 tiles, pixels 40000m x 40000m.</summary>
    <georss:where>
      <gml:Envelope srsName="urn:ogc:def:crs:OGC:1.3:CRS84">
        <gml:lowerCorner>180 -90</gml:lowerCorner>
        <gml:upperCorner>-180 90</gml:upperCorner>
      </gml:Envelope>
    </georss:where>
    <content type="text/xml">
      <TileMatrix xmlns="http://www.opengis.net/wmts/1.0">
        <ows:Identifier>3</ows:Identifier>
        <ZoomLevel>3</ZoomLevel>
        <ScaleDenominator>132523203.32</ScaleDenominator>
        <TopLeftCorner>-180 90</TopLeftCorner>
        <TileWidth>640</TileWidth>
        <TileHeight>480</TileHeight>
        <MatrixWidth>2</MatrixWidth>
        <MatrixHeight>2</MatrixHeight>
      </TileMatrix>
    </content>
  </entry>
  <entry>
    <title>Blue Marble Next Generation - 60000m pixel size</title>
    <!--  
          Hypertext As The Engine Of Application State: instead of directly accessing the tile images,
          we link to a feed of Tile representations via the alternate link (ie the feed of tile metadata as a whole
          is an alternate representation of this TileMatrix entry. 
    -->
    <link rel="alternate" type="application/atom+xml;type=feed" href="http://example.com/geomap/bmng/en/2"/>
    <id>urn:uuid:uuid_value_goes_here</id>
    <updated>2009-10-06T13:30:02Z</updated>
    <summary>1 tile, pixels 60000m x 60000m</summary>
    
    <georss:where>
      <gml:Envelope srsName="urn:ogc:def:crs:OGC:1.3:CRS84">
        <gml:lowerCorner>180 -90</gml:lowerCorner>
        <gml:upperCorner>-180 90</gml:upperCorner>
      </gml:Envelope>
    </georss:where>
    
    <content type="text/xml">
      <TileMatrix xmlns="http://www.opengis.net/wmts/1.0">
        <ows:Identifier>2</ows:Identifier>
        <ZoomLevel>2</ZoomLevel>
        <ScaleDenominator>198784804.98</ScaleDenominator>
        <TopLeftCorner>-180 90</TopLeftCorner>
        <TileWidth>640</TileWidth>
        <TileHeight>480</TileHeight>
        <MatrixWidth>1</MatrixWidth>
        <MatrixHeight>1</MatrixHeight>
      </TileMatrix>
    </content>
  </entry>
</feed>


Next, a 'sub-feed' of a TileMatrix:

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en" 
      xmlns:os="http://a9.com/-/spec/opensearch/1.1/" 
      xmlns:geo="http://a9.com/-/opensearch/extensions/geo/1.0/"
      xmlns:georss="http://www.georss.org/georss"
      xmlns:wmts="http://www.opengis.net/wmts/1.0"
      xmlns:ows="http://www.opengis.net/ows/1.1"
      xmlns:gml="	http://www.opengis.net/gml">

  <!-- standard Atom elements -->
  <title>Blue Marble Next Generation - 60000m pixel size</title>
  <subtitle>Each entry contains a link to a Tile media entry (image) representing part of a map</subtitle>
  <!-- does the id of a collection have to be the same as its URL??? --> 
  <!-- ok here's a conundrum: I've stated that an entry in the TileMatrixSet feed is an alternate representation of this whole feed -->
  <!-- question is, does this feed have to therefore have the same id as the equivalent entry in the TileMatrixSet feed? -->
  <!-- I think "yes", but not really sure.  Have to check with REST authorities. -->
  <id>urn:uuid:uuid_value_goes_here</id>
  <updated>2009-10-06T13:30:02Z</updated>
  <author>
    <name>Peter Rushforth</name>
    <email>peter.rushforth at nrcan.gc.ca</email>
  </author>
  
  <!-- there should be a standard way using AtomPub link at rel values to establish a hierarchy of feeds 
  and maybe this will become the standard - http://tools.ietf.org/html/draft-divilly-atom-hierarchy-03 -->
  <!-- in any case the 'up' rel tells the client the location of the TileMatrix feed -->
  <!-- note this is different than 'zoomout' -->
  <link rel="up" type="application/atom+xml;type=feed" href="http://example.com/geomap/bmng/en/"/>

  <link rel="east" type="application/atom+xml;type=feed" href=""/>
  <link rel="west" type="application/atom+xml;type=feed" href=""/>
  <link rel="north" type="application/atom+xml;type=feed" href=""/>
  <link rel="south" type="application/atom+xml;type=feed" href=""/>
  <link rel="northeast" type="application/atom+xml;type=feed" href=""/>
  <link rel="northwest" type="application/atom+xml;type=feed" href=""/>
  <link rel="southeast" type="application/atom+xml;type=feed" href=""/>
  <link rel="southwest" type="application/atom+xml;type=feed" href=""/>
  <!-- ideas -->
  <link rel="zoomin" type="application/atom+xml;type=feed" href=""/>
  <link rel="zoomout" type="application/atom+xml;type=feed" href=""/>
  
  
  <!-- that way, a Tile Matrix Set could be an entry (in a feed (representing a ServiceInfo resource) of multiple Tile Matrix Sets) 
       but also represented by a feed containing Tile Matrix entries.  That would allow a client which entered the resource hierarchy
       at this point (i.e. in a Tile Matrix representation) to navigate down *and* up, (which is necessary to zoom out). -->
  <link rel="self" type="application/atom+xml;type=feed" href="http://example.com/geomap/bmng/en/2"/>
  
  <!-- provide translations where appropriate via AtomPub standard mechanism -->
  <link rel="alternate" hreflang="fr" href="http://example.com/geomap/bmng/fr/2"/>

  <!-- link to the OpenSearch description document -->
  <link rel="search" href="http://example.com/geomap/bmng/opensearchdescription.xml" type="application/opensearchdescription+xml" />

  <!-- this feed is an alternate representation of the 60000m Tile Matrix, the primary purpose of which is to provide -->
  <!-- individual tile metadata, especially place name (+/- other) keywords via category elements, tile row,col index values -->
  <TileMatrix xmlns="http://www.opengis.net/wmts/1.0">
    <ows:Identifier>2</ows:Identifier>
    <ZoomLevel>2</ZoomLevel>
    <ScaleDenominator>198784804.98</ScaleDenominator>
    <TopLeftCorner>-180 90</TopLeftCorner>
    <TileWidth>640</TileWidth>
    <TileHeight>480</TileHeight>
    <MatrixWidth>1</MatrixWidth>
    <MatrixHeight>1</MatrixHeight>
  </TileMatrix>
  
  <!-- mandatory bounding box of this TileMatrix -->
  <georss:where>
    <gml:Envelope srsName="urn:ogc:def:crs:OGC:1.3:CRS84">
      <gml:lowerCorner>180 -90</gml:lowerCorner>
      <gml:upperCorner>-180 90</gml:upperCorner>
    </gml:Envelope>
  </georss:where>
  
  <!-- in the 60000m Tile Matrix feed, there is only one Tile resource.  In higher resolution feeds, there would be (many) more. -->
  <entry>
    <title>The World</title>
    <!-- this id is the id of a media resource.  I think it's a good idea to separate identity semantics from URL composition -->
    <id>urn:uuid:uuid_value_goes_here</id>
    <updated>2009-10-06T13:30:02Z</updated>
    
    <summary type="text">This is a media link entry.  The content links to the media, as does the link element.</summary>
    
    <!-- other @rel values might be possible and even useful, for example in an AtomPub tile update scenario, @rel="edit" -->
    <link rel="self" type="application/atom+xml;type=entry" href="http://example.com/geomap/bmng/en/2/1/1"/>
    <link rel="alternate" type="application/atom+xml;type=entry" hreflang="fr" href="http://example.com/geomap/bmng/fr/2/1/1"/>
    
    <!-- category element could describe what the tile is in terms of contained place names, among other schemes -->
    <category term="tile" scheme="http://www.opengis.net/geomap#placename">"North America","South America",Africa,Eurasia,Atlantic,Pacific,Arctic,"Southern Ocean"</category>
    
    <!-- the bounds of this tile -->
    <georss:where>
      <gml:Envelope srsName="urn:ogc:def:crs:OGC:1.3:CRS84">
        <gml:lowerCorner>180 -90</gml:lowerCorner>
        <gml:upperCorner>-180 90</gml:upperCorner>
      </gml:Envelope>
    </georss:where>
    
    <!-- foreign markup; this isn't strictly part of the WMTS spec, but to avoid creating another namespace for now -->
    <Tile xmlns="http://www.opengis.net/wmts/1.0">
      <TileRow>1</TileRow>
      <TileCol>1</TileCol>
    </Tile>
    
    <!-- note the URL of the image conforms to that which could be generated directly by the client from template -->
    <content type="image/png" src="http://example.com/geomap/bmng/en/2/1/1"/>  
  </entry>
</feed>




 


________________________________

	From: tiling-bounces at lists.osgeo.org [mailto:tiling-bounces at lists.osgeo.org] On Behalf Of Cédric MOULLET
	Sent: September 14, 2010 03:53
	To: tiling at lists.osgeo.org
	Subject: [Tiling] WMTS vs TMS
	
	
	Hi,
	Thanks Chris for initiating this discussion plattform. 
	After the publication of the WMTS implementation specification, I'm wondering what is the added value of TMS (sorry if this was discussed at the BOF, but I followed another one) ?
	By saying that, I absolutely don't want to discredit TMS (we have about 300'000'000 tiles with this structure...), but I'd like to know if WMTS is the path to follow or if it's better to stay on TMS.
	Thanks in advance for any information,
	Cédric
	
	
	-- 
	
	Welcome to my world: http://www.cedricmoullet.com/
	My Linked In profile: http://www.linkedin.com/in/cedricmoullet
	Twitter: http://twitter.com/cedricmoullet
	Home sweet home: http://map.geo.admin.ch/?crosshair=bowl&zoom=11&X=185241.24219&Y=561288.90625&bgOpacity=0&selectedNode=node_ch.swisstopo.fixpunkte-lage1




More information about the Tiling mailing list