Introduction
This is my analysis about how Google map works, and specially how the tiles are encoded. Google map uses pre-rendered tiles that can be obtained with a simple URL. This article explains how to build the URL for a tile from its geo coordinates (latitude/longitude).
Map Tile Encoding
Google map uses two different algorithms to encode the location of the tiles.
For Google map, the URL of a tile looks like http://mt1.google.com/mt?n=404&v=w2.12&x=130&y=93&zoom=9 using x and y for the tile coordinates, and a zoom factor. The zoom factor goes from 17
(fully zoomed out) to 0
(maximum definition). At a factor 17
, the whole earth is in one tile where x=0 and y=0. At a factor 16
, the earth is divided in 2x2 parts, where 0<=x<=1 and 0<=y<=1, and at each zoom step, each tile is divided into 4 parts. So at a zoom factor Z, the number of horizontal and vertical tiles is 2^(17-z)
Algorithm to Find a Tile from a Latitude, a Longitude and a Zoom Factor
latitude=90-latitude;
longitude=180+longitude;
double latTileSize=180/(pow(2,(17-zoom)));
double longTileSize=360/(pow(2,(17-zoom)));
int tilex=(int)(longitude/longTileSize);
int tiley=(int)(latitude/latTileSize);
In fact this algorithm is theoretical as the covered zone doesn't match the whole globe.
Servers
Google uses four servers to balance the load. These are mt0, mt1, mt2 and mt3.
Tile Size
Each tile is a 256x256 PNG picture.
For Satellite Images, the Encoding is a Bit Different
The URL looks like http://kh0.google.com/kh?n=404&v=8&t=trtqtt where the 't' parameters encode the image location. The length of the parameter indicates a zoom level.
To see the whole globe, just use 't=t'. This gives a single tile representing the earth. For the next zoom level, this tile is divided into 4 quadrants, called, clockwise from top left : 'q' 'r' 's' and 't'. To see a quadrant, just append the letter of that quadrant to the image you are viewing. For example :'t=tq' will give the upper left quadrant of the 't' image. And so on at each zoom level...
Algorithm to Find a Tile from a Latitude, a Longitude and a Zoom Factor
double xmin=-180;
double xmax=180;
double ymin=-90;
double ymax=90;
double xmid=0;
double ymid=0;
string location="t";
double halflat = latitude / 2;
for (int i = 0; i < zoom; i++)
{
xmoy = (xmax + xmin) / 2;
ymoy = (ymax + ymin) / 2;
if (halflat > ymoy)
{
ymin = ymoy;
if (longitude < xmoy)
{
location+= "q";
xmax = xmoy;
}
else
{
location+= "r";
xmin = xmoy;
}
}
else
{
ymax = ymoy;
if (longitude < xmoy)
{
location+= "t";
xmax = xmoy;
}
else
{
location+= "s";
xmin = xmoy;
}
}
}
Again, this algorithm is quite theoretical, as the covered zone doesn't match the full globe.
Servers
Google uses four servers to balance the load. These are kh0, kh1, kh2 and kh3.
Tile Size
Each tile is a 256x256 JPG picture.
Mercator Projection
Due to the Mercator projection, the above algorithm has to be modified. In Mercator projection, the spacing between two parallels is not constant. So the angle described by a tile depends on its vertical position.
Here comes a piece of code to compute a tile's vertical number from its latitude.
private int getMercatorLatitude(double lati)
{
double maxlat = Math.PI;
double lat = lati;
if (lat > 90) lat = lat - 180;
if (lat < -90) lat = lat + 180;
double phi = Math.PI * lat / 180;
double res;
res = 0.5 * Math.Log((1 + Math.Sin(phi)) / (1 - Math.Sin(phi)));
double maxTileY = Math.Pow(2, zoom);
int result = (int)(((1 - res / maxlat) / 2) * (maxTileY));
return (result);
}
Covered Zone
Theoretically, latitude should go from -90
to 90
, but in fact due to the Mercator projection which sends the poles to the infinites, the covered zone is a bit less than -90
to 90
. In fact the maximum latitude is the one that gives PI
(3.1415926) on the Mercator projection, using the formula Y = 1/2((1+sin(lat))/(1-sin(lat)))
(see the link in the Mercator paragraph).
Protection
Google map uses a protection mechanism to keep a good quality of service. If one makes too many requests, Google map will add its IP address to a blacklist, and send a nice message:
Google Error
We're sorry... ... but your query looks similar to automated requests from a computer virus or spyware application. To protect our users, we can't process your request right now. We'll restore your access as quickly as possible, so try again soon. In the meantime, if you suspect that your computer or network has been infected, you might want to run a virus checker or spyware remover to make sure that your systems are free of viruses and other spurious software. We apologize for the inconvenience, and hope we'll see you again on Google.
To avoid being blacklisted, developers should use a caching mechanism if possible...
Sat Examples
See the whole globe at http://kh0.google.com/kh?n=404&v=8&t=t.
And the four corresponding quadrants: (note the 4 servers name to balance the load)
- http://kh0.google.com/kh?n=404&v=8&t=tq
- http://kh1.google.com/kh?n=404&v=8&t=tr
- http://kh2.google.com/kh?n=404&v=8&t=ts
- http://kh3.google.com/kh?n=404&v=8&t=tt
Map Examples
See the whole globe at http://mt1.google.com/mt?n=404&v=&x=0&y=0&zoom=17.
And the four corresponding quadrants:
- http://mt0.google.com/mt?n=404&v=&x=0&y=0&zoom=16
- http://mt1.google.com/mt?n=404&v=&x=1&y=0&zoom=16
- http://mt2.google.com/mt?n=404&v=&x=0&y=1&zoom=16
- http://mt3.google.com/mt?n=404&v=&x=1&y=1&zoom=16
Nice, isn't it?
For a sample code written in C#, see the download at the top of this article.
History
- Article edited: Google map has changed the v parameter for the maps. It was 2.12 when I wrote this article, but it's now 2.66. I suppose this is a version number or something like that...