I was born at Tsrrtrsqsqqqrqrtsst

Sunday, July 17th, 2005

I’ve been playing around with the marvellous and , and just noticed how elegant the system for addressing image tiles is [specifically from Google Maps].

Google Maps now offers a satellite view as well as a map view, and does so using the former Keyhole database. The view is built using tiles— 256 pixel square JPEGs fetched from the the kh.google.com server.

As of this writing, the image URLs take the form:

http://kh.google.com/kh?v=projection&t=address

projection is either 2 or 3. Selecting 2 gives a plate carrée projection, while 3 provides a Mercator projection, ensuring that local features are uniformly scaled. [Update: projection type 2 is no longer supported]

quadtree recursive subdivisionaddress is a short string of letters encoding the location of a particular map square. The addressing mode is quite elegant, with the world recursively quartered until the desired detail level is reached. This simple heirarchical structure is known as a quadtree, and is commonly used in computer graphics. For whatever reason, Google labels the four quadrants q, r, s & t.

The topmost tile contains the entire world map, and is referenced with an address of t. Adding an s to this selects the lower-right quadrant of the map, and adding a further r selects the upper-right of that map, resulting in a tile containing most of Australasia. Each time an extra letter is added, we descend into a new quadrant, and this continues until the maximum detail is reached. So, for example, the hospital where I was born can be uniquely addressed [to within a hundred metres or so] using the URL:

Converting between Quadtree addresses and Longitude/Latitude

This page contains Javascript to returns all tiles containing a particular location, with each yellow quadrant marking the region occupied by the subsequent map. If you’d like to copy the code you can view the page source, or simply use the excerpts shown below. The first two functions are based on equations from Wikipedia’s entry on the Mercator Projection.

function MercatorToNormal(y)
{
y = -y * Math.PI / 180; // convert to radians
y = Math.sin(y);
y = (1+y)/(1-y);
y = 0.5 * Math.log(y);
y *= 1.0 / (2 * Math.PI); // scale factor from radians to normalized
y += 0.5; // and make y range from 0 - 1
return y;
}
 
function NormalToMercator(y)
{
y -= 0.5;
y *= 2 * Math.PI;
y = Math.exp(y * 2);
y = (y-1)/(y+1);
y = Math.asin(y);
y = y * -180/Math.PI;
return y;
}
 
function GetCoordinatesFromAddress(str)
{
// get normalized coordinate first
var x = 0.0;
var y = 0.0;
var scale = 1.0;
str = str.toLowerCase();
str = str.substr(1); // skip the first character
while (str.length > 0)
{
scale *= 0.5;
var c = str.charAt(0); // remove first character
if (c == ‘r’ || c == ’s’)
{
x += scale;
}
if (c == ‘t’ || c == ’s’)
{
y += scale;
}
str = str.substr(1);
}
var ret = new Object();
ret.longmin = (x - 0.5) * 360;
ret.latmin = NormalToMercator(y);
ret.longmax = (x + scale - 0.5) * 360;
ret.latmax = NormalToMercator(y + scale);
ret.long = (x + scale * 0.5 - 0.5) * 360;
ret.lat = NormalToMercator(y + scale * 0.5);
return ret;
}
 
function GetQuadtreeAddress(long, lat)
{
// now convert to normalized square coordinates
// use standard equations to map into mercator projection
var x = (180.0 + parseFloat(long)) / 360.0;
var y = MercatorToNormal(parseFloat(lat));
var quad = “t”; // google addresses start with t
var lookup = “qrts”; // tl tr bl br
for (digits = 0; digits < 24; digits++)
{
// make sure we only look at fractional part
x -= Math.floor(x);
y -= Math.floor(y);
quad = quad + lookup.substr((x>=0.5?1:0) + (y>=0.5?2:0), 1);
// now descend into that square
x *= 2;
y *= 2;
}
return quad;
}

feed

26 Comments

  1. Tim says:

    I’m fairly sure that I’m somewhere in tsrrttsrsqqrrs, but it’s kinda hard to follow with all that pixellation :/

  2. mark says:

    Annoying when you just miss out isn’t it? My parents’ house is within 100m of the hi-resolution images– if it were in the middle of town I think I would be creating a poster sized print for them right now…

  3. Narref Blog: Powerful, yet simlpe.... says:

    […] log] Imatges per refer讣nciaPosted by Ferran on 30/07/2005 06:07:41 pmHe llegit al blog de Intepid una manera d’obtenri dinamicament la imatge per satel.lit d’una posici󠤥 del planeta, o d’ […]

  4. Nikolay Klimchuk says:

    Yesterday projection=2 was disabled

  5. mark says:

    Entry updated with source code for converting long/lat to quadtree address.

  6. sc says:

    very good,if I have convert from a latitude & longitude to a Google Maps quadtree address (an URL to a particular image tile.How can I get all image tiles in one range from latitude to latitude and longitude to longitude.

  7. Peter says:

    Hey man,
    I say: Well done!!! Your code workes very well! Now I need another function and maybe you have it already?!? Thats why I ask… ;-)
    You have described how to get the filename by coordinates, but I need to get the coordinates by filename! Is that possible?!?
    Thanks for help as soon as possible. Right now I am sitting on that problem becasue I am going to asia for earthquake help next week and I need some more satelite files. Thanks, Pete

  8. Michael says:

    Thanks for the code. There seems to be a typo: shouldn´t this be (digits–) instead of (digits-)?

  9. mark says:

    It seems that my blogging software is displaying two minus signs as an endash “–”, and has done exactly the same with your comment. I haven’t figured out how to turn this “feature” off yet…

  10. talk more on google map - danielyuen.hk Blog says:

    […] And the Satellite ’s url hack u can find from here: intepid » I was born at TSRRTRSQSQQQRQRTSS […]

  11. sc says:

    Because Mercator Projection is limietd in hignest latitude,I want to konw that Google Earth how to solve this question.

  12. mark says:

    It is likely that beyond a certain latitude Google Earth switches to a different coord system, using separate maps for the poles

  13. sc says:

    But,in the first and the second layers we can find that Google earth using Mercator Projection .Maybe the third,the forth also using Mercator Projection .In fact Google eatrh can not using Mercator Projection in all layers.But how to judge it?

  14. Tian says:

    A stupid question about the range of y in the line “y = 0.5 * Math.log((1+Math.sin(y)) / (1 - Math.sin(y)))”. Isn’t it from negative infinite to infinite? How could it be scaled to normalized? Thanks a lot. Confused Tian

  15. mark says:

    Hi Tian, you can see this mentioned in a later post here.

  16. Tian says:

    Thanks mark :-) I made a reverse code to get long&lat from a quad based on yours.

  17. Jean CARTIER says:

    Very cool !
    Exactly what I was looking for !

    Thanks !

  18. Selwyn Simsek says:

    I know this is old..but thank you! This is just what I have been looking for!

  19. ahmed abulmagd says:

    you hack is more elegant than thier design

  20. leon says:

    good artical!

  21. Daniel says:

    I need calibrate a qrst type img. I need know lat/long of 2 corner of img. Can help me?

  22. khalid omar says:

    i’m also need to know the latlon of two corner of the image

  23. mark says:

    I’ve added function GetCoordinatesFromAddress(str) to the code (and here) which returns center, minimum and maximum coordinates from quadtree address

  24. khalid omar says:

    realy thank you this is agreat work

  25. Gladcolor says:

    Really a good job, thank! I am going to programming on google map, and I will email you if any problem. Don’t refuse me! Thanks again.

  26. Saverio says:

    Nice job! I have a question, though: If the whole 360 degrees of the long are divided by 2 the same number of times that the 180 degrees of the lat, then each tile is a rectangle (wide one) near the equator, and a rectangle (tall one) near the poles, being a square only when lat = 60. Why all the tiles are square?

Leave a Comment