update docs
[web/altusmetrum] / AltOS / doc / map-loading.html
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Loading Map Tiles from Google Maps</title><link rel="stylesheet" type="text/css" href="am.css" /><meta name="generator" content="DocBook XSL Stylesheets V1.79.1" /></head><body><div xml:lang="en" class="article" lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="idm1"></a>Loading Map Tiles from Google Maps</h2></div></div><hr /></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="section"><a href="#_the_google_maps_problem">1. The Google Maps Problem</a></span></dt><dd><dl><dt><span class="section"><a href="#_the_proposed_solution_an_intermediate_service">1.1. The Proposed Solution — An Intermediate Service</a></span></dt></dl></dd><dt><span class="section"><a href="#_altos_map_service">2. AltOS Map Service</a></span></dt><dd><dl><dt><span class="section"><a href="#_altos_map_cgi_script">2.1. AltOS Map CGI Script</a></span></dt><dt><span class="section"><a href="#_altos_map_cache_manager">2.2. AltOS Map Cache Manager</a></span></dt><dt><span class="section"><a href="#_altos_map_uri">2.3. AltOS Map URI</a></span></dt><dt><span class="section"><a href="#_altos_version_uri">2.4. AltOS Version URI</a></span></dt><dt><span class="section"><a href="#_altos_tile_request">2.5. AltOS Tile Request</a></span></dt><dt><span class="section"><a href="#_altos_tile_reply">2.6. AltOS Tile Reply</a></span></dt><dt><span class="section"><a href="#_altos_tile_filename">2.7. AltOS Tile Filename</a></span></dt></dl></dd><dt><span class="section"><a href="#_implementation">3. Implementation</a></span></dt><dd><dl><dt><span class="section"><a href="#_access_control">3.1. Access Control</a></span></dt><dt><span class="section"><a href="#_location_restrictions">3.2. Location Restrictions</a></span></dt><dt><span class="section"><a href="#_per_client_restrictions">3.3. Per-Client Restrictions</a></span></dt><dt><span class="section"><a href="#_cache_lifetime_restrictions">3.4. Cache Lifetime Restrictions.</a></span></dt></dl></dd></dl></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_the_google_maps_problem"></a>1. The Google Maps Problem</h2></div></div></div><p>Until recently, Google Maps could be used without fee to fetch map
3 tiles. Applications could load map tiles anonymously or using a key;
4 when used anonymously, the number of tiles that could be loaded per
5 day and the rate at which tiles could be loaded was throttled to make
6 the API practical only for development purpose. With an application
7 key, the number of tiles available per day was much higher, and there
8 was no rate limiting. This was usually sufficient for Altos Metrum
9 customer use.</p><p>However, this has changed and now there is no way to load map tiles
10 anonymously, and any application key must be tied to a credit
11 card. The tile cap for free usage is now monthly instead of
12 daily. Because the key is tied to a credit card, we should not ship it
13 with the application any longer. And because the cap is monthly
14 instead of daily, we need some way to control usage by our
15 applications.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_the_proposed_solution_an_intermediate_service"></a>1.1. The Proposed Solution — An Intermediate Service</h3></div></div></div><p>To give us some measure of control over tile loading, we will want to
16 interpose a server controlled by us between the application and Google
17 Maps. This will let us store the Google Maps key in a secure location,
18 and also control tile loading by each user.</p><div class="informalfigure"><div class="mediaobject" align="center"><img src="map-loading.svg" align="middle" alt="map-loading.svg" /></div></div></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_altos_map_service"></a>2. AltOS Map Service</h2></div></div></div><p>This service receives a URL request and replies with either a map tile
19 or an error. It is functionally equivalent to the Google Maps service,
20 except that it can control use of the Google Maps API.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_altos_map_cgi_script"></a>2.1. AltOS Map CGI Script</h3></div></div></div><p>The AltOS Map CGI Script is a straightforward script which connects to
21 the AltOS Map Cache Manager, transmits a URL describing the desired
22 map tile and receives back a filename (or error), then sends the
23 contents of that file back through Apache to the requesting
24 application. The name of the script is <span class="emphasis"><em>altos-map</em></span>.</p><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="_inputs"></a>Inputs</h4></div></div></div><p>The AltOS Map CGI Script will parse the provided AltOS Map URI or
25 AltOS Version URI.</p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="_outputs"></a>Outputs</h4></div></div></div><p>For AltOS Map URLs, the CGI Script will return either the contents of
26 the associated Google Map tile or an error indicating what failed:</p><p><span class="emphasis"><em>200 OK</em></span>: The map tile image data or version information</p><p><span class="emphasis"><em>400 Bad Request</em></span>: The URL is malformed or not compatible with the
27 version supported by the service</p><p><span class="emphasis"><em>403 Forbidden</em></span>: The map tile is outside the areas supported by the
28 current AltOS Map service area</p><p><span class="emphasis"><em>408 Request Timeout</em></span>: Attempts to fetch the tile from Google Maps
29 timed out.</p><p><span class="emphasis"><em>503 Service Unavailable</em></span>: The service is temporarily refusing to
30 satisfy this request due to resource limitations.</p></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_altos_map_cache_manager"></a>2.2. AltOS Map Cache Manager</h3></div></div></div><p>This is a service running on the local machine and available over a
31 local network socket. It translates an AltOS Map URL into a local
32 filename containing the contents of the associated Google Maps
33 tile. The name of the cache manager is <span class="emphasis"><em>altos-mapd</em></span>. It will listen
34 for requests on port 16717.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_altos_map_uri"></a>2.3. AltOS Map URI</h3></div></div></div><p>AltOS uses a limited subset of the Google Maps, and the AltOS Map URIs
35 only encode those elements which we currently use. This specification
36 describes AltOS Map URI format version 1.0.0. The application is
37 required to provide URIs compatible with the format supported by the
38 server. The elements of the  elements are:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
39 Latitude of center point
40 </li><li class="listitem">
41 Longitude of center point
42 </li><li class="listitem">
43 Zoom level (from bushes to planets)
44 </li></ul></div><p>Encoding this in a URI is straightforward:</p><pre class="literallayout">altos-map?lat=&lt;lat&gt;&amp;lon=&lt;lon&gt;&amp;zoom=&lt;zoom&gt;</pre><p>Latitude and longitude are both encoded using decimal degrees with 6
45 digits following the decimal point.</p><p>Zoom levels can range from 1 (world) to 20 (buildings). Higher zoom
46 levels show smaller areas at greater detail.</p><p>The only Google Map type supported by version 1.0.0 of the service is
47 “hybrid”, which combines road graphics on top of satellite images.</p><p>Version 1.0.0 always returns images which are 512x512 pixels.</p><p>If we need additional elements in the URL, we can add them in the
48 future and bump the supported version number.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_altos_version_uri"></a>2.4. AltOS Version URI</h3></div></div></div><p>To allow applications to discover what AltOS Map URI version is supported by the
49 AltOS Map service, the application may query the version of the API
50 supported using the Version URI. The application provides the version
51 that it supports and the AltOS Map service returns a version not
52 greater than the client version:</p><pre class="literallayout">altos-map?version=&lt;client-major&gt;.&lt;client-minor&gt;.&lt;client-revision&gt;
53
54 &lt;server-major&gt;.&lt;server-minor&gt;.&lt;server.revision&gt;</pre></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_altos_tile_request"></a>2.5. AltOS Tile Request</h3></div></div></div><p>The AltOS Map CGI Script parses the Map URI and passes that
55 information to the AltOS Map Cache Manager using the AltOS Tile
56 Specifier syntax. This is a JSON representation of the same data
57 provided by the URI:</p><pre class="literallayout">{
58         "lat": &lt;latitude&gt;,
59         "lon": &lt;longitude&gt;,
60         "zoom": &lt;zoom-level&gt;,
61         "remote_addr": "&lt;IPv4 or IPv6 address of requesting client&gt;"
62 }</pre><p>Latitude and longitude are both encoded using decimal degrees with 6
63 digits following the decimal point.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_altos_tile_reply"></a>2.6. AltOS Tile Reply</h3></div></div></div><p>Sent back from the Cache Manager to the CGI Script, this encodes the
64 status of the request and the filename of any tile data available. It
65 is encoded in JSON format:</p><pre class="literallayout">{
66         "status": &lt;HTTP status&gt;,
67         "filename": "&lt;absolute path to image file&gt;",
68         "content_type": "&lt;HTTP content-type&gt;"
69 }</pre><p>The “filename” and “content-type” elements are only included when
70 the status is <span class="emphasis"><em>200 OK</em></span>.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_altos_tile_filename"></a>2.7. AltOS Tile Filename</h3></div></div></div><p>While the current AltOS Map URI version only supports a limited subset
71 of the Google Maps functionality, we’ll encode more of that data in
72 filenames to allow for easy expansion of functionality in the
73 future. The elements of an AltOS Tile filename consist of :</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
74 Latitude, with N/S indicator (instead of a sign)
75 </li><li class="listitem">
76 Longitude, with E/W indicator (instead of a sign)
77 </li><li class="listitem">
78 Map type.
79 </li><li class="listitem">
80 Zoom level
81 </li><li class="listitem">
82 Scale factor. Scale, and the preceding hyphen are omitted for a scale factor of 1.
83 </li><li class="listitem">
84 Image format suffix. <span class="emphasis"><em>.jpg</em></span> for JPEG files and <span class="emphasis"><em>.png</em></span> for PNG files.
85 </li></ul></div><p>Latitude and longitude are both encoded using decimal degrees with 6
86 digits following the decimal point.</p><p>Map type is one of :</p><p><span class="emphasis"><em>hybrid</em></span>: Road graphics over satellite images
87 <span class="emphasis"><em>roadmap</em></span>: Symbolic road map
88 <span class="emphasis"><em>satellite</em></span>: Un-annotated satellite images
89 <span class="emphasis"><em>terrain</em></span>: Topographic map</p><p>Here’s what map filenames look like:</p><pre class="literallayout">map-{N,S}&lt;lat&gt;,{E,W}&lt;lon&gt;-&lt;type&gt;-&lt;zoom&gt;[-&lt;scale&gt;].&lt;format&gt;</pre><pre class="literallayout">map-N36.508532,W107.823944-hybrid-18.jpg</pre><p>To transmit this name from the AltOS Map Cache Manager back to the
90 Altos Map CGI script, the filename will be wrapped in a JSON string</p></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_implementation"></a>3. Implementation</h2></div></div></div><p>The AltOS Map CGI Script and AltOS Map Cache Manager will both be
91 implemented in Java as much of the required Google Maps infrastructure
92 is already available in that language.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_access_control"></a>3.1. Access Control</h3></div></div></div><p>No access control to the service is planned at this point. If
93 necessary, we could implement username/password access control for each
94 user of the service.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_location_restrictions"></a>3.2. Location Restrictions</h3></div></div></div><p>To avoid unbounded usage, and confine the utility of this service to
95 AltOS users, the service will only offer map tiles whose center
96 location is within 10 miles of one of the sites registered in
97 our launch sites database.</p><p>To allow testing of the registered launch site database, a database of
98 privileged clients will be supported. Privileged clients will have
99 unlimited access to the service.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_per_client_restrictions"></a>3.3. Per-Client Restrictions</h3></div></div></div><p>We should implement a per-day limit on the number of tiles provided to
100 a particular requesting client. We can also rate limit clients to a
101 certain number of tiles per minute to reduce the bandwidth consumed
102 out of our server.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_cache_lifetime_restrictions"></a>3.4. Cache Lifetime Restrictions.</h3></div></div></div><p>The Google Maps API allows for caching of map data for no more than 30
103 days. To honor this, the Cache Manager will re-fetch any requested
104 tiles when the cached version is older than this. If the fetch fails,
105 the cache manager will continue to serve the data from the cached
106 version of the file.</p></div></div></div></body></html>