How to get latitude and longitude from marker right click event

2,609 views
Skip to first unread message

Kevin

unread,
Dec 16, 2010, 4:13:55 PM12/16/10
to google-map...@googlegroups.com
How do you determine the coordinates of the marker clicked on in it's right click event handler?  And an even bigger question, how do you make it work for all browsers?
 
My scenario:
When a marker is right clicked, display a context menu at the marker and save the latLon coordinates for later use.
When "Zoom in" to marker is selected on the context menu, center the map on the saved coordinates and zoom in.
 
My problem:
The coordinates I am saving are wrong for all browsers except IE.
I am able to calculate the right pixel location for displaying the context menu.  That works in IE, Firefox, Chrome & Safari.  But the lat lon coords I am calculating from that pixel position are wrong for all browsers except IE.
 
Javascript:
        var _googleMap = null;
        var _overlayView = null; // This will be useful in getting latLon from pixel in map's container
        function load() {
            var mapTypes = new Array();
            mapTypes.push(google.maps.MapTypeId.ROADMAP);
            mapTypes.push(google.maps.MapTypeId.HYBRID);
            mapTypes.push(google.maps.MapTypeId.TERRAIN);
            var latlng = new google.maps.LatLng(cityLatitudeCenter, cityLongitudeCenter);
           
            var myOptions = {zoom: 8,
                             center: latlng,
                             mapTypeControlOptions: { mapTypeIds: mapTypes },
                             mapTypeId: google.maps.MapTypeId.TERRAIN };
            _googleMap = new google.maps.Map(document.getElementById("googlemap"), myOptions);
            google.maps.event.addListener(_googleMap, 'zoom_changed', CheckZoom);
            google.maps.event.addListener(_googleMap, 'bounds_changed', SetDefaultMap);  // Saves map position to cookie
            google.maps.event.addListener(_googleMap, 'center_changed', SetDefaultMap);   // Saves map position to cookie
            google.maps.event.addListener(_googleMap, 'rightclick', showContextMenu);
            google.maps.event.addListener(_googleMap, 'click', hideContextMenu);
            _overlayView = new google.maps.OverlayView();
            _overlayView.draw = function() { };
            _overlayView.setMap(_googleMap);
            loadKMLFiles();  // uses GeoXML3 to parse and place markers on map via v3 api
        }
// === Global variable that can be used by the context handling functions ==
var clickedLatLng;
 
markerContextHtml = '<div>' +
                    '<a href="javascript:zoomIn()"><div class="context" onmouseover=this.style.backgroundColor=\'#A0A0A4\' onmouseout=this.style.backgroundColor=\'#ffffff\'>&nbsp;&nbsp;Zoom In to Location&nbsp;&nbsp;<\/div><\/a>' +
                    '<a href="javascript:zoomOut()"><div class="context" onmouseover=this.style.backgroundColor=\'#A0A0A4\' onmouseout=this.style.backgroundColor=\'#ffffff\'>&nbsp;&nbsp;Zoom Out to State&nbsp;&nbsp;<\/div><\/a>' +
                    '<\/div>';
 
function showContextMenu(event) {
    // This method is called by both a right click event on the map and a right click on a marker. 
    // The marker mouseevent does not include latitude longitude coordinates
    var x;
    var y;
   
    // Get clicked pixel location
    if (event.pixel != null) {  // Map mouse event returns pixel in event
        x = event.pixel.x;
        y = event.pixel.y;
    }
    else if (BrowserDetect.browser == "Explorer") { // Marker event for IE returns pixel in event as x and y
        x = event.x;
        y = event.y;
    }
    else if (BrowserDetect.browser == "Mozilla") { // Marker event for Mozilla - must calculate x,y pixel position
        x = event.clientX - _googleMap.getDiv().offsetLeft - window.scrollX;
        y = event.clientY - _googleMap.getDiv().offsetTop - window.scrollY;
    }
    else { // Marker event for other browsers (tested for Chrome and Safari) - must calculate x,y pixel position
        x = event.pageX - _googleMap.getDiv().offsetLeft;
        y = event.pageY - _googleMap.getDiv().offsetTop;
    }
    // Store latLng for later user
    if (event.latLng != null) { // Click event on map
        clickedLatLng = event.latLng;
    }
    else { // Click event on marker doesn't contain LatLon.  Derive latLon from clicked pixel in map's container
        var xy = new google.maps.Point(x, y);
        clickedLatLng = _overlayView.getProjection().fromDivPixelToLatLng(xy);
        //clickedLatLng = new google.maps.LatLng(this.position.lat(), this.position.lon());
    }
    // Adjust the context menu location if near an edge
    if (x > _googleMap.getDiv().offsetWidth - 120) { x = _googleMap.getDiv().offsetWidth - 120 }
    if (y > _googleMap.getDiv().offsetHeight - 100) { y = _googleMap.getDiv().offsetHeight - 100 }
    // Set context menu position
    contextmenu.innerHTML = markerContextHtml;
    contextmenu.style.position = "absolute";
    contextmenu.style.left = x.toString() + "px";
    contextmenu.style.top = y.toString() + "px";
    contextmenu.style.visibility = "visible";
    // Add context menu to the map
    $(_googleMap.getDiv()).append(contextmenu);
}
 
function zoomIn() {
    // perform the requested operation
    _googleMap.setCenter(clickedLatLng);
    _googleMap.setZoom(_maxZoomLevel / 1);  // divide by one to convert to number
    // hide the context menu now that it has been used
    hideContextMenu();
}

Nathan Raley

unread,
Dec 16, 2010, 5:30:46 PM12/16/10
to google-map...@googlegroups.com
Why aren't you passing the event to the function so the function call has access to the properties triggered by the event?

--
You received this message because you are subscribed to the Google Groups "Google Maps JavaScript API v3" group.
To post to this group, send email to google-map...@googlegroups.com.
To unsubscribe from this group, send email to google-maps-js-a...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-maps-js-api-v3?hl=en.

Nathan Raley

unread,
Dec 16, 2010, 5:35:11 PM12/16/10
to google-map...@googlegroups.com
Also, why are you calculating the pixel coordinates and translating to lat/lng when the click event itself provides you with lat/lng of the point clicked or the marker clicked?
Message has been deleted

Jones, Kevin

unread,
Dec 17, 2010, 8:43:25 AM12/17/10
to google-map...@googlegroups.com

The right click event for the Map returns a MouseEvent which includes
the LatLng.  I am using it in that instance.

However, the method also handles the right click for a Marker which
returns an Event not a MouseEvent.  Event does not include a LatLng so I
have to make the calculation then.
http://code.google.com/apis/maps/documentation/javascript/reference.html
#Marker

I left this out of my code sniplet.  This is my modification to GeoXml3
that adds the rightclick event to the marker.

        if (parserOptions.rightClickFunction != null) {

            google.maps.event.addListener(marker, 'rightclick',
parserOptions.rightClickFunction);

Jones, Kevin

unread,
Dec 17, 2010, 10:05:35 AM12/17/10
to google-map...@googlegroups.com

Okay, I’ve got.  Hopefully, this will help someone else.

 

The best way to add the event listener is like this

               google.maps.event.addListener(marker, 'rightclick', function(event) { markerRightClick(event, marker.getPosition()) });

Not like this

               google.maps.event.addListener(marker, 'rightclick', markerRightClick);

 

Now you don’t have to keep a dummy OverlayView and deal with the projection like in other posts.

 

The rest of the code is like this

 

function mapRightClick(mouseEvent) {

 

    clickedLatLng = mouseEvent.latLng;  // Save for context menu “Zoom In”

 

    showContextMenu(mouseEvent.pixel.x, mouseEvent.pixel.y);

}

 

function markerRightClick(event, LatLon) {

    var x;

    var y;

   

    if (BrowserDetect.browser == "Explorer") { // Marker event for IE returns pixel in event as x and y

        x = event.x;

        y = event.y;

    }

    else if (BrowserDetect.browser == "Mozilla") { // Marker event for Mozilla - must calculate x,y pixel position

        x = event.clientX - _googleMap.getDiv().offsetLeft - window.scrollX;

        y = event.clientY - _googleMap.getDiv().offsetTop - window.scrollY;

    }

    else { // Marker event for other browsers (tested for Chrome and Safari) - must calculate x,y pixel position

        x = event.pageX - _googleMap.getDiv().offsetLeft;

        y = event.pageY - _googleMap.getDiv().offsetTop;

    }

 

    clickedLatLng = LatLon;  // Save for context menu “Zoom In”

 

    showContextMenu(x, y);

}

 

function showContextMenu(x, y) {

 

    // Adjust the context menu location if near an edge

    if (x > _googleMap.getDiv().offsetWidth - 120) { x = _googleMap.getDiv().offsetWidth - 120 }

    if (y > _googleMap.getDiv().offsetHeight - 100) { y = _googleMap.getDiv().offsetHeight - 100 }

 

    // Set context menu position

    contextmenu.innerHTML = markerContextHtml;

    contextmenu.style.position = "absolute";

    contextmenu.style.left = x.toString() + "px";

    contextmenu.style.top = y.toString() + "px";

    contextmenu.style.visibility = "visible";

 

    // Add context menu to the map

    $(_googleMap.getDiv()).append(contextmenu);

}

 

I am still curious why fromDivPixelToLatLon() was not working in the other browsers.  However, I am will to let that go for the sake of getting other things done.

 

 

From: google-map...@googlegroups.com [mailto:google-map...@googlegroups.com] On Behalf Of Nathan Raley
Sent: Thursday, December 16, 2010 5:35 PM
To: google-map...@googlegroups.com
Subject: Re: [Google Maps API v3] How to get latitude and longitude from marker right click event

 

Also, why are you calculating the pixel coordinates and translating to lat/lng when the click event itself provides you with lat/lng of the point clicked or the marker clicked?

Nathan Raley

unread,
Dec 17, 2010, 10:32:53 AM12/17/10
to google-map...@googlegroups.com
Yea, I just got back to my computer and saw your post.  I was going to tell you the marker has a getPosition that returns you its lat/lng.  Congrats on finding it yourself.

I would assume the fromDivPixelToLatLon was not being passed the right values or something along those lines.  However, you didn't post a link so we can't see exactly how your code was behaving.

However, I was going to recommend using the inverse from that and taking the lat/lng and converting that to Pixel X,Y if you were needing the pixels as you know your lat/lng are going to be correct.  There are a lot of factors that come into play when you are converting from lat/lng to Pixel or Tile X,Y and vice versa.  The Google documentation goes into some detail about how these are determined and I found a nice read on Bing Maps documentation that goes into a bit more detail that I found easier to understand.  They both use Mercator projection so the same principles apply to both.
Reply all
Reply to author
Forward
0 new messages