Showing posts with label google maps api v3 context menu dropdown. Show all posts
Showing posts with label google maps api v3 context menu dropdown. Show all posts

Monday, June 7, 2010

How to add context menu to google maps, using api V3

Here's the way how to add context menu to google map, using api V3 and jQuery.



step 1:
while initializing maps, add listener for event "rightclick":

 google.maps.event.addListener(map, "rightclick",function(event){showContextMenu(event.latLng);});

;


step 2:
Body of contextmenu is created in showContextMenu()
      function showContextMenu(caurrentLatLng  ) {
var projection;
var contextmenuDir;
projection = map.getProjection() ;
$('.contextmenu').remove();
contextmenuDir = document.createElement("div");
contextmenuDir.className = 'contextmenu';
contextmenuDir.innerHTML = '<a id="menu1"><div class="context">menu item 1<\/div><\/a>'
+ '<a id="menu2"><div class="context">menu item 2<\/div><\/a>';

$(map.getDiv()).append(contextmenuDir);

setMenuXY(caurrentLatLng);

contextmenuDir.style.visibility = "visible";
}


step 3:
When menu is created we must calculate where to display it, so LatLng is converted into appropriate X,Y.

      function getCanvasXY(caurrentLatLng){
var scale = Math.pow(2, map.getZoom());
var nw = new google.maps.LatLng(
map.getBounds().getNorthEast().lat(),
map.getBounds().getSouthWest().lng()
);
var worldCoordinateNW = map.getProjection().fromLatLngToPoint(nw);
var worldCoordinate = map.getProjection().fromLatLngToPoint(caurrentLatLng);
var caurrentLatLngOffset = new google.maps.Point(
Math.floor((worldCoordinate.x - worldCoordinateNW.x) * scale),
Math.floor((worldCoordinate.y - worldCoordinateNW.y) * scale)
);
return caurrentLatLngOffset;
}


step 4:
Just to avoid displaying menu outside the map, X and Y coordinates are redefined if nessesary

  function setMenuXY(caurrentLatLng){
var mapWidth = $('#map_canvas').width();
var mapHeight = $('#map_canvas').height();
var menuWidth = $('.contextmenu').width();
var menuHeight = $('.contextmenu').height();
var clickedPosition = getCanvasXY(caurrentLatLng);
var x = clickedPosition.x ;
var y = clickedPosition.y ;

if((mapWidth - x ) < menuWidth)//if to close to the map border, decrease x position
x = x - menuWidth;
if((mapHeight - y ) < menuHeight)//if to close to the map border, decrease y position
y = y - menuHeight;

$('.contextmenu').css('left',x );
$('.contextmenu').css('top',y );
};


step 5:
To display context menu in right way we must apply this style:


.contextmenu{
visibility:hidden;
background:#ffffff;
border:1px solid #8888FF;
z-index: 10;
position: relative;
width: 140px;
}
.contextmenu div{
padding-left: 5px
}


And now complete source:

  
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
<script type="text/javascript">
var map;
function initialize() {
var latlng = new google.maps.LatLng(49.814357,19.025956);
var myOptions = {
zoom: 12,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
google.maps.event.addListener(map, "rightclick",function(event){showContextMenu(event.latLng);});

}
function getCanvasXY(caurrentLatLng){
var scale = Math.pow(2, map.getZoom());
var nw = new google.maps.LatLng(
map.getBounds().getNorthEast().lat(),
map.getBounds().getSouthWest().lng()
);
var worldCoordinateNW = map.getProjection().fromLatLngToPoint(nw);
var worldCoordinate = map.getProjection().fromLatLngToPoint(caurrentLatLng);
var caurrentLatLngOffset = new google.maps.Point(
Math.floor((worldCoordinate.x - worldCoordinateNW.x) * scale),
Math.floor((worldCoordinate.y - worldCoordinateNW.y) * scale)
);
return caurrentLatLngOffset;
}
function setMenuXY(caurrentLatLng){
var mapWidth = $('#map_canvas').width();
var mapHeight = $('#map_canvas').height();
var menuWidth = $('.contextmenu').width();
var menuHeight = $('.contextmenu').height();
var clickedPosition = getCanvasXY(caurrentLatLng);
var x = clickedPosition.x ;
var y = clickedPosition.y ;

if((mapWidth - x ) < menuWidth)
x = x - menuWidth;
if((mapHeight - y ) < menuHeight)
y = y - menuHeight;

$('.contextmenu').css('left',x );
$('.contextmenu').css('top',y );
};
function showContextMenu(caurrentLatLng ) {
var projection;
var contextmenuDir;
projection = map.getProjection() ;
$('.contextmenu').remove();
contextmenuDir = document.createElement("div");
contextmenuDir.className = 'contextmenu';
contextmenuDir.innerHTML = "<a id='menu1'><div class=context>menu item 1<\/div><\/a><a id='menu2'><div class=context>menu item 2<\/div><\/a>";
$(map.getDiv()).append(contextmenuDir);

setMenuXY(caurrentLatLng);

contextmenuDir.style.visibility = "visible";
}
$(document).ready(function(){
initialize();

});
</script>

<style type="text/css">
#map_canvas{
width: 400px;
height: 300px;
}
.contextmenu{
visibility:hidden;
background:#ffffff;
border:1px solid #8888FF;
z-index: 10;
position: relative;
width: 140px;
}
.contextmenu div{
padding-left: 5px
}
</style>
<div class="formDiv" id="map_canvas"></div>