While google maps v2 had a simple fromLatLngToContainerPixel(latlng, z) on every projection (and the other way around as well), v3 seems to be lacking a bit in its api. While this certainly isn't the only thing the api lacks, it's at least something that was solved quite quickly with the help of the google maps group.
So in v2 you could do
map.getProjection().fromLatLngToContainerPixel(latlng, 4) and you'd get the proper point according to given zoom index. v3 almost has that method, but only on the
MapCanvasProjection object and only without a zoom parameter. Suck.
So here is your
fromLatLngToPixel and
fromPixelToLatLng, in gmaps v3 style. I found it in
this post (
last reply, I don't know how to link to that directly... UI fail?).
/**
* @param {google.maps.Map} map
* @param {google.maps.LatLng} latlng
* @param {int} z
* @return {google.maps.Point}
*/
var latlngToPoint = function(map, latlng, z){
var normalizedPoint = map.getProjection().fromLatLngToPoint(latlng); // returns x,y normalized to 0~255
var scale = Math.pow(2, z);
var pixelCoordinate = new google.maps.Point(normalizedPoint.x * scale, normalizedPoint.y * scale);
return pixelCoordinate;
};
/**
* @param {google.maps.Map} map
* @param {google.maps.Point} point
* @param {int} z
* @return {google.maps.LatLng}
*/
var pointToLatlng = function(map, point, z){
var scale = Math.pow(2, z);
var normalizedPoint = new google.maps.Point(point.x / scale, point.y / scale);
var latlng = map.getProjection().fromPointToLatLng(normalizedPoint);
return latlng;
};
It works quite simple actually. But it would probably help if the docs would have explained this one slightly better.
Some interesting facts to help explaining this function:
map.getProjection().fromLatLngToPoint returns normalized values, between 0 and 255
- each tile in google maps is 256 pixels wide and high
- when zooming in google maps, the deeper layer is twice the size of the layer above
So "my"
latlngToPoint function uses these facts. First it asks where the
latlng would be on zoom level 0 (this is one tile of 256x256 pixels). You can't get to zoom level 0 by normal means (but you can somewhat clearly see that level 1 consists of four tiles). We get a very high precision floating number back, between 0 and 255.
Next we take the zoom level. Each level increases the size by two fold so to get the size of the "world" at zoom level z, we need to double it z times. That's what
Math.pow(2,z) does. The last step is actually multiplying the normalized coordinate with the zoom factor and voila, there's the point in our world at zoom level z.
Of course,
pointToLatlng is simply the inverse of that.
Please note that there is
another method (
again, last reply) of doing this. Sort of. It involves creating a new
MapCanvasProjection and using
fromLatLngToContainerPixel from that. Like..
overlay = new google.maps.OverlayView();
overlay.draw = function() {};
overlay.setMap(map);
var point = overlay.getProjection().fromLatLngToContainerPixel(latLng);
I can only say uuuuugeleeeeey. Thanks. Please use the two functions I described first :)
Hope it helps you :)