I have seen some questions with similar titles, but they seem to be referring to x
and y
pixel coordinates.
I am asking about the actual tile numbers of x
and y
from Google Maps getTile()
function:
To clarify the question...
Given the x, y, and zoom parameters in the getTile() function, how can I find the latitude and longitude bounds of the tile?
CoordMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
var x = coord.x,
y = coord.y,
url = "http://mt1.google.com/vt/lyrs=y&x="+x+"&y="+y+"&z="+zoom;
//other stuff
}
The only reason at the moment that I need this is that I want to determine the maximum zoom level at this tile projection. From this link: Maximum Zoom, it states that in order to find the maximum zoom, I will need a latitude and longitude value using getMaxZoomAtLatLng()
. So if I can get the bounds, then I can use any latitude and longitude points within the bounds to find my max Zoom.
Alternatives I have thought of were creating an image and checking if the src url had an error (this seems like a terrible idea to me, as I would be making many bad requests just to check if imagery existed).
var img = new Image;
img.onload = function() {/*imagery exists*/ }
img.onerror = function() {/*past maximum zoom*/ }
img.src = url;
EDIT:
After further investigation, I realize that the getMaxZoomAtLatLng()
function is using an ajax call which will not fit into my plans. But I still am interested in how to find the latitude and longitude boundaries of a given tile ( that could be useful for other applications ).
Assuming a basic google-map using mercator-projection and a tileSize of 256x256:
The number of tiles on each(x-axis and y-axis) is Math.pow(2,zoom)
, so on zoom 0
the map is using 1 tile, on zoom 1
4 tiles, on zoom 2
16 tiles and so on.
First calculate the southWest/northeast-points of the tile.
the size of a tile (in points) is 256/Math.pow(2,zoom)
southWest-point:
x = tile.x * tileSizeInPoints
y = (tile.y * tileSizeInPoints) + tileSizeInPoints
northEast-point:
x = (tile.x * tileSizeInPoints) + tileSizeInPoints
y = tile.y * tileSizeInPoints
These points must be translated to LatLngs. When you use a map you may use the method fromLatLngToPoint of the maps projection.
For a custom implementation take a look at https://developers.google.com/maps/documentation/javascript/examples/map-coordinates.
A possible API-independant implementation:
MERCATOR={
fromLatLngToPoint:function(latLng){
var siny = Math.min(Math.max(Math.sin(latLng.lat* (Math.PI / 180)),
-.9999),
.9999);
return {
x: 128 + latLng.lng * (256/360),
y: 128 + 0.5 * Math.log((1 + siny) / (1 - siny)) * -(256 / (2 * Math.PI))
};
},
fromPointToLatLng: function(point){
return {
lat: (2 * Math.atan(Math.exp((point.y - 128) / -(256 / (2 * Math.PI)))) -
Math.PI / 2)/ (Math.PI / 180),
lng: (point.x - 128) / (256 / 360)
};
},
getTileAtLatLng:function(latLng,zoom){
var t=Math.pow(2,zoom),
s=256/t,
p=this.fromLatLngToPoint(latLng);
return {x:Math.floor(p.x/s),y:Math.floor(p.y/s),z:zoom};
},
getTileBounds:function(tile){
tile=this.normalizeTile(tile);
var t=Math.pow(2,tile.z),
s=256/t,
sw={x:tile.x*s,
y:(tile.y*s)+s},
ne={x:tile.x*s+s,
y:(tile.y*s)};
return{sw:this.fromPointToLatLng(sw),
ne:this.fromPointToLatLng(ne)
}
},
normalizeTile:function(tile){
var t=Math.pow(2,tile.z);
tile.x=((tile.x%t)+t)%t;
tile.y=((tile.y%t)+t)%t;
return tile;
}
}
call MERCATOR.getTileBounds()
by supplying a single object as argument with the following format:
{
x:tileIndexX,
y:tileIndexY,
z:zoom
}
Demo: http://jsfiddle.net/doktormolle/55Nke/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With