Add your own alternative version
Stats
619.1K views 4.2K downloads 202 bookmarked
Posted
12 Jul 2006

Comments and Discussions



seclen is wrong. Should be...
int seclen = ( (x * 3) + y ) % 8;






What is this function for?





Example: tile from Label layer:
http://mt1.google.com/mt?v=w2t.80&hl=en&x=1&y=2&zoom=15&s=Galil
mt1  1=servernum
s=Galil  Galil=secure word with seclen=5 (=substring of word Galileo)





OK, but what is the advantage of this "securemode"?





In this article is said that the algorithm to calculate the string to get a tile from the latitude is not correct, since it doesn't consider the Mercator number. Indeed, that is true, although no solution is given. This is my Java (working) code to construct the string with 'q', 'r', 's' and 't' from given coordinates, based on the code proposed here:
public static String calculateZoom(double latitude, double longitude, int zoom) {
if(zoom > 17) // 17 is maximum zoom allowed
return "t";
double xmin = 180;
double xmax = 180;
double xmid = 0;
double merc = 0;
String location="t";
for (int i = 0; i < zoom; i++) {
xmid = (xmax + xmin) / 2;
merc = getMercatorTile(latitude, i + 1);
if(longitude > xmid) { // 'r' o 's'
xmin = xmid;
if(merc % 2 == 0) { // 'r' // L'idea è che essendo potenze di 2, se il numero è pari, si deve salire
location += "r";
} else { // 's'
location += "s";
}
} else {
xmax = xmid;
if(merc % 2 == 0) { // 'q'
location += "q";
} else { // 't'
location += "t";
}
}
}
return location;
}
private static int getMercatorTile(double lat, int zoom) {
if (lat > 90) lat = lat  180;
if (lat < 90) lat = lat + 180;
double phi = Math.PI * lat / 180;
double res = 0.5 * Math.log((1 + Math.sin(phi)) / (1  Math.sin(phi)));
double maxTileY = Math.pow(2, zoom);
// res varia tra 0 e pi greco
int result = (int)(((1  res / Math.PI) / 2) * (maxTileY));
return result;
}
Hope this helps!





It is forbidden it terms of use by google to use their map tiles without google JavaScript API. Have you heard about it? Did you try to speak with Google if it possible to use their map tiles in legal way?





I have read the terms and licences, and I think that I'm just at the limit of the licence.
If I remember well, the javascript api is needed for the streetview feature. But that's not the purpose of this article.
For maps, the licence says that it's not allowed to store images from google.
Again from my memory... but getting images directly from their servers seems to be allowed.
I don't think that google will be angry if you use their data for a personnal application, however, I think that for a professional application, you should contact google for a fully legal use of the picture.
regards
Pascal.





IMHO you crossed the limit border ...
I don't know if google will be angry but for sure it is a question of honesty and ethics if you steal pictures from a webserver or not.
regards
Daniel






Seems everyone has given up.





Or maybe the others have solve their problems...
I have other projects running, and this one is no more my priority, sorry...
However, I will try to answer questions, as far as it doesn't take too long to find a solution.
You can also try to find a solution by yourself... You can find many formulas on the internet, some keyword are "Mercator", and "Gudermannian".
wikipedia for examples helps a lot : http://en.wikipedia.org/wiki/Mercator_projection[^]
good luck
Pascal.





OK, just worked out how to get the x and y inside a tile, it's very precise too! Now I have my homemade GPS system.





Kewl ! congratulations !
Now you can write an article presenting your project ...





Hey, it would be great if you would share the solution.
Thanks, Tim





Yes, I will be writing a complete solution in a few days time. Will keep you guys posted.









This program is only Tile Image..I can't it.
How to do realtime download tile image(Chaching?)?
and then.. Zoom is nocorrect...
hello~





This article explains how to get images from google. If you want to do a smooth zoom, or build big maps for printing, that's your job...
Regards
Pascal





Hi Pascal,
can you please demonstrate the algorithm to work out the x,y pixel in tile when x = 258340 and y = 160003 with GPS coordinate is lat: 36.88303 long: 174.77634?
I am sure other ppl will understand better in this way. Cheers!
James





ok, let me take some time to prepare something clear and bugproof, as it sure can be interesting to other people...
Regards
Pascal





hope to have your solutions soon, I managed to download 27700 tiles from google last night, so your solution is the last step to finish my GPS project





how to get X and Y coordinates of a point int a tile, at a certain zoom level, knowing it's GPS coordinates :
That's THE question that seems to be the most frequenlty asked.
the GPS coordinates are : lat = 36.88303 long=174.77634
We will work at zoom level 1. The tile is x=258340 / y=160003
At level 1, we have 2^18 tiles hotizontaly and verticaly to cover the globe.
Remember that tiles are 256x256 pixels.
I will explain with the longitude, as it will be easier to understand :
In the article, the algo to get the longitude is :
//correct the longitude to go from 0 to 360
longitude=180+longitude;
//caculate the number of tiles :
double nbTiles = pow(2,(17zoom));
//find tile size from zoom level
double longTileSize=360/nbTiles;
//find the tile coordinates
int tilex=(int)(longitude/longTileSize);
Now imagine, that we have 1px tiles.
Then we will have 256x more tiles in width and height.
nbTiles = 256 * pow (2,17zoom);
then compute the rest of the longitude using that new value, and you should
find a value of 66135103
now, if I take the rest of the integer division (mod), of that result by 256,
I find 63.
This should be the value of the pixel corresponding to the longitude in the tile.
Try to do the same with the lalitude, using the mercator formula... that should work
regards
Pascal





Hi Pascal,
Is this how we get the x and y? I am using zoom level 0 and the x,y pixel I got is wrong...
private Point getXYPixelFromTile(double latitude, double longitude)
{
double nbTiles = Math.Pow(2, 17  (zoom))*256;
double correctedLong = 180 + longitude;
double longTileSize = 360 / nbTiles;
int tilex = Convert.ToInt32(correctedLong / longTileSize) % 256;
double correctedLat = 0;
if ((latitude < 90)  (latitude > 90))
{
correctedLat = 90  latitude;
}
else
{
correctedLat = latitude;
}
double phi = Math.PI * correctedLat / 180;
double mercator = 0.5 * Math.Log((1 + Math.Sin(phi)) / (1  Math.Sin(phi)));
int tiley = Convert.ToInt32(((1  (mercator / Math.PI)) / 2) * nbTiles) % 256;
return new Point(tilex, tiley);
}
regards
James





Hi Pascal,
any updates please?
Cheers
James





This seems to work for the Longitude:
public static int getLongitudePos(double longi, int zoom) {
double numberTiles = 256*Float11.pow(2, zoom); // Number of Tiles with 1px for given zoom level
double longitude = 180 + longi; // Correct the Longitude to go from 0 to 360
double longTileSize = 360/numberTiles; // Find Tile size from zoom level
int tilex = (int)(longitude/longTileSize); // Find Tile Number
int xPos = tilex % 256; // Calculate Longitude Position
System.out.println("Longitude position: "+xPos);
return xPos;
}
Any ideas for the Latitude?
Thanks, Tim





Hi Tim,
Your calculation has the only difference is:
256*Float11.pow(2, zoom);
mine is:
256*Float11.pow(2, 17  zoom);
however I tried both, and the x,y pixel is incorrect.
cheers, James





this c# function is base on Pascal's tutorial
private Point getTileXY(double lat, double lon)
{
double nbTiles = Math.Pow(2,17 (1));
double correctedLong = 180 + lon;
double longTileSize = 360 / nbTiles;
int tilex = (int)(correctedLong / longTileSize);
double correctedLat = 0;
if ((lat < 90)  (lat > 90))
{
correctedLat = 90  lat;
}
else
{
correctedLat = lat;
}
double phi = Math.PI * correctedLat / 180;
double mercator = 0.5 * Math.Log((1+Math.Sin(phi))/(1Math.Sin(phi)));
int tiley = (int)(((1  (mercator / Math.PI)) / 2) * nbTiles);
return new Point(tilex, tiley);
}
modified on Sunday, February 24, 2008 3:24 PM





Hi Guys,
I am writing a program to rip the maps and store them on my harddrive, it's pretty simple by specifying the top left x,y and bottom right x,y
I am awared of google's detection mechanism, and I shuffled the coordinates so it doesn't go like x = 1, 2, 3, 4, 5 etc...
However I am still getting "forbidden" message.... any ideas?
source code:
int xstart = 0;
int ystart = 0;
int xend = 0;
int yend = 0;
public GoogleMapStore()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
xstart = 258330;
ystart = 160003;
xend = 258350;
yend = 160030;
ArrayList xArray = new ArrayList();
ArrayList yArray = new ArrayList();
for (int x = xstart; x < xend; x++)
{
xArray.Add(x);
}
for (int y = ystart; y < yend; y++)
{
yArray.Add(y);
}
ArrayList points = new ArrayList();
foreach (int xpoint in xArray)
{
foreach (int ypoint in yArray)
{
points.Add(new Point(xpoint, ypoint));
}
}
ShuffleArrayList(ref points);
WebClient wc = new WebClient();
foreach (Point p in points)
{
//Console.Out.WriteLine(p.X + "" + p.Y);
wc.DownloadFile("http://mt1.google.com/mt?n=404&v=w2.66&x=" + p.X + "&y=" + p.Y + "&zoom=1", p.X + "" + p.Y + ".png");
Thread.Sleep(1000);
}
}
private void ShuffleArrayList(ref ArrayList source)
{
ArrayList target = new ArrayList(source.Count);
Random rnd = new Random();
while (source.Count > 0)
{
int idx = rnd.Next(source.Count);
target.Add(source[idx]);
source.RemoveAt(idx);
}
source = target;
}





Shuffle is not important, but after analysing the streams between a browser and google, a friend of mine told me that there is a cookie mechanism to setup.
At first connexion, you will get a cookie that but be transmitted with other requests...





Hi Pascal,
can you please elaborate more?
James





You need set:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create( url );
request.KeepAlive = false;
request.CookieContainer = new CookieContainer();
Cookie cookie1 = new Cookie( "PREF", "ID=334ce41bb88c29d8:TM=1205424979:LM=1205424979:S=HEwCacQowpAkpAGG", "/", ".google.com" );
cookies.Add( cookie1 );
Cookie cookie2 = new Cookie( "NID", "12=OBEKICECRYqGFJxg3S4oLIo0TQySnebQRp3darA3K7gcNLpGC6o4x_giTvz50paskE7nXhOSBN8wYkmYXhhGF5PVD2qqVOQ2DORPUn8tLHjfguQgrWyTFsgQsS4hFVnB", "/", ".google.com" );
cookies.Add( cookie2 );
request.CookieContainer.Add( cookies );
request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; enUS; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14"; // or another agent
request.Referer = "http://maps.google.com/maps";
It works but use hardcoded cookies
New result of testing: cookies are not required, just UserAgent and Referer setting required.
modified on Tuesday, June 24, 2008 6:37 AM





Hi, when we use lat and long here, I got 2 formats
one is lat: 36'52.7588 long: 174'46.7855
other one is lat: 36.88303 long: 174.77634
which one should I use? can someone please use my data to show the calculation for me?
cheers!
James





Use the second one with formulas, the first one indicates parts of degrees in base 60.
(36 + 52.75/60) = 36.879
But take care, the longitude must go from 0 to 360, instead of 180 to 180.





Hi Pascal,
sorry for being stupid, can you please apply my coordinates to your fomulas?
the URL of the tile for the GPS coordinate is http://mt1.google.com/mt?n=404&v=w2.66&x=258339&y=160003&zoom=1[^]
notice the zoom is 1, what should I do?
I can't find out how to compute x=258339 and y=160003
//correct the latitude to go from 0 (north) to 180 (south),
// instead of 90(north) to 90(south)
latitude=90latitude;
//correct the longitude to go from 0 to 360
longitude=180+longitude;
//find tile size from zoom level
double latTileSize=180/(pow(2,(17zoom)));
double longTileSize=360/(pow(2,(17zoom)));
//find the tile coordinates
int tilex=(int)(longitude/longTileSize);
int tiley=(int)(latitude/latTileSize);
Thanks alot.
James
modified on Tuesday, January 29, 2008 7:34:26 PM





OK, I think I understand your problem :
The above formula is ok for longitude, but for latitude, you have to compute using the mercator formula.
Here is the detail for both :
common part both : compute the number of tiles using zoom factor of 1 :
nbTiles = pow(2,17 (1)) = 262144
Longitude (easy first) :
initial longitude : 174.77634
corrected longitude : 174.77+180 = 354.77634
longTileSize = 360 / nbTiles = 0.00137329
so tilex = corrected longitude / longTileSize = 354.77634 / 0.00137329 = 258340 NOT BAD !!
Latitude (the hard part) :
we use the mercator formula :
initial latitude : 36.88303
corrected value : 36.88303 (value already in 90 ... 90 range)
phi = pi * latitude / 180 = 0.643730312
mercator projection : 0.5 * ln((1+sin(phi))/(1sin(phi))) = 0.693433709
tile id : ((1 (mercator/pi))/2) * nbtiles = 160003.1038 YEAH, RIGHT ON !!
hope it will help....
regards
Pascal





Hi Pascal,
been waiting for the answer for whole day, it certainly helps to clear my mind, thanks!
I am sure I will have more questions to ask while my project proceeds.
cheers!
James





given a tile, how to get the surroudning tiles of that tile?
cheers!
James





For road maps, the x and y coordinates of the tile are passed directly in the url.
So supposing you have a tile with coordinates X and Y.
the 8 Surrounding tiles will be :
(X1,Y1)  (X,Y1)  (X+1,Y1)

(X1,Y)  (X,Y)  (X+1,Y)

(X1,Y+1)  (X,Y+1)  (X+1,Y+1)
does it answers your question ?





thank you, it's very useful.





Thank you for this article, it helped me a lot
btw, there should be
double maxTileY = Math.Pow(2, (17zoom));
in getMercatorLatitude(...)





hi folks,
question from a beginner...
the first tile of satimages (t) has a width of 360 degrees
in next zoomlevel(tq) (tr) (ts) (tt) the width is 180 degrees
next level (t..) the width is 90 degrees, and so on
but what about the image height ???
how do i compute the heigh for a given zoomlevel ???
SmileT4





Hi... this question is THE most frequently asked : how to get back from mercator coordinates to latitude / longitude.
You can look at this response from pelsta, I think it could help...
regards
Pascal





hi pascal,
thanks for the fast answer.
but i don't understand the code...
i have an excel sheet with a line
360 180 90 45 22.5 11.25 ...
... representing the width in degrees (for each of the 15? zoomlevels)
now i need a formula for the height for each level
(=widht * ...)
can you help ???
regards
SmileT4





Ok, I understand. The answer is : you can't do that.
The vertical angle covered by a tile doesn't only depends from the zoom level, but also from the latitude itself. When you go to the poles, parallels get closer, so the angle covered by the tile gets smaller.
this article on wikipedia explains the mercator projection.
and this article tells about parallels and lalitude...
You'll have to find a workaround.
Good luck
Pascal





...but...
the height of the tiles for each zoomlevel is fix when you move east or west.
it only changes when you move north or south...
my problem is this:
when i download tile "tsqqtrrtqqts" and the 8 tiles around to build a "map"
i need to know the corner coords for calibrating...
calculating the width in degrees is easy, i wanna know how to
calculate the height...
SmileT4





Thank you Pascal Buirey.
for exam.
eiffel tower, france
latitude : 48.858375
longitude : 2.294432
convert to tile id is "trtqttqqrrqrtqqqsst"
and have got 256x256 jpg image.
then how to calculate this jpg image start longitute and latitute.
and how to know correct degrees point of this jpg image.







General News Suggestion Question Bug Answer Joke Praise Rant Admin Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

