MarkerCluster library creates and manages per-zoom-level clusters for large amounts of markers (hundreds or thousands). And also I use infobox.js library to create custom InfoWindows.
<div class="row"> <div class="span3"> <ul class="nav nav-list" id="markerlist"> </ul> </div> <div class="span9" id="map_canvas"> </div> </div>
Note: You can put it into external file
.info-windows{
background: transparent url(/assets/images/pin_tooltip.png) left bottom no-repeat;
width: 450px;
height:239px;
opacity: 0.9;
color: #ffedc8;
font: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
max-width: none;
}
.m-rate {
background: transparent url(/assets/images/rating-lines.png) left 6px no-repeat;
width: 65px;
height:20px;
color:#fdb748;
padding-left:42px;
margin-left:13px;
}
.star-rating{
list-style:none;
margin: 0px;
padding:0px;
height: 16px;
position: relative;
background: url(/assets/images/stars.png) left bottom repeat-x;
}
.star-rating li{
padding:0px;
margin:0px;
height:16px;
width: 16px;
float: left;
}
.star-rating li.current-rating{
background: url(/assets/images/stars.png) left top;
position: absolute;
height: 16px;
display: block;
text-indent: -9000px;
z-index: 1;
}
.a-list {
float:left;padding-left:10px;font-size:13px;width:290px;
}
.r-2 div {
float:left;
padding:5px 0 0 35px;
font-size:12px;
}
.i-box-1 {
width: 450px;
height:239px;
padding:15px 0 0 25px;
}
.i-box-1 img {max-width: none;}
.i-title {
font-size:16px;font-weight:bold;height:20px;display: block;
}
.a-list .address {display: block;font-size:10px;}
.r-2 {}
#map_canvas {height:500px}
#map_canvas img {max-width: none;} /* Google Map fix for Twitter bootstrap */
Note: You can put it into external file
(function($) {
jQuery.fn.gogMap = function(markers_raw) {
var marker_icons_path = "/themes/third_party/mx_google_map/maps-icons/";
var markers = [];
var infowindows = [];
var active_info = null;
var panel = $('#markerlist');
panel.innerHTML = '';
var options = {
'zoom': 10,
'center': new google.maps.LatLng(40.7563551136864, -73.98548310000001),
'mapTypeId': google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), options);
for (var m_id in markers_raw) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(markers_raw[m_id].latitude, markers_raw[m_id].longitude),
id: (markers_raw[m_id].marker_id),
title: markers_raw[m_id].title,
icon: marker_icons_path + ((markers_raw[m_id].icon == "") ? "home.png" : markers_raw[m_id].icon)
});
markers.push(marker);
var myOptions = {
content: "<div>" + markers_raw[m_id].infow + "</div>",
disableAutoPan: false,
maxWidth: 0,
alignBottom: true,
pixelOffset: new google.maps.Size(-66, -42),
zIndex: null,
boxClass: "info-windows",
closeBoxURL: "",
infoBoxClearance: new google.maps.Size(1, 1),
pane: "floatPane",
enableEventPropagation: false,
infoBoxClearance: "10px",
position: marker.position
};
var infowindow = new InfoBox(myOptions); // infoWindow w/ infobox.js
infowindows[marker.id] = infowindow;
var titleText = marker.title;
if (titleText == '') {
titleText = 'No title';
}
var item = document.createElement('li');
var title = document.createElement('A');
item.rel = markers_raw[m_id].marker_id;
//item.id = "marker" + marker.id;
title.href = '#';
title.className = 'title';
title.innerHTML = titleText;
item.appendChild(title);
panel.append(item);
google.maps.event.addDomListener(item, 'click', function() {
if (active_info) {
active_info.className = '';
infowindows[active_info.rel].close();
}
infowindows[this.rel].open(map);
this.className = 'active';
active_info = this;
return false;
});
google.maps.event.addListener(markers[markers.length - 1], 'click', function() {
if (active_info) {
infowindows[active_info].close();
}
infowindows[this.id].open(this.map);
active_info = this.id;
this.map.setCenter(this.position);
return false;
}); // add to list
}
// optional - Custom Cluster icon
mcOptions = {
styles: [{
height: 53,
url: "http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/m1.png",
width: 53
},
{
height: 56,
url: "http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/m2.png",
width: 56
},
{
height: 66,
url: "http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/m3.png",
width: 66
},
{
height: 78,
url: "http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/m4.png",
width: 78
},
{
height: 90,
url: "http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/m5.png",
width: 90
}]
};
var markerCluster = new MarkerClusterer(map, markers, mcOptions);
}
})(jQuery);
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="/assets/js/google_maps/infobox.js"></script>
<script type="text/javascript" src="/assets/js/google_maps/markerclusterer.js"></script>
<script type="text/javascript">
//<![CDATA[
$(document).ready(function() {
var markers_raw = [{exp:channel:entries channel="hotel" dynamic="off" backspace="1" parse="inward"}{hl_map backspace="1"}{marker_id : {point_id},
latitude: {latitude},
longitude: {longitude},
draggable: false,
title: "{title}",
icon: "hotel-pin.png",
infow:"<div class='i-box-1'>\
<div style='float:left;height:175px;display:block;'><img src='http://media-cdn.tripadvisor.com/media/photo-s/01/7a/ea/49/mini-suite-with-2-double.jpg' width='120px' height='110px' style='border:1px solid #333;padding:3px;'>\
<div style='margin:10px 0 0 25px'><ul class='star-rating' style='width: 80px;'><li class='current-rating' style='width: \
{exp:mx_calc expression="round(16*({hl_value}+{hl_rooms}+{hl_cleanliness}+{hl_service}+{hl_sleep_quality}+{hl_location})/6,0)"}px;'>\
{exp:mx_calc expression="round(({hl_value}+{hl_rooms}+{hl_cleanliness}+{hl_service}+{hl_sleep_quality}+{hl_location})/6,0)"}/5</li></ul></div>\
<div class='m-rate'>{exp:mx_calc expression="round(({hl_value}+{hl_rooms}+{hl_cleanliness}+{hl_service}+{hl_sleep_quality}+{hl_location})/6,0)"}/5</div>\
</div>\
<div class='a-list'>\
<span class='i-title'>{title}</span>\
<span class='address'>147 West 43rd Street New York, NY. 10036</span>\
<div class='r-2'><div>Value<ul class='star-rating' style='width: 80px;'><li class='current-rating' style='width: {hl_value}16{/hl_value}px;'>{hl_value}/{hl_value:scale}</li></ul></div>\
<div>Rooms <ul class='star-rating' style='width: 80px;'><li class='current-rating' style='width: {hl_rooms}16{/hl_rooms}px;'>{hl_rooms}/{hl_rooms:scale}</li></ul></div><br/>\
<div>Location <ul class='star-rating' style='width: 80px;'><li class='current-rating' style='width: {hl_location}16{/hl_location}px;'>{hl_location}/{hl_location:scale}</li></ul></div>\
<div>Sleep Quality <ul class='star-rating' style='width: 80px;'><li class='current-rating' style='width: {hl_sleep_quality}16{/hl_sleep_quality}px;'>{hl_sleep_quality}/{hl_sleep_quality:scale}</li></ul></div><br/>\
<div>Cleanliness <ul class='star-rating' style='width: 80px;'><li class='current-rating' style='width: {hl_cleanliness}16{/hl_cleanliness}px;'>{hl_cleanliness}/{hl_cleanliness:scale}</li></ul></div>\
<div>Service <ul class='star-rating' style='width: 80px;'><li class='current-rating' style='width: {hl_service}16{/hl_service}px;'>{hl_service}/{hl_service:scale}</li></ul></div>\
<div style='padding:10px 0 0 80px;'><a class='btn btn-warning' href='#ee_template'>Book It</a></div>\
</div></div></div>" },{/hl_map},{/exp:channel:entries}];
$().gogMap(markers_raw);
});
//]]>
</script>