Difference between revisions of "Tile Map Service Specification"

From OSGeo
Jump to navigation Jump to search
m (→‎TileMap Resource: fix url: "http://http://tms.osgeo.org/1.0.0")
 
(85 intermediate revisions by 37 users not shown)
Line 1: Line 1:
This specification is currently in ''active revision''Please join the mailing list http://lists.eogeo.org/mailman/listinfo/tiling to discuss issues with the draft here. The specification will first move from ''active revision'' to ''final review'' and then finally to ''numbered specification'', at which point it will be locked.
+
This document is the work of a loose community of participants interested in client/server mapping solutions that use multi-resolution image pyramidsIt is meant to be used as a baseline for the implementation of client/server mapping software. It is not an "official standard" nor is it endorsed by OSGeo as an official project or work product of the Foundation.
 +
 
 +
This document is version "1.0", and will not be edited further. Changes will be discussed on the [[Tile Map Service Specification Change Requests]] page.
 +
 
 +
Any new revisions will take place in a new working copy.
  
 
==Introduction==
 
==Introduction==
Line 5: Line 9:
 
===Document Scope===
 
===Document Scope===
  
This standard specifies the behavior of a service that provides access to georeferenced maps in the form of a regularly spaced set of regularly sized squares at a finite number of scales.  This standard specifies operations to retrieve a computer-readable description of the service instance and to retrieve particular tiles.
+
A Tile Map Service (TMS) provides access to cartographic maps of geo-referenced data, not direct access to the data itself.  This document standardizes the way in which map tiles are requested by clients, and the ways that servers describe their holdings.
 
 
A Tile Map Service provides access to cartographic maps of geo-referenced data, not direct access to the data itself.  This document standardizes the way in which map tiles are requested by clients, and the ways that servers describe their holdings.  
 
  
 
===Document Form===
 
===Document Form===
  
This specification will proceed from a description of general resources provided by the server to particular resources (such as map tiles) providing examples of access URLs and return values at each stage.
+
This document will proceed from a description of general resources provided by the server to particular resources (such as map tiles) providing examples of access URLs and return values at each stage.
  
 
==Specification==
 
==Specification==
Line 19: Line 21:
 
Each resource contains the descriptive information and links to further resources.  Note that while the URLs used to access resources may appear to have internal meaning (the resource for version 1.0.0 of the service has "1.0.0" in it's URL) such structure is ''not required'' of them.  
 
Each resource contains the descriptive information and links to further resources.  Note that while the URLs used to access resources may appear to have internal meaning (the resource for version 1.0.0 of the service has "1.0.0" in it's URL) such structure is ''not required'' of them.  
  
The only requirement is that the resource be referenced by a URL (<nowiki>http://tms.osgeo.org/1.0.0/ could be http://tms.osgeo.org/onepointzeropointzero or http://tms.osgeo.org/flipper as long as the value appeared in the href of the <TileMapService> element</nowiki>).
+
The only requirement is that the resource be referenced by a URL (<nowiki>http://tms.osgeo.org/1.0.0/ could be http://tms.osgeo.org/onepointzeropointzero or http://tms.osgeo.org/flipper.xml as long as the value appeared in the href of the <TileMapService> element</nowiki>).
  
Note that the value of an "href" could be a relative URL, providing the location of the referenced resouce relative to the location of the resource currently being read.  For example: href="subdirectory/tilemap.xml"
+
The value of an "href" '''must''' be an absolute URL (starting with "http://").  For example: href="<nowiki>http://www.service.org/subdirectory/tilemap.xml</nowiki>"
  
 
===Root Resource===
 
===Root Resource===
Line 35: Line 37:
 
  <nowiki><?xml version="1.0" encoding="UTF-8" ?>
 
  <nowiki><?xml version="1.0" encoding="UTF-8" ?>
 
  <Services>
 
  <Services>
   <TileMapService version="1.0.0" href="http://tms.osgeo.org/1.0.0/" />
+
   <TileMapService title="Example Tile Map Service" version="1.0.0" href="http://tms.osgeo.org/1.0.0/" />
   <TileMapService version="1.1.0" href="http://tms.osgeo.org/1.1.0/" />
+
   <TileMapService title="New Example Tile Map Service" version="1.1.0" href="http://tms.osgeo.org/1.1.0/" />
   <FancyFeatureService version="0.9" href="http://ffs.osgeo.org/0.9/" />
+
   <FancyFeatureService title="Features!" version="0.9" href="http://ffs.osgeo.org/0.9/" />
 
  </Services></nowiki>
 
  </Services></nowiki>
  
Line 48: Line 50:
 
  <nowiki><?xml version="1.0" ?>
 
  <nowiki><?xml version="1.0" ?>
 
  <Services>
 
  <Services>
   <TileMapService version="1.0.0" href="tilemapservice.xml" />
+
   <TileMapService title="Example Static Tile Map Service" version="1.0.0" href="http://www.osgeo.org/services/tilemapservice.xml" />
 
  </Services></nowiki>
 
  </Services></nowiki>
  
Line 64: Line 66:
  
 
  <nowiki><?xml version="1.0" encoding="UTF-8" ?>
 
  <nowiki><?xml version="1.0" encoding="UTF-8" ?>
  <TileMapService version="1.0.0">
+
  <TileMapService version="1.0.0" services="http://tms.osgeo.org">
 
   <Title>Example Tile Map Service</Title>
 
   <Title>Example Tile Map Service</Title>
 
   <Abstract>This is a longer description of the example tiling map service.</Abstract>
 
   <Abstract>This is a longer description of the example tiling map service.</Abstract>
Line 88: Line 90:
 
   <TileMaps>
 
   <TileMaps>
 
     <TileMap  
 
     <TileMap  
       href="http://tms.osgeo.org/1.0.0/vmap0/"  
+
       title="VMAP0 World Map"  
       srs="EPSG:4326"
+
       srs="EPSG:4326"  
|    face-id="0"
+
      profile="global-geodetic"  
       global-profile="1">
+
       href="http://tms.osgeo.org/1.0.0/vmap0" />
      VMAP0 World Map
 
    </TileMap>
 
 
     <TileMap  
 
     <TileMap  
       href="http://tms.osgeo.org/1.0.0/landsat2000/"
+
      title="British Columbia Landsat Imagery (2000)"
      srs="EPSG:3005"
+
      srs="EPSG:3005"
      global-profile="0">
+
      profile="local"
      British Columbia Landsat Imagery (2000)
+
       href="http://tms.osgeo.org/1.0.0/landsat2000" />
    </TileMap>
 
 
   </TileMaps>
 
   </TileMaps>
 
  </TileMapService></nowiki>
 
  </TileMapService></nowiki>
  
The <TileMap> element is the key to this response. 
 
 
* The "href" attribute provides a URL that returns a <TileMap> document. 
 
* The "srs" element provides the reference system that the <TileMap> will be in, using an AUTHORITY:ID pattern.  The EPSG authority is the only authority in common use currently, see the [[#Spatial Referencing Systems]] section for more information about SRS details. 
 
* The "global-profile" attribute is "1" if the <TileMap> conforms to the global profile and "0" otherwise. See the [[#Maximizing Interoperability]] section for more information.
 
* The "face-id" attribute is used by some advanced clients that combine multiple tile maps into a single visual output.  The OSGPlanet and GeoFusion clients both use separate polar faces in conjuction with equatorial faces (an "earth cube") to create a single world view from multiple tile maps.  See the [[#Using Faces]] section for more information on implementations.
 
  
 
Request:  
 
Request:  
Line 117: Line 110:
  
 
  <nowiki><?xml version="1.0" encoding="UTF-8" ?>
 
  <nowiki><?xml version="1.0" encoding="UTF-8" ?>
  <TileMapService version="1.0.0">
+
  <TileMapService version="1.0.0" services="http://www.osgeo.org/services/root.xml">
 
   <Title>Example Static Tile Map Service</Title>
 
   <Title>Example Static Tile Map Service</Title>
 
   <Abstract>This is a longer description of the static tiling map service.</Abstract>
 
   <Abstract>This is a longer description of the static tiling map service.</Abstract>
Line 141: Line 134:
 
   <TileMaps>
 
   <TileMaps>
 
     <TileMap  
 
     <TileMap  
       href="basemap.xml"  
+
       title="Vancouver Island Base Map"  
       srs="EPSG:26910"
+
       srs="EPSG:26910"  
|    face-id="0"
+
      profile="none"  
       global-profile="0">
+
       href="http://www.osgeo.org/services/basemap.xml" />
      VMAP0 World Map
 
    </TileMap>
 
 
   </TileMaps>
 
   </TileMaps>
 
  </TileMapService></nowiki>
 
  </TileMapService></nowiki>
Line 158: Line 149:
 
At a particular scale, and in a particular cartographic projection, a <TileMap> is represented by a <TileSet>, a coverage of regularly sized and spaced images that taken together form a complete visual representation of the entire area of coverage of the <TileMap>.
 
At a particular scale, and in a particular cartographic projection, a <TileMap> is represented by a <TileSet>, a coverage of regularly sized and spaced images that taken together form a complete visual representation of the entire area of coverage of the <TileMap>.
  
Each <TileMap> supports one <SRS> and one image format. To support more than one SRS or image format, define extra <TileMaps> in your <TileMapService> for each combination you want.
+
Request:  
 
 
<TileMap>s have both a <BoundingBox> and an <Origin>.  The <BoundingBox> is the extent of the data of interest -- it might be used by a client to set an initial spatial extent.  The <Origin> is the lower-left corner of the 0/0 tile, and the upper right corner of tile -1/-1 (if you choose to configure your service so that negative tiles are required).  The <Origin> may be outside of the visual region of interest (the <BoundingBox>), for reasons of implementation convenience.
 
 
 
Optional metadata elements are called out in the resource below with the pipe character.
 
 
 
Request:
 
  
  <nowiki>http://tms.osgeo.org/1.0.0/vmap0/</nowiki>
+
<nowiki>http://tms.osgeo.org/1.0.0/vmap0</nowiki>
  
 
Response (Content-type: text/xml):
 
Response (Content-type: text/xml):
  
<nowiki><?xml version="1.0" encoding="UTF-8" ?>
+
  <nowiki><?xml version="1.0" encoding="UTF-8" ?>
<TileMap tilemapservice="http://tms.osgeo.org/1.0.0/">
+
  <TileMap version="1.0.0" tilemapservice="http://tms.osgeo.org/1.0.0">
 
   <Title>VMAP0 World Map</Title>
 
   <Title>VMAP0 World Map</Title>
 
   <Abstract>A map of the world built from the NGA VMAP0 vector data set.</Abstract>
 
   <Abstract>A map of the world built from the NGA VMAP0 vector data set.</Abstract>
Line 180: Line 165:
 
  |  <Logo width="10" height="10" href="http://nga.mil/logo.gif" mime-type="image/gif" />
 
  |  <Logo width="10" height="10" href="http://nga.mil/logo.gif" mime-type="image/gif" />
 
  | </Attribution>
 
  | </Attribution>
  | <WebMapServer href="http://wms.org" />
+
  | <WebMapContext href="http://wms.org" />
 +
| <Face>0</Face>
 
   <SRS>EPSG:4326</SRS>
 
   <SRS>EPSG:4326</SRS>
 
   <BoundingBox minx="-180" miny="-90" maxx="180" maxy="90" />
 
   <BoundingBox minx="-180" miny="-90" maxx="180" maxy="90" />
   <Origin x="-180" y="-180" />   
+
   <Origin x="-180" y="-90" />   
 
   <TileFormat width="256" height="256" mime-type="image/jpeg" extension="jpg" />
 
   <TileFormat width="256" height="256" mime-type="image/jpeg" extension="jpg" />
   <TileSets>
+
   <TileSets profile=global-geodetic">
     <TileSet href="http://tms.osgeo.org/1.0.0/vmap0/levelzero" units-per-pixel="0.703125" order="0" />
+
     <TileSet href="http://tms.osgeo.org/1.0.0/vmap0/0" units-per-pixel="0.703125" order="0" />
     <TileSet href="http://tms.osgeo.org/1.0.0/vmap0/levelone" units-per-pixel="0.3515625" order="1" />
+
     <TileSet href="http://tms.osgeo.org/1.0.0/vmap0/1" units-per-pixel="0.3515625" order="1" />
     <TileSet href="http://tms.osgeo.org/1.0.0/vmap0/leveltwo" units-per-pixel="0.17578125" order="2" />
+
     <TileSet href="http://tms.osgeo.org/1.0.0/vmap0/2" units-per-pixel="0.17578125" order="2" />
     <TileSet href="http://tms.osgeo.org/1.0.0/vmap0/levelthree" units-per-pixel="0.08789063" order="3" />
+
     <TileSet href="http://tms.osgeo.org/1.0.0/vmap0/3" units-per-pixel="0.08789063" order="3" />
 
   </TileSets>
 
   </TileSets>
 
  </TileMap></nowiki>
 
  </TileMap></nowiki>
  
 +
Request:
  
Request:
+
  <nowiki>http://tms.osgeo.org/1.0.0/landsat2000</nowiki>
 
 
  <nowiki>http://tms.osgeo.org/1.0.0/landsat2000/</nowiki>
 
  
 
Response (Content-type: text/xml):
 
Response (Content-type: text/xml):
  
<nowiki><?xml version="1.0" encoding="UTF-8" ?>
+
  <nowiki><?xml version="1.0" encoding="UTF-8" ?>
<TileMap tilemapservice="http://tms.osgeo.org/1.0.0/">
+
  <TileMap version="1.0.0" tilemapservice="http://tms.osgeo.org/1.0.0">
 
   <Title>British Columbia Landsat Imagery (2000)</Title>
 
   <Title>British Columbia Landsat Imagery (2000)</Title>
 
   <Abstract>Landsat data collected in the year 2000 over British Columbia.</Abstract>
 
   <Abstract>Landsat data collected in the year 2000 over British Columbia.</Abstract>
Line 210: Line 195:
 
  |  <Logo width="10" height="10" href="http://gov.bc.ca/logo.png" mime-type="image/png" />
 
  |  <Logo width="10" height="10" href="http://gov.bc.ca/logo.png" mime-type="image/png" />
 
  | </Attribution>
 
  | </Attribution>
  | <WebMapServer href="http://wms.gov.bc.ca" />
+
  | <WebMapContext href="http://wms.gov.bc.ca" />
 
   <SRS>EPSG:3005</SRS>
 
   <SRS>EPSG:3005</SRS>
 
   <BoundingBox minx="100000" miny="100000" maxx="1800000" maxy="1800000" />
 
   <BoundingBox minx="100000" miny="100000" maxx="1800000" maxy="1800000" />
 
   <Origin x="100000" y="100000" />
 
   <Origin x="100000" y="100000" />
 
   <TileFormat width="256" height="256" mime-type="image/png" extension="png" />
 
   <TileFormat width="256" height="256" mime-type="image/png" extension="png" />
   <TileSets>
+
   <TileSets profile="local">
     <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/32" units-per-pixel="3200" order="0" />
+
     <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/2048" units-per-pixel="2048" order="0" />
     <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/16" units-per-pixel="1600" order="1" />
+
     <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/1024" units-per-pixel="1024" order="1" />
     <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/8" units-per-pixel="800" order="2" />
+
     <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/512" units-per-pixel="512" order="2" />
     <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/4" units-per-pixel="400" order="3" />
+
     <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/256" units-per-pixel="256" order="3" />
     <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/2" units-per-pixel="200" order="4" />
+
     <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/128" units-per-pixel="128" order="4" />
     <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/1" units-per-pixel="100" order="5" />
+
     <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/64" units-per-pixel="64" order="5" />
 
   </TileSets>
 
   </TileSets>
 
  </TileMap></nowiki>
 
  </TileMap></nowiki>
  
 +
Request:
  
Request:
+
<nowiki>http://www.osgeo.org/services/basemap.xml</nowiki>
 
 
  <nowiki>http://www.osgeo.org/services/basemap.xml</nowiki>
 
  
 
Response (Content-type: text/xml):
 
Response (Content-type: text/xml):
  
<nowiki><?xml version="1.0" encoding="UTF-8" ?>
+
  <nowiki><?xml version="1.0" encoding="UTF-8" ?>
<TileMap tilemapservice="tilemapservice.xml">
+
  <TileMap version="1.0.0" tilemapservice="http://www.osgeo.org/services/tilemapservice.xml">
 
   <Title>Vancouver Island Base Map</Title>
 
   <Title>Vancouver Island Base Map</Title>
 
   <Abstract>A map of the Vancouver Island built from British Columbia planimetric mapping  
 
   <Abstract>A map of the Vancouver Island built from British Columbia planimetric mapping  
Line 243: Line 227:
 
  |  <Logo width="10" height="10" href="http://www.gov.bc.ca/logo.gif" mime-type="image/gif" />
 
  |  <Logo width="10" height="10" href="http://www.gov.bc.ca/logo.gif" mime-type="image/gif" />
 
  | </Attribution>
 
  | </Attribution>
  | <WebMapServer href="http://openmaps.gov.bc.ca" />
+
  | <WebMapContext href="http://openmaps.gov.bc.ca" />
 
   <SRS>EPSG:26910</SRS>
 
   <SRS>EPSG:26910</SRS>
 +
| <Face>0</Face>
 
   <BoundingBox minx="500000" miny="4800000" maxx="700000" maxy="5500000" />
 
   <BoundingBox minx="500000" miny="4800000" maxx="700000" maxy="5500000" />
 
   <Origin x="500000" y="4800000" />   
 
   <Origin x="500000" y="4800000" />   
 
   <TileFormat width="256" height="256" mime-type="image/png" extension="png" />
 
   <TileFormat width="256" height="256" mime-type="image/png" extension="png" />
   <TileSets>
+
   <TileSets profile="none">
     <TileSet href="basemap/L1" units-per-pixel="6400" order="0" />
+
     <TileSet href="http://www.osgeo.org/services/basemap/L1" units-per-pixel="6400" order="0" />
     <TileSet href="basemap/L2" units-per-pixel="1600" order="1" />
+
     <TileSet href="http://www.osgeo.org/services/basemap/L2" units-per-pixel="1600" order="1" />
     <TileSet href="basemap/L3" units-per-pixel="400" order="2" />
+
     <TileSet href="http://www.osgeo.org/services/basemap/L3" units-per-pixel="400" order="2" />
     <TileSet href="basemap/L4" units-per-pixel="100" order="3" />
+
     <TileSet href="http://www.osgeo.org/services/basemap/L4" units-per-pixel="100" order="3" />
     <TileSet href="basemap/L5" units-per-pixel="25" order="4" />
+
     <TileSet href="http://www.osgeo.org/services/basemap/L5" units-per-pixel="25" order="4" />
 
   </TileSets>
 
   </TileSets>
 
  </TileMap></nowiki>
 
  </TileMap></nowiki>
 +
 +
Each <TileMap> supports one <SRS> and one image format. To support more than one SRS or image format, define extra <TileMaps> in your <TileMapService> for each combination you want.
 +
 +
<TileMap>s have both a <BoundingBox> and an <Origin>.  The <BoundingBox> is the extent of the data of interest -- it might be used by a client to set an initial spatial extent.  The <Origin> is the lower-left corner of the 0/0 tile, and the upper right corner of tile -1/-1 (if you choose to configure your service so that negative tiles are required).  The <Origin> may be outside of the visual region of interest (the <BoundingBox>), for reasons of implementation convenience.
 +
 +
<TileMap>s may participate as a <Face> of a larger complex of <TileMap>s. The OSGPlanet and GeoFusion clients both use separate polar faces in conjuction with equatorial faces (an "earth cube") to create a single world view from multiple tile maps.  See [[#Using Faces]].
 +
 +
<TileMap>s may implement one of three "profile"s, two global profiles in common global projections, or a local profile in an arbitrary projection.  All profiles restrict the service to a fixed set of scales, to allow tilesets from different services to be more easily overlaid.
 +
 +
===Profiles===
 +
 +
Using this server specification will ensure that clients can easily consume your tiled map data.  However, it will not guarantee that clients can efficiently overlay your data with data from other tile map servers.  In order to maximize the interoperability of your tile map with other tile maps, you must implement the a "profile" for your tile map.
 +
 +
The profile a <TileMap> supports is advertised in the "profile" attribute of the <TileSets> element.  The "profile" will be one of:
 +
 +
* none
 +
* global-geodetic
 +
* global-mercator
 +
* local
 +
 +
====global-geodetic====
 +
 +
If the profile type is set to "global-geodetic", the <TileMap> must meet the following requirements:
 +
 +
* Must use <SRS>EPSG:4326</SRS>
 +
* Must provide <TileSet>s with units-per-pixel meeting the following formula for any integral value of "n" greater than or equal to 0: units-per-pixel = 0.703125 / 2^n
 +
** This scaling allows an initial zoom level that consists of 2 256x256 pixel tiles covering the whole earth, with an <Origin> of (-180,-90).  Other combinations of tile size and <Origin> are also possible at this scale.
 +
 +
<nowiki><TileSets profile="global-geodetic">
 +
<TileSet href="http://tms.osgeo.org/1.0.0/vmap0/0" units-per-pixel="0.703125" order="0" />
 +
<TileSet href="http://tms.osgeo.org/1.0.0/vmap0/1" units-per-pixel="0.3515625" order="1" />
 +
<TileSet href="http://tms.osgeo.org/1.0.0/vmap0/2" units-per-pixel="0.17578125" order="2" />
 +
<TileSet href="http://tms.osgeo.org/1.0.0/vmap0/3" units-per-pixel="0.08789063" order="3" />
 +
</TileSets></nowiki>
 +
 +
====global-mercator====
 +
 +
If the profile type is set to "global-mercator", the <TileMap> must meet the following requirements:
 +
 +
* Must use <SRS>OSGEO:41001</SRS>
 +
* Must provide <TileSet>s with units-per-pixel meeting the following formula for any integral value of "n" greater than or equal to 0: units-per-pixel = 78271.516 / 2^n
 +
** This scaling allows an initial zoom level that consists of four 256x256 pixel tiles covering the whole earth, with an <Origin> of (-20037508.34, -20037508.34).  Other combinations of tile size and <Origin> are also possible at this scale.
 +
 +
====local====
 +
 +
Unlike the global profiles, the "local" profile is built from the bottom up, starting with a smallest possible scale of one unit per pixel and compounding upwards from there.  Local profiles can be in any projection, but are at a fixed set of scales.
 +
 +
If the profile type is set to "local", the <TileMap> must meet the following requirements:
 +
 +
* May use any coordinate system, and must identify that coordinate system in the <SRS>.
 +
* Must provide <TileSet>s with units-per-pixel meeting the following formula for any integral value of "n" greater than or equal to 0: units-per-pixel = 2^n
 +
* Must provide <TileSet> sub-directories below the <Profile> href value, using the value of "n" appropriate for that <TileSet> as the sub-directory name.
 +
 +
<nowiki><SRS>EPSG:3005</SRS>
 +
<BoundingBox minx="100000" miny="100000" maxx="1800000" maxy="1800000" />
 +
<Origin x="100000" y="100000" />
 +
<TileSets profile="local">
 +
  <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/6" units-per-pixel="2048" order="0" />
 +
  <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/5" units-per-pixel="1024" order="1" />
 +
  <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/4" units-per-pixel="512" order="2" />
 +
  <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/3" units-per-pixel="256" order="3" />
 +
  <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/2" units-per-pixel="128" order="4" />
 +
  <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/1" units-per-pixel="64" order="5" />
 +
</TileSets></nowiki>
  
 
===Tile Resources===
 
===Tile Resources===
Line 279: Line 328:
 
===TileMap Diagram===
 
===TileMap Diagram===
  
''(This is where a diagram of how the Origin, Bounding Box, tile numbering and so on all tie together.)''
+
[[Image:Tms.png]]
  
 
===Error Handling===
 
===Error Handling===
Line 313: Line 362:
  
 
* For all geodetic coordinate systems in the EPSG database, the tile map service specification will treat the coordinate order as longitude, latitude and the units as decimal degrees.
 
* For all geodetic coordinate systems in the EPSG database, the tile map service specification will treat the coordinate order as longitude, latitude and the units as decimal degrees.
* Spatial reference systems not defined in the EPSG database can be temporarily defined in the tile map service specification itself, subject to deprecation in the case of later inclusion by the EPSG.
+
* Spatial reference systems not defined in the EPSG database may be defined in the tile map service specification itself, using an OSGEO authority string.
** EPSG:41001 - <nowiki>PROJCS["WGS84 / Simple Mercator", GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["WGS_1984",6378137,298.257223563]], PRIMEM["Greenwich",0], UNIT["Decimal_Degree", 0.0174532925199433]], PROJECTION["Mercator_1SP"], PARAMETER["central_meridian",0], PARAMETER["false_easting",0], PARAMETER["false_northing",0], UNIT["Meter",1]]</nowiki>
+
** '''OSGEO:41001''' <nowiki>PROJCS["WGS84 / Simple Mercator", GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["WGS_1984",6378137,298.257223563]], PRIMEM["Greenwich",0], UNIT["Decimal_Degree", 0.0174532925199433]], PROJECTION["Mercator_1SP"], PARAMETER["central_meridian",0], PARAMETER["false_easting",0], PARAMETER["false_northing",0], UNIT["Meter",1]]</nowiki>
** EPSG:42310 - <nowiki>PROJCS["WGS84+GRS80 / Mercator", GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["GRS 1980",6378137,298.257222101], TOWGS84[0,0,0]], PRIMEM["Greenwich",0], UNIT["Decimal_Degree",0.0174532925199433]], PROJECTION["Mercator_1SP"], PARAMETER["central_meridian",0], PARAMETER["false_easting",0], PARAMETER["false_northing",0], UNIT["Meter",1]]</nowiki>
+
** '''OSGEO:42310''' <nowiki>PROJCS["WGS84+GRS80 / Mercator", GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["GRS 1980",6378137,298.257222101], TOWGS84[0,0,0]], PRIMEM["Greenwich",0], UNIT["Decimal_Degree",0.0174532925199433]], PROJECTION["Mercator_1SP"], PARAMETER["central_meridian",0], PARAMETER["false_easting",0], PARAMETER["false_northing",0], UNIT["Meter",1]]</nowiki>
** EPSG:42101 - <nowiki>PROJCS["WGS 84 / LCC Canada", GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["WGS_1984",6378137,298.257223563]], PRIMEM["Greenwich",0], UNIT["Decimal_Degree",0.0174532925199433]], PROJECTION["Lambert_Conformal_Conic_2SP"], PARAMETER["central_meridian",-95.0], PARAMETER["latitude_of_origin",0], PARAMETER["standard_parallel_1",49.0], PARAMETER["standard_parallel_2",77.0], PARAMETER["false_easting",0.0], PARAMETER["false_northing",-8000000.0], UNIT["Meter",1]]</nowiki>
+
** '''OSGEO:42101''' <nowiki>PROJCS["WGS 84 / LCC Canada", GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["WGS_1984",6378137,298.257223563]], PRIMEM["Greenwich",0], UNIT["Decimal_Degree",0.0174532925199433]], PROJECTION["Lambert_Conformal_Conic_2SP"], PARAMETER["central_meridian",-95.0], PARAMETER["latitude_of_origin",0], PARAMETER["standard_parallel_1",49.0], PARAMETER["standard_parallel_2",77.0], PARAMETER["false_easting",0.0], PARAMETER["false_northing",-8000000.0], UNIT["Meter",1]]</nowiki>
** EPSG:42304 - <nowiki>PROJCS["NAD83 / NRCan LCC Canada", GEOGCS["NAD83", DATUM["North_American_Datum_1983", SPHEROID["GRS_1980",6378137,298.257222101], TOWGS84[0,0,0]], PRIMEM["Greenwich",0], UNIT["Decimal_Degree",0.0174532925199433]], PROJECTION["Lambert_Conformal_Conic_2SP"], PARAMETER["central_meridian",-95.0], PARAMETER["latitude_of_origin",49.0], PARAMETER["standard_parallel_1",49.0], PARAMETER["standard_parallel_2",77.0], PARAMETER["false_easting",0.0], PARAMETER["false_northing",0.0], UNIT["Meter",1]]</nowiki>
+
** '''OSGEO:42304''' <nowiki>PROJCS["NAD83 / NRCan LCC Canada", GEOGCS["NAD83", DATUM["North_American_Datum_1983", SPHEROID["GRS_1980",6378137,298.257222101], TOWGS84[0,0,0]], PRIMEM["Greenwich",0], UNIT["Decimal_Degree",0.0174532925199433]], PROJECTION["Lambert_Conformal_Conic_2SP"], PARAMETER["central_meridian",-95.0], PARAMETER["latitude_of_origin",49.0], PARAMETER["standard_parallel_1",49.0], PARAMETER["standard_parallel_2",77.0], PARAMETER["false_easting",0.0], PARAMETER["false_northing",0.0], UNIT["Meter",1]]</nowiki>
 
 
===Maximizing Interoperability===
 
 
 
Using this server specification will ensure that clients can easily consume your tiled map data.  However, it will not guarantee that clients can efficiently overlay your data with data from other tile map servers.  In order to maximize the interoperability of your tile map with other tile maps, you must implement the "global profile" for your tile map.
 
 
 
(Services implementing the "global profile" should be flagged as such by setting the "global-profile" attribute in the <TileMap> element of the <TileMapService> resource to "1".)
 
 
 
In order to conform to the "global profile" a TileMap must meet the following requirements:
 
 
 
* Must use <SRS>EPSG:4326</SRS>
 
* Must provide <TileSet>s with units-per-pixel meeting the following formula for any integral value of "n" greater than or equal to 0: units-per-pixel = 0.703125 / 2^n
 
  
 
===Maximizing Cacheability===
 
===Maximizing Cacheability===
Line 348: Line 386:
 
For HTTP 1.0, use the "Expires" header.  If you expect your data to change no more than once per week, set your Expires header to one week in the future.  For example, if it is January 1, 2007, and you wanted your tiles to expire no more than one week after they are retreived, you would set your header using this PHP invocation:
 
For HTTP 1.0, use the "Expires" header.  If you expect your data to change no more than once per week, set your Expires header to one week in the future.  For example, if it is January 1, 2007, and you wanted your tiles to expire no more than one week after they are retreived, you would set your header using this PHP invocation:
  
  header('Expires: Sun, 25 Jun 2006 14:57:12 GMT');
+
  header('Expires: Mon, 8 Jan 2007 14:57:12 GMT');
  
 
Or, to always set the Expires header to one week in the future:
 
Or, to always set the Expires header to one week in the future:
Line 389: Line 427:
 
If "tms" is the CGI executable, it can easily extract the remaining path information and use that for processing purposes.
 
If "tms" is the CGI executable, it can easily extract the remaining path information and use that for processing purposes.
  
Note that by default Microsoft IIS does not conform to the CGI specification for this behavior (Apache does).  See the note at http://support.microsoft.com/kb/q184320/ for information on how to enable this bahavior in IIS.
+
Note that by default some versions of Microsoft IIS do not conform to the CGI specification for this behavior (Apache does).  See the note at http://support.microsoft.com/kb/q184320/ for information on how to enable this bahavior in IIS.
  
 
Note that it is allowable for URLs to include "."s in the middle of paths, so that executable scripts (like PHP files) can be legally used as TMS servers.
 
Note that it is allowable for URLs to include "."s in the middle of paths, so that executable scripts (like PHP files) can be legally used as TMS servers.
Line 409: Line 447:
 
===Reference Implementations===
 
===Reference Implementations===
  
* This is a first attempt at a reference server, it might not work yet, and has no error handling at all. And it is probably very slow, it just wraps up the NASA WMS Global Mosaic within the Tile Map Service specification.
+
====Servers====
** http://mapserver.refractions.net/cgi-bin/tms
+
 
 +
* TileCache
 +
** http://www.tilecache.org/
 +
 
 +
====Clients====
 +
 
 +
* Worldkit: http://worldkit.org/tilemap/
 +
* Openlayers: http://openlayers.org/
 +
* Cadcorp SIS: [http://wiki.osgeo.org/images/a/a5/CadcorpTmsClient.png Screenshot]
 +
* [http://www.merkaartor.org/ Merkaartor], an [http://www.osm.org OpenStreetMap] editor, can use a TMS server as source for background layers: ''Note that like Google's map tiles OpenStreetMap counts tile 0,0 from the top-left not the bottom-left.''
  
 
===Returning Error Codes===
 
===Returning Error Codes===
Line 429: Line 476:
 
==See Also==
 
==See Also==
  
* [http://www.peej.co.uk/articles/http-caching.html  HTTP Caching]
 
 
* [http://www.peej.co.uk/articles/rest.html What is REST]
 
* [http://www.peej.co.uk/articles/rest.html What is REST]
 +
* [http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames OpenStreetMap's "Slippy tiles"]. ''Note that like Google map tiles, their grid counting starts from the top-left not the bottom-left.''
 +
 +
[[Category:Standards]]
 +
[[Category:Tiling]]

Latest revision as of 05:08, 16 May 2012

This document is the work of a loose community of participants interested in client/server mapping solutions that use multi-resolution image pyramids. It is meant to be used as a baseline for the implementation of client/server mapping software. It is not an "official standard" nor is it endorsed by OSGeo as an official project or work product of the Foundation.

This document is version "1.0", and will not be edited further. Changes will be discussed on the Tile Map Service Specification Change Requests page.

Any new revisions will take place in a new working copy.

Introduction

Document Scope

A Tile Map Service (TMS) provides access to cartographic maps of geo-referenced data, not direct access to the data itself. This document standardizes the way in which map tiles are requested by clients, and the ways that servers describe their holdings.

Document Form

This document will proceed from a description of general resources provided by the server to particular resources (such as map tiles) providing examples of access URLs and return values at each stage.

Specification

The Tiled Web Service provides access to resources, in particular, to rendered cartographic tiles at fixed scales. Access to these resources is provided via a "REST" interface, starting with a root resource describing available layers, then map resources with a set of scales, then scales holding sets of tiles.

Each resource contains the descriptive information and links to further resources. Note that while the URLs used to access resources may appear to have internal meaning (the resource for version 1.0.0 of the service has "1.0.0" in it's URL) such structure is not required of them.

The only requirement is that the resource be referenced by a URL (http://tms.osgeo.org/1.0.0/ could be http://tms.osgeo.org/onepointzeropointzero or http://tms.osgeo.org/flipper.xml as long as the value appeared in the href of the <TileMapService> element).

The value of an "href" must be an absolute URL (starting with "http://"). For example: href="http://www.service.org/subdirectory/tilemap.xml"

Root Resource

The root resource describes the available versions of the <TileMapService> (and possibly other services as well).

Request:

http://tms.osgeo.org/

Response (Content-type: text/xml):

<?xml version="1.0" encoding="UTF-8" ?>
 <Services>
   <TileMapService title="Example Tile Map Service" version="1.0.0" href="http://tms.osgeo.org/1.0.0/" />
   <TileMapService title="New Example Tile Map Service" version="1.1.0" href="http://tms.osgeo.org/1.1.0/" />
   <FancyFeatureService title="Features!" version="0.9" href="http://ffs.osgeo.org/0.9/" />
 </Services>

Request:

http://www.osgeo.org/services/root.xml

Response:

<?xml version="1.0" ?>
 <Services>
   <TileMapService title="Example Static Tile Map Service" version="1.0.0" href="http://www.osgeo.org/services/tilemapservice.xml" />
 </Services>

TileMapService Resource

The <TileMapService> resource provides description metadata about the service and lists the available <TileMaps>.

Optional elements in the resource are called out below using the pipe character. All other elements are mandatory.

Request:

http://tms.osgeo.org/1.0.0/

Response (Content-type: text/xml):

<?xml version="1.0" encoding="UTF-8" ?>
 <TileMapService version="1.0.0" services="http://tms.osgeo.org">
   <Title>Example Tile Map Service</Title>
   <Abstract>This is a longer description of the example tiling map service.</Abstract>
 | <KeywordList>example tile service</KeywordList>
 | <ContactInformation>
 |   <ContactPersonPrimary>
 |     <ContactPerson>Paul Ramsey</ContactPerson>
 |     <ContactOrganization>Refractions Research</ContactOrganization>
 |   </ContactPersonPrimary>
 |   <ContactPosition>Manager</ContactPosition>
 |   <ContactAddress>
 |     <AddressType>postal</AddressType>
 |     <Address>300 - 1207 Douglas Street</Address>
 |     <City>Victoria</City>
 |     <StateOrProvince>British Columbia</StateOrProvince>
 |     <PostCode>V8W2E7</PostCode>
 |     <Country>Canada</Country>
 |   </ContactAddress>
 |   <ContactVoiceTelephone>12503833022</ContactVoiceTelephone>
 |   <ContactFacsimileTelephone>12503832140</ContactFacsimileTelephone>
 |   <ContactElectronicMailAddress>pramsey@refractions.net</ContactElectronicMailAddress>
 | </ContactInformation>
   <TileMaps>
     <TileMap 
       title="VMAP0 World Map" 
       srs="EPSG:4326" 
       profile="global-geodetic" 
       href="http://tms.osgeo.org/1.0.0/vmap0" />
     <TileMap 
       title="British Columbia Landsat Imagery (2000)" 
       srs="EPSG:3005" 
       profile="local" 
       href="http://tms.osgeo.org/1.0.0/landsat2000" />
   </TileMaps>
 </TileMapService>


Request:

http://www.osgeo.org/services/tilemapservice.xml

Response (Content-type: text/xml):

<?xml version="1.0" encoding="UTF-8" ?>
 <TileMapService version="1.0.0" services="http://www.osgeo.org/services/root.xml">
   <Title>Example Static Tile Map Service</Title>
   <Abstract>This is a longer description of the static tiling map service.</Abstract>
 | <KeywordList>example tile service static</KeywordList>
 | <ContactInformation>
 |   <ContactPersonPrimary>
 |     <ContactPerson>Paul Ramsey</ContactPerson>
 |     <ContactOrganization>Refractions Research</ContactOrganization>
 |   </ContactPersonPrimary>
 |   <ContactPosition>Manager</ContactPosition>
 |   <ContactAddress>
 |     <AddressType>postal</AddressType>
 |     <Address>300 - 1207 Douglas Street</Address>
 |     <City>Victoria</City>
 |     <StateOrProvince>British Columbia</StateOrProvince>
 |     <PostCode>V8W2E7</PostCode>
 |     <Country>Canada</Country>
 |   </ContactAddress>
 |   <ContactVoiceTelephone>12503833022</ContactVoiceTelephone>
 |   <ContactFacsimileTelephone>12503832140</ContactFacsimileTelephone>
 |   <ContactElectronicMailAddress>pramsey@refractions.net</ContactElectronicMailAddress>
 | </ContactInformation>
   <TileMaps>
     <TileMap 
       title="Vancouver Island Base Map" 
       srs="EPSG:26910" 
       profile="none" 
       href="http://www.osgeo.org/services/basemap.xml" />
   </TileMaps>
 </TileMapService>

TileMap Resource

A <TileMap> is a (usually) cartographically complete map representation. Sometimes <TileMap>s are built to be used in conjunction, as a set of stacked layers, but they are generally visually complete on their own.

<TileMap>s are composed of a set of scale-appropriate cartographic renderings, each divided up into regularly spaced image tiles, called <TileSet>s. Small-scale (eg, 1:10000000) tile sets may only contain a handful of tiles. Large-scale tile sets (eg, 1:10000) may contain millions of tiles.

At a particular scale, and in a particular cartographic projection, a <TileMap> is represented by a <TileSet>, a coverage of regularly sized and spaced images that taken together form a complete visual representation of the entire area of coverage of the <TileMap>.

Request:

http://tms.osgeo.org/1.0.0/vmap0

Response (Content-type: text/xml):

 <?xml version="1.0" encoding="UTF-8" ?>  
  <TileMap version="1.0.0" tilemapservice="http://tms.osgeo.org/1.0.0">
   <Title>VMAP0 World Map</Title>
   <Abstract>A map of the world built from the NGA VMAP0 vector data set.</Abstract>
 | <KeywordList></KeywordList>
 | <Metadata type="TC211" mime-type="text/xml" href="http://www.org" />
 | <Attribution>
 |   <Title>National Geospatial Intelligence Agency</Title>
 |   <Logo width="10" height="10" href="http://nga.mil/logo.gif" mime-type="image/gif" />
 | </Attribution>
 | <WebMapContext href="http://wms.org" /> 
 | <Face>0</Face>
   <SRS>EPSG:4326</SRS>
   <BoundingBox minx="-180" miny="-90" maxx="180" maxy="90" />
   <Origin x="-180" y="-90" />  
   <TileFormat width="256" height="256" mime-type="image/jpeg" extension="jpg" />
   <TileSets profile=global-geodetic">
     <TileSet href="http://tms.osgeo.org/1.0.0/vmap0/0" units-per-pixel="0.703125" order="0" />
     <TileSet href="http://tms.osgeo.org/1.0.0/vmap0/1" units-per-pixel="0.3515625" order="1" />
     <TileSet href="http://tms.osgeo.org/1.0.0/vmap0/2" units-per-pixel="0.17578125" order="2" />
     <TileSet href="http://tms.osgeo.org/1.0.0/vmap0/3" units-per-pixel="0.08789063" order="3" />
   </TileSets>
 </TileMap>

Request:

http://tms.osgeo.org/1.0.0/landsat2000

Response (Content-type: text/xml):

 <?xml version="1.0" encoding="UTF-8" ?>
  <TileMap version="1.0.0" tilemapservice="http://tms.osgeo.org/1.0.0">
   <Title>British Columbia Landsat Imagery (2000)</Title>
   <Abstract>Landsat data collected in the year 2000 over British Columbia.</Abstract>
 | <KeywordList></KeywordList>
 | <Metadata type="TC211" mime-type="text/xml" href="http://www.org" />
 | <Attribution>
 |   <Title>Government of British Columbia</Title>
 |   <Logo width="10" height="10" href="http://gov.bc.ca/logo.png" mime-type="image/png" />
 | </Attribution>
 | <WebMapContext href="http://wms.gov.bc.ca" />
   <SRS>EPSG:3005</SRS>
   <BoundingBox minx="100000" miny="100000" maxx="1800000" maxy="1800000" />
   <Origin x="100000" y="100000" />
   <TileFormat width="256" height="256" mime-type="image/png" extension="png" />
   <TileSets profile="local">
     <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/2048" units-per-pixel="2048" order="0" />
     <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/1024" units-per-pixel="1024" order="1" />
     <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/512" units-per-pixel="512" order="2" />
     <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/256" units-per-pixel="256" order="3" />
     <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/128" units-per-pixel="128" order="4" />
     <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/64" units-per-pixel="64" order="5" />
   </TileSets>
 </TileMap>

Request:

http://www.osgeo.org/services/basemap.xml

Response (Content-type: text/xml):

 <?xml version="1.0" encoding="UTF-8" ?>
  <TileMap version="1.0.0" tilemapservice="http://www.osgeo.org/services/tilemapservice.xml">
   <Title>Vancouver Island Base Map</Title>
   <Abstract>A map of the Vancouver Island built from British Columbia planimetric mapping 
   data and digital elevation hill shading.</Abstract>
 | <KeywordList></KeywordList>
 | <Metadata type="TC211" mime-type="text/xml" href="http://www.org" />
 | <Attribution>
 |   <Title>Goverment of British Columbia</Title>
 |   <Logo width="10" height="10" href="http://www.gov.bc.ca/logo.gif" mime-type="image/gif" />
 | </Attribution>
 | <WebMapContext href="http://openmaps.gov.bc.ca" />
   <SRS>EPSG:26910</SRS>
 | <Face>0</Face>
   <BoundingBox minx="500000" miny="4800000" maxx="700000" maxy="5500000" />
   <Origin x="500000" y="4800000" />  
   <TileFormat width="256" height="256" mime-type="image/png" extension="png" />
   <TileSets profile="none">
     <TileSet href="http://www.osgeo.org/services/basemap/L1" units-per-pixel="6400" order="0" />
     <TileSet href="http://www.osgeo.org/services/basemap/L2" units-per-pixel="1600" order="1" />
     <TileSet href="http://www.osgeo.org/services/basemap/L3" units-per-pixel="400" order="2" />
     <TileSet href="http://www.osgeo.org/services/basemap/L4" units-per-pixel="100" order="3" />
     <TileSet href="http://www.osgeo.org/services/basemap/L5" units-per-pixel="25" order="4" />
   </TileSets>
 </TileMap>

Each <TileMap> supports one <SRS> and one image format. To support more than one SRS or image format, define extra <TileMaps> in your <TileMapService> for each combination you want.

<TileMap>s have both a <BoundingBox> and an <Origin>. The <BoundingBox> is the extent of the data of interest -- it might be used by a client to set an initial spatial extent. The <Origin> is the lower-left corner of the 0/0 tile, and the upper right corner of tile -1/-1 (if you choose to configure your service so that negative tiles are required). The <Origin> may be outside of the visual region of interest (the <BoundingBox>), for reasons of implementation convenience.

<TileMap>s may participate as a <Face> of a larger complex of <TileMap>s. The OSGPlanet and GeoFusion clients both use separate polar faces in conjuction with equatorial faces (an "earth cube") to create a single world view from multiple tile maps. See #Using Faces.

<TileMap>s may implement one of three "profile"s, two global profiles in common global projections, or a local profile in an arbitrary projection. All profiles restrict the service to a fixed set of scales, to allow tilesets from different services to be more easily overlaid.

Profiles

Using this server specification will ensure that clients can easily consume your tiled map data. However, it will not guarantee that clients can efficiently overlay your data with data from other tile map servers. In order to maximize the interoperability of your tile map with other tile maps, you must implement the a "profile" for your tile map.

The profile a <TileMap> supports is advertised in the "profile" attribute of the <TileSets> element. The "profile" will be one of:

  • none
  • global-geodetic
  • global-mercator
  • local

global-geodetic

If the profile type is set to "global-geodetic", the <TileMap> must meet the following requirements:

  • Must use <SRS>EPSG:4326</SRS>
  • Must provide <TileSet>s with units-per-pixel meeting the following formula for any integral value of "n" greater than or equal to 0: units-per-pixel = 0.703125 / 2^n
    • This scaling allows an initial zoom level that consists of 2 256x256 pixel tiles covering the whole earth, with an <Origin> of (-180,-90). Other combinations of tile size and <Origin> are also possible at this scale.
<TileSets profile="global-geodetic">
 <TileSet href="http://tms.osgeo.org/1.0.0/vmap0/0" units-per-pixel="0.703125" order="0" />
 <TileSet href="http://tms.osgeo.org/1.0.0/vmap0/1" units-per-pixel="0.3515625" order="1" />
 <TileSet href="http://tms.osgeo.org/1.0.0/vmap0/2" units-per-pixel="0.17578125" order="2" />
 <TileSet href="http://tms.osgeo.org/1.0.0/vmap0/3" units-per-pixel="0.08789063" order="3" />
 </TileSets>

global-mercator

If the profile type is set to "global-mercator", the <TileMap> must meet the following requirements:

  • Must use <SRS>OSGEO:41001</SRS>
  • Must provide <TileSet>s with units-per-pixel meeting the following formula for any integral value of "n" greater than or equal to 0: units-per-pixel = 78271.516 / 2^n
    • This scaling allows an initial zoom level that consists of four 256x256 pixel tiles covering the whole earth, with an <Origin> of (-20037508.34, -20037508.34). Other combinations of tile size and <Origin> are also possible at this scale.

local

Unlike the global profiles, the "local" profile is built from the bottom up, starting with a smallest possible scale of one unit per pixel and compounding upwards from there. Local profiles can be in any projection, but are at a fixed set of scales.

If the profile type is set to "local", the <TileMap> must meet the following requirements:

  • May use any coordinate system, and must identify that coordinate system in the <SRS>.
  • Must provide <TileSet>s with units-per-pixel meeting the following formula for any integral value of "n" greater than or equal to 0: units-per-pixel = 2^n
  • Must provide <TileSet> sub-directories below the <Profile> href value, using the value of "n" appropriate for that <TileSet> as the sub-directory name.
<SRS>EPSG:3005</SRS>
 <BoundingBox minx="100000" miny="100000" maxx="1800000" maxy="1800000" />
 <Origin x="100000" y="100000" />
 <TileSets profile="local">
   <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/6" units-per-pixel="2048" order="0" />
   <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/5" units-per-pixel="1024" order="1" />
   <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/4" units-per-pixel="512" order="2" />
   <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/3" units-per-pixel="256" order="3" />
   <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/2" units-per-pixel="128" order="4" />
   <TileSet href="http://tms.osgeo.org/1.0.0/landsat2000/1" units-per-pixel="64" order="5" />
 </TileSets>

Tile Resources

The origin of a <TileMap> is defined in the coordinates of the spatial reference system of the <TileMap>. The x-coordinate of the tile numbers increases with the x-coordinate of the spatial reference system, and the y-coordinate of the tile numbers also increases with the y-coordinate of the spatial reference system.

Tiles are addressed under the "href" specified in the <TileSet> appending the "x" tile coordinate as a directory name and using the "y" tile coordinate as the file name, with the file "extension" from the <TileFormat>.

Example:

The tile at the origin of the tile set in the first zoom level of vmap0.
http://tms.osgeo.org/1.0.0/vmap0/levelzero/0/0.jpg
The tile near the middle of the tile set in the third zoom level of vmap0.
http://tms.osgeo.org/1.0.0/vmap0/leveltwo/3/4.jpg
The tile near the middle of the tile set in the fifth zoom level of landsat2000.
http://tms.osgeo.org/1.0.0/landsat2000/1/8500/8500.png
The tile at the origin of the tile set in the first zoom level of basemap.
http://www.osgeo.org/services/basemap/L1/0/0.png

TileMap Diagram

Tms.png

Error Handling

When an error occurs in the server, it is important that the client be able easily notice that an error has occurred, and ascertain why the error occured so the user can be notified if necessary.

The tile map server uses HTTP error codes to relay the general reason for an error condition, and an XML payload to communicate the specific reason for the failure in human readable language.

Only HTTP error codes given in this specification should be used to return errors to the client.

  • The client requests a nonexistent resource URL. Return HTTP error code 404 (Not Found)
  • The server fails in processing a response for a valid resource URL. Return HTTP error code 500 (Internal Server Error)

Servers are optionally allowed to return content, even when throwning an error code. The following is the XML format for a tile map server error message. If the Content-type of the return on an error is set to text/xml, this format is the required form of the response.

<?xml version="1.0" ?>
 <TileMapServerError>
   <Message>The requested tile is outside the bounding box of the tile map.</Message>
 </TileMapServerError>

Implementation Advice

Spatial Referencing Systems

Spatial referencing systems for the tile map service will be defined using the EPSG database as a reference for "well-known" projections, subject to interpretations, given below.

There are two substantial implementation issues with using the EPSG database as a source of truth for spatial reference systems:

  • Firstly, the EPSG database has some specific definitions for commonly used geodetic coordinate systems, in particular EPSG:4326 -- geodetic coordinates relative to the WGS84 spheroid. The EPSG definition for 4326 says that the coordinate order is latitude, longitude and that the units are degrees, minutes, seconds. However, common usage of EPSG:4326 in web mapping says that the coordinate order is longitude, latitude and the units are decimal degrees.
  • Secondly, the EPSG database does not include every commonly used spatial reference system. There are still many local systems which are not included in the database, though the EPSG does make an effort to include new systems as they are brought to their attention. However, the EPSG does not catalogue commonly used global and large area systems, presumably as a matter of policy. For example, no EPSG identifier is provided for a Mercator projection of the world, or an Albers projection of North America.

The issues will be dealt with by fiat in this specification, matching implementation practice rather than following the database definition:

  • For all geodetic coordinate systems in the EPSG database, the tile map service specification will treat the coordinate order as longitude, latitude and the units as decimal degrees.
  • Spatial reference systems not defined in the EPSG database may be defined in the tile map service specification itself, using an OSGEO authority string.
    • OSGEO:41001 PROJCS["WGS84 / Simple Mercator", GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["WGS_1984",6378137,298.257223563]], PRIMEM["Greenwich",0], UNIT["Decimal_Degree", 0.0174532925199433]], PROJECTION["Mercator_1SP"], PARAMETER["central_meridian",0], PARAMETER["false_easting",0], PARAMETER["false_northing",0], UNIT["Meter",1]]
    • OSGEO:42310 PROJCS["WGS84+GRS80 / Mercator", GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["GRS 1980",6378137,298.257222101], TOWGS84[0,0,0]], PRIMEM["Greenwich",0], UNIT["Decimal_Degree",0.0174532925199433]], PROJECTION["Mercator_1SP"], PARAMETER["central_meridian",0], PARAMETER["false_easting",0], PARAMETER["false_northing",0], UNIT["Meter",1]]
    • OSGEO:42101 PROJCS["WGS 84 / LCC Canada", GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["WGS_1984",6378137,298.257223563]], PRIMEM["Greenwich",0], UNIT["Decimal_Degree",0.0174532925199433]], PROJECTION["Lambert_Conformal_Conic_2SP"], PARAMETER["central_meridian",-95.0], PARAMETER["latitude_of_origin",0], PARAMETER["standard_parallel_1",49.0], PARAMETER["standard_parallel_2",77.0], PARAMETER["false_easting",0.0], PARAMETER["false_northing",-8000000.0], UNIT["Meter",1]]
    • OSGEO:42304 PROJCS["NAD83 / NRCan LCC Canada", GEOGCS["NAD83", DATUM["North_American_Datum_1983", SPHEROID["GRS_1980",6378137,298.257222101], TOWGS84[0,0,0]], PRIMEM["Greenwich",0], UNIT["Decimal_Degree",0.0174532925199433]], PROJECTION["Lambert_Conformal_Conic_2SP"], PARAMETER["central_meridian",-95.0], PARAMETER["latitude_of_origin",49.0], PARAMETER["standard_parallel_1",49.0], PARAMETER["standard_parallel_2",77.0], PARAMETER["false_easting",0.0], PARAMETER["false_northing",0.0], UNIT["Meter",1]]

Maximizing Cacheability

Tile maps are usually base maps, and usually represent data that changes on a very slow cycle. They are also usually large in volume, comprising potentially millions of different tiles. Given these basic facts, the aggressive use of caching strategies can optimize performance of tile map services.

Caching can happen at multiple layers between the server and the client:

  • At the client itself, as the user-agent caches results on the local disk.
  • In a shared cache at an intermediate ISP, allowing multiple users of the ISP to pull data from the cache.
  • In a cache on the server itself, to move load from the tile generator to a simpler caching process.

In order for caching to occur at any of these layers, the caching mechanisms need to know when a resource is cachable.

If your tile server is written using a scripting or programming language, you will probably be constructing your HTTP headers yourself, and it is important to include cache control headers when doing so to allow caching to occur.

There are different cache headers for HTTP 1.0 and HTTP 1.1, and because both protocols are in active use, it is important to include both.

For HTTP 1.0, use the "Expires" header. If you expect your data to change no more than once per week, set your Expires header to one week in the future. For example, if it is January 1, 2007, and you wanted your tiles to expire no more than one week after they are retreived, you would set your header using this PHP invocation:

header('Expires: Mon, 8 Jan 2007 14:57:12 GMT');

Or, to always set the Expires header to one week in the future:

header('Expires: ' . gmdate('D, j M Y H:i:s T', time() + 7 * 24 * 60 * 60));   // time + 7 days worth of seconds

For HTTP 1.1, use the "Cache-control" header. Unlike the older "Expires" header, "Cache-control" does not have a clock reference, just a time period to reatain the data, thereby avoiding the clock sychronization issues of "Expires".

header('Cache-Control: max-age=86400, must-revalidate');
header('Cache-Control: ' . 7 * 24 * 60 * 60 );

Read about HTTP 1.1 cache control headers in the W3.org specification.

Implementing Cacheability

You can trust that the somewhere on the internet, someone will respect your cache control headers and your content will be cached, or you can set up your own cache. If you are running Apache 2.0 adding mod_cache caching to your tms is laughably easy.

Just add a mod_cache directive inside your <VirtualHost> definition:

<IfModule mod_disk_cache.c>
 CacheRoot /tmp/apache-cache 
 CacheSize 1024000
 CacheEnable disk /cgi-bin/tms
 CacheDirLevels 5
 CacheDirLength 3
</IfModule> 

This example is for a disk cache, probably what you will use for your TMS, since the data volumes tend to be high. Note how the CacheEnable directive allows you to very precisely control which content you are going to cache. In my case, I am only caching the output from my TMS server, nothing else. If I wanted, I could be even narrower and restrict caching to just one tile map inside my service, or just one tile set.

URLs That are Actually Scripts

For large implementations of the tile map server specification, the data will not be statically pre-built, but will be demand-generated by some kind of backend service. That means that URLs that appear to be static may actually be dynamic.

The CGI specification allows this trivially, by passing any path information after the CGI executable in the URL back to the executable in the PATH_INFO environment variable:

http://tms.osgeo.org/cgi-bin/tms/1.0.0/vmap0

PATH_INFO = 1.0.0/vmap0

If "tms" is the CGI executable, it can easily extract the remaining path information and use that for processing purposes.

Note that by default some versions of Microsoft IIS do not conform to the CGI specification for this behavior (Apache does). See the note at http://support.microsoft.com/kb/q184320/ for information on how to enable this bahavior in IIS.

Note that it is allowable for URLs to include "."s in the middle of paths, so that executable scripts (like PHP files) can be legally used as TMS servers.

Here is a root resource:
http://tms.osgeo.org/tms.php
Here is the a tile request on that server:
http://tms.osgeo.org/tms.php/1.0.0/thetilemap/firstlevel/2/1.jpg

In general, the simplest way to extract information from the incoming script invocation is to take the incoming PATH_INFO environment variable, strip the "/" character from the start and end of the string, and then split the string into an array using the "/" character. In this manner, the first element of the array will be the version, the second element will be the tile map, the third will be the level, the fourth will be the tile "x" and the fifth will be the tile "y" (with a .extension).

Using Faces

The "face-id" attribute of the <TileMap> referenced in the <TileMapService> is used for some specialized clients. How that attribute is used by each client is described here.

To be filled in by implementation knowledge...

Reference Implementations

Servers

Clients

Returning Error Codes

If your tile map server is a static set of files, you will find that your web server sets the appropriate error codes automatically when people ask for resources that do not exist, or the server suffers a failure.

However, if your tile map server is dynamic, you will have to set the HTTP status codes yourself, otherwise the HTTP server will assign a code of 200 (OK) for your error message XML document, which would be wrong. In PHP, an error return function might look like this:

header("HTTP/1.0 404 Not Found");
header("Content-type: text/xml");
print "<?xml version='1.0' ?>";
print "<TileMapServerErrror>";
print "<Message>You requested a map tile [ $path_info ] that does not exist.</Message>";
print "</TileMapServerError>";

Note that in addition to setting the error code the Content-type was also correctly set. Also note that cache headers were not set, since errors are not a good thing to cache.

See Also