altoslib: Change map loading to lat=&lon= from center=
[fw/altos] / doc / map-loading.txt
1 = Loading Map Tiles from Google Maps
2 :doctype: article
3
4 == The Google Maps Problem
5
6 Until recently, Google Maps could be used without fee to fetch map
7 tiles. Applications could load map tiles anonymously or using a key;
8 when used anonymously, the number of tiles that could be loaded per
9 day and the rate at which tiles could be loaded was throttled to make
10 the API practical only for development purpose. With an application
11 key, the number of tiles available per day was much higher, and there
12 was no rate limiting. This was usually sufficient for Altos Metrum
13 customer use.
14
15 However, this has changed and now there is no way to load map tiles
16 anonymously, and any application key must be tied to a credit
17 card. The tile cap for free usage is now monthly instead of
18 daily. Because the key is tied to a credit card, we should not ship it
19 with the application any longer. And because the cap is monthly
20 instead of daily, we need some way to control usage by our
21 applications.
22
23 === The Proposed Solution — An Intermediate Service
24
25 To give us some measure of control over tile loading, we will want to
26 interpose a server controlled by us between the application and Google
27 Maps. This will let us store the Google Maps key in a secure location,
28 and also control tile loading by each user.
29
30 image::map-loading.svg[align="center"]
31
32 == AltOS Map Service
33
34 This service receives a URL request and replies with either a map tile
35 or an error. It is functionally equivalent to the Google Maps service,
36 except that it can control use of the Google Maps API.
37
38 === AltOS Map CGI Script
39
40 The AltOS Map CGI Script is a straightforward script which connects to
41 the AltOS Map Cache Manager, transmits a URL describing the desired
42 map tile and receives back a filename (or error), then sends the
43 contents of that file back through Apache to the requesting
44 application. The name of the script is 'altos-map'.
45
46 ==== Inputs
47
48 The AltOS Map CGI Script will parse the provided AltOS Map URI or
49 AltOS Version URI.
50
51 ==== Outputs
52
53 For AltOS Map URLs, the CGI Script will return either the contents of
54 the associated Google Map tile or an error indicating what failed:
55
56 _200 OK_: The map tile image data or version information
57
58 _400 Bad Request_: The URL is malformed or not compatible with the
59 version supported by the service
60
61 _403 Forbidden_: The map tile is outside the areas supported by the
62 current AltOS Map service area
63
64 _408 Request Timeout_: Attempts to fetch the tile from Google Maps
65 timed out.
66
67 _503 Service Unavailable_: The service is temporarily refusing to
68 satisfy this request due to resource limitations.
69
70 === AltOS Map Cache Manager
71
72 This is a service running on the local machine and available over a
73 local network socket. It translates an AltOS Map URL into a local
74 filename containing the contents of the associated Google Maps
75 tile. The name of the cache manager is 'altos-mapd'. It will listen
76 for requests on port 16717.
77
78 === AltOS Map URI
79
80 AltOS uses a limited subset of the Google Maps, and the AltOS Map URIs
81 only encode those elements which we currently use. This specification
82 describes AltOS Map URI format version 1.0.0. The application is
83 required to provide URIs compatible with the format supported by the
84 server. The elements of the  elements are:
85
86  * Latitude of center point
87  * Longitude of center point
88  * Zoom level (from bushes to planets)
89
90 Encoding this in a URI is straightforward:
91
92 \       altos-map?lat=<lat>&lon=<lon>&zoom=<zoom>
93
94 Latitude and longitude are both encoded using decimal degrees with 6
95 digits following the decimal point.
96
97 Zoom levels can range from 1 (world) to 20 (buildings). Higher zoom
98 levels show smaller areas at greater detail.
99
100 The only Google Map type supported by version 1.0.0 of the service is
101 “hybrid”, which combines road graphics on top of satellite images.
102
103 Version 1.0.0 always returns images which are 512x512 pixels.
104
105 If we need additional elements in the URL, we can add them in the
106 future and bump the supported version number.
107
108 === AltOS Version URI
109
110 To allow applications to discover what AltOS Map URI version is supported by the
111 AltOS Map service, the application may query the version of the API
112 supported using the Version URI. The application provides the version
113 that it supports and the AltOS Map service returns a version not
114 greater than the client version:
115
116 \       altos-map?version=<client-major>.<client-minor>.<client-revision>
117 \       →
118 \       <server-major>.<server-minor>.<server.revision>
119
120 === AltOS Tile Request
121
122 The AltOS Map CGI Script parses the Map URI and passes that
123 information to the AltOS Map Cache Manager using the AltOS Tile
124 Specifier syntax. This is a JSON representation of the same data
125 provided by the URI:
126
127 \       {
128 \               "lat": <latitude>,
129 \               "lon": <longitude>,
130 \               "zoom": <zoom-level>,
131 \               "remote_addr": "<IPv4 or IPv6 address of requesting client>"
132 \       }
133
134 Latitude and longitude are both encoded using decimal degrees with 6
135 digits following the decimal point.
136
137 === AltOS Tile Reply
138
139 Sent back from the Cache Manager to the CGI Script, this encodes the
140 status of the request and the filename of any tile data available. It
141 is encoded in JSON format:
142
143 \       {
144 \               "status": <HTTP status>,
145 \               "filename": "<absolute path to image file>",
146 \               "content_type": "<HTTP content-type>"
147 \       }
148
149 The “filename” and “content-type” elements are only included when
150 the status is _200 OK_.
151
152 === AltOS Tile Filename
153
154 While the current AltOS Map URI version only supports a limited subset
155 of the Google Maps functionality, we'll encode more of that data in
156 filenames to allow for easy expansion of functionality in the
157 future. The elements of an AltOS Tile filename consist of :
158
159  * Latitude, with N/S indicator (instead of a sign)
160  * Longitude, with E/W indicator (instead of a sign)
161  * Map type.
162  * Zoom level
163  * Scale factor. Scale, and the preceding hyphen are omitted for a scale factor of 1.
164  * Image format suffix. '.jpg' for JPEG files and '.png' for PNG files.
165
166 Latitude and longitude are both encoded using decimal degrees with 6
167 digits following the decimal point.
168
169 Map type is one of :
170
171  _hybrid_: Road graphics over satellite images
172  _roadmap_: Symbolic road map
173  _satellite_: Un-annotated satellite images
174  _terrain_: Topographic map
175
176 Here's what map filenames look like:
177
178 \       map-{N,S}<lat>,{E,W}<lon>-<type>-<zoom>[-<scale>].<format>
179 \
180 \       map-N36.508532,W107.823944-hybrid-18.jpg
181
182 To transmit this name from the AltOS Map Cache Manager back to the
183 Altos Map CGI script, the filename will be wrapped in a JSON string
184
185 == Implementation
186
187 The AltOS Map CGI Script and AltOS Map Cache Manager will both be
188 implemented in Java as much of the required Google Maps infrastructure
189 is already available in that language.
190
191 === Access Control
192
193 No access control to the service is planned at this point. If
194 necessary, we could implement username/password access control for each
195 user of the service.
196
197 === Location Restrictions
198
199 To avoid unbounded usage, and confine the utility of this service to
200 AltOS users, the service will only offer map tiles whose center
201 location is within 10 miles of one of the sites registered in
202 our launch sites database.
203
204 To allow testing of the registered launch site database, a database of
205 privileged clients will be supported. Privileged clients will have
206 unlimited access to the service.
207
208 === Per-Client Restrictions
209
210 We should implement a per-day limit on the number of tiles provided to
211 a particular requesting client. We can also rate limit clients to a
212 certain number of tiles per minute to reduce the bandwidth consumed
213 out of our server.
214
215 === Cache Lifetime Restrictions.
216
217 The Google Maps API allows for caching of map data for no more than 30
218 days. To honor this, the Cache Manager will re-fetch any requested
219 tiles when the cached version is older than this. If the fetch fails,
220 the cache manager will continue to serve the data from the cached
221 version of the file.