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