How to get screen XY from Google maps (V3) LatLng?
Asked Answered
P

2

7

I have polyline in my map. I want to know the pixel (screen) xy-coordinates, when user clicks the polyline. Click event only returns the LatLng object, so does anyone have a clue how to get the pixel coordinates from latLng?

I would appreciate very much if someone could help me!

Phyletic answered 29/3, 2011 at 11:34 Comment(2)
when you say pixel coordinates do you mean x y coordinates of the mouse?Hartwig
Yep, exactly and the xy of the container divPhyletic
E
10

If you have the LatLng object, you can use the google map projection object to transform it into tile coordinates and then into pixel coordinates:

For the docs on the projection class: https://developers.google.com/maps/documentation/javascript/reference#Projection

Google's example explaining how to transform a LatLng into a pixel coordinate: https://developers.google.com/maps/documentation/javascript/examples/map-coordinates?csw=1

There's one catch. The above will give you the pixel coordinates inside google's map div (which you may want depending on your needs). If you want the pixels relative to the top left corner of the screen, there's one more step. You need to do the same projection on the the viewport's top left corner and subtract the two. This will give you the pixel coordinates of the LatLng point.

The code I finally used looked like this (note that "latLng" is an input):

var numTiles = 1 << map.getZoom();
var projection = map.getProjection();
var worldCoordinate = projection.fromLatLngToPoint(latLng);
var pixelCoordinate = new google.maps.Point(
        worldCoordinate.x * numTiles,
        worldCoordinate.y * numTiles);

var topLeft = new google.maps.LatLng(
    map.getBounds().getNorthEast().lat(),
    map.getBounds().getSouthWest().lng()
);

var topLeftWorldCoordinate = projection.fromLatLngToPoint(topLeft);
var topLeftPixelCoordinate = new google.maps.Point(
        topLeftWorldCoordinate.x * numTiles,
        topLeftWorldCoordinate.y * numTiles);

return new google.maps.Point(
        pixelCoordinate.x - topLeftPixelCoordinate.x,
        pixelCoordinate.y - topLeftPixelCoordinate.y
)
Exodus answered 3/12, 2013 at 21:14 Comment(3)
Works like a charm. This is currently the correct and complete answer!Irkutsk
I know this is an old question, but could you explain this line to me? "var numTiles = 1 << map.getZoom();"Impeach
@Impeach It has been a long while, but from what I recall the number of tiles that could be in the viewport something like 2 ^ zoom level. That line could be rewritten to Math.pow(2, 15) to be a little more clear.Exodus
J
0

Answer from @Bryan Johnson is correct but not enough in some cases, so I note it here for someone (or me in future) who need it:

  1. if title != 0, it no longer correct
  2. if you change zoom, drag map, it no longer correct even if you handle it in zoom_changed or bounds_changed. The projection does not seem to match with map animation.

So in order to get correct coordinate all the times, you need to create a custom OverlayView and handle projection change in draw function.

I made an example here:

jsfiddle
https://jsfiddle.net/tienketnoi/x4610Lsb/33/

Also you can check out the original guide from google here: https://developers.google.com/maps/documentation/javascript/customoverlays

Jessamine answered 7/7, 2023 at 8:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.