Marius Manastireanu
Marius Manastireanu

Reputation: 2586

Convert (x, y) pixel coordinates in google.maps.Point

I am trying to find out the LatLng based on my x,y pixel coordinates (and of course map options, such as zoom and center).

In order to do so, I posted another question and someone came up with this solution, from this post:

/**
* @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; 
};

As you can notice from the code sample, the function uses as argument a google.maps.Point, therefore I need to convert my screen pixel coordinate into a google.maps.Point and I have no clue how, since their documentation of the API is not quite verbose...

Can you please help me? Or am I missing something on the way?

Upvotes: 2

Views: 2687

Answers (2)

Keith
Keith

Reputation: 994

You could use an overlay that draws nothing in order to get at the super valuable function, fromContainerPixelToLatLng()

var overlay = new google.maps.OverlayView();
overlay.draw = function() {}; // empty function required
overlay.setMap(map);

var coordinates = overlay.getProjection().fromContainerPixelToLatLng(
    new google.maps.Point(x, y)
);

console.log(coordinates.lat + ", " + coordinates.lng);

Upvotes: 2

Marius Manastireanu
Marius Manastireanu

Reputation: 2586

After some research and some fails I came up with a solution. Following the documentation from this link I found out that the google Points are computed in the range of x:[0-256], y:[0-256] (a tile being 256x256 pixels) and the (0,0) point being the leftmost point of the map (check the link for more information).

However, my approach is as it follows:

  • having the x and y coordinates (which are coordinates on the screen - on the map) I computed the percentage where the x and y coordinates were placed in response to the div containing the map (in my case, the hole window)

  • computed the NortEast and SouthWest LatLng bounds of the (visible) map

  • converted the bounds in google Points

  • computed the new lat and lng, in google points, with the help of the boundaries and percentage of x and y

      // retrieve the lat lng for the far extremities of the (visible) map
      var latLngBounds = map.getBounds();
      var neBound = latLngBounds.getNorthEast();
      var swBound = latLngBounds.getSouthWest();
    
      // convert the bounds in pixels
      var neBoundInPx = map.getProjection().fromLatLngToPoint(neBound);
      var swBoundInPx = map.getProjection().fromLatLngToPoint(swBound);
    
      // compute the percent of x and y coordinates related to the div containing the map; in my case the screen
      var procX = x/window.innerWidth;
      var procY = y/window.innerHeight;
    
      // compute new coordinates in pixels for lat and lng;
      // for lng : subtract from the right edge of the container the left edge, 
      // multiply it by the percentage where the x coordinate was on the screen
      // related to the container in which the map is placed and add back the left boundary
      // you should now have the Lng coordinate in pixels
      // do the same for lat
      var newLngInPx = (neBoundInPx.x - swBoundInPx.x) * procX + swBoundInPx.x;
      var newLatInPx = (swBoundInPx.y - neBoundInPx.y) * procY + neBoundInPx.y;
      var finalResult = new google.maps.Point(newLngInPx, newLatInPx);
    

Upvotes: 2

Related Questions