
function MarkerClusterer(map,opt_markers,opt_opts){var clusters_=[];var map_=map;var maxZoom_=null;var me_=this;var gridSize_=60;var sizes=[53,56,66,78,90];var styles_=[];var leftMarkers_=[];var mcfn_=null;var i=0;for(i=1;i<=5;++i){styles_.push({'url':"http://gmaps-utility-library.googlecode.com/svn/trunk/markerclusterer/images/m"+i+".png",'height':sizes[i-1],'width':sizes[i-1]});}
if(typeof opt_opts==="object"&&opt_opts!==null){if(typeof opt_opts.gridSize==="number"&&opt_opts.gridSize>0){gridSize_=opt_opts.gridSize;}
if(typeof opt_opts.maxZoom==="number"){maxZoom_=opt_opts.maxZoom;}
if(typeof opt_opts.styles==="object"&&opt_opts.styles!==null&&opt_opts.styles.length!==0){styles_=opt_opts.styles;}}
function addLeftMarkers_(){if(leftMarkers_.length===0){return;}
var leftMarkers=[];for(i=0;i<leftMarkers_.length;++i){me_.addMarker(leftMarkers_[i],true,null,null,true);}
leftMarkers_=leftMarkers;}
this.getStyles_=function(){return styles_;};this.clearMarkers=function(){for(var i=0;i<clusters_.length;++i){if(typeof clusters_[i]!=="undefined"&&clusters_[i]!==null){clusters_[i].clearMarkers();}}
clusters_=[];leftMarkers_=[];GEvent.removeListener(mcfn_);};function isMarkerInViewport_(marker){return map_.getBounds().containsLatLng(marker.getLatLng());}
function reAddMarkers_(markers){var len=markers.length;var clusters=[];for(var i=len-1;i>=0;--i){me_.addMarker(markers[i].marker,true,markers[i].isAdded,clusters,true);}
addLeftMarkers_();}
this.addMarker=function(marker,opt_isNodraw,opt_isAdded,opt_clusters,opt_isNoCheck){if(opt_isNoCheck!==true){if(!isMarkerInViewport_(marker)){leftMarkers_.push(marker);return;}}
var isAdded=opt_isAdded;var clusters=opt_clusters;var pos=map_.fromLatLngToDivPixel(marker.getLatLng());if(typeof isAdded!=="boolean"){isAdded=false;}
if(typeof clusters!=="object"||clusters===null){clusters=clusters_;}
var length=clusters.length;var cluster=null;for(var i=length-1;i>=0;i--){cluster=clusters[i];var center=cluster.getCenter();if(center===null){continue;}
center=map_.fromLatLngToDivPixel(center);if(pos.x>=center.x-gridSize_&&pos.x<=center.x+gridSize_&&pos.y>=center.y-gridSize_&&pos.y<=center.y+gridSize_){cluster.addMarker({'isAdded':isAdded,'marker':marker});if(!opt_isNodraw){cluster.redraw_();}
return;}}
cluster=new Cluster(this,map);cluster.addMarker({'isAdded':isAdded,'marker':marker});if(!opt_isNodraw){cluster.redraw_();}
clusters.push(cluster);if(clusters!==clusters_){clusters_.push(cluster);}};this.removeMarker=function(marker){for(var i=0;i<clusters_.length;++i){if(clusters_[i].remove(marker)){clusters_[i].redraw_();return;}}};this.redraw_=function(){var clusters=this.getClustersInViewport_();for(var i=0;i<clusters.length;++i){clusters[i].redraw_(true);}};this.getClustersInViewport_=function(){var clusters=[];var curBounds=map_.getBounds();for(var i=0;i<clusters_.length;i++){if(clusters_[i].isInBounds(curBounds)){clusters.push(clusters_[i]);}}
return clusters;};this.getMaxZoom_=function(){return maxZoom_;};this.getMap_=function(){return map_;};this.getGridSize_=function(){return gridSize_;};this.getTotalMarkers=function(){var result=0;for(var i=0;i<clusters_.length;++i){result+=clusters_[i].getTotalMarkers();}
return result;};this.getTotalClusters=function(){return clusters_.length;};this.resetViewport=function(){var clusters=this.getClustersInViewport_();var tmpMarkers=[];var removed=0;for(var i=0;i<clusters.length;++i){var cluster=clusters[i];var oldZoom=cluster.getCurrentZoom();if(oldZoom===null){continue;}
var curZoom=map_.getZoom();if(curZoom!==oldZoom){var mks=cluster.getMarkers();for(var j=0;j<mks.length;++j){var newMarker={'isAdded':false,'marker':mks[j].marker};tmpMarkers.push(newMarker);}
cluster.clearMarkers();removed++;for(j=0;j<clusters_.length;++j){if(cluster===clusters_[j]){clusters_.splice(j,1);}}}}
reAddMarkers_(tmpMarkers);this.redraw_();};this.addMarkers=function(markers){for(var i=0;i<markers.length;++i){this.addMarker(markers[i],true);}
this.redraw_();};if(typeof opt_markers==="object"&&opt_markers!==null){this.addMarkers(opt_markers);}
mcfn_=GEvent.addListener(map_,"moveend",function(){me_.resetViewport();});}
function Cluster(markerClusterer){var center_=null;var markers_=[];var markerClusterer_=markerClusterer;var map_=markerClusterer.getMap_();var clusterMarker_=null;var zoom_=map_.getZoom();this.getMarkers=function(){return markers_;};this.isInBounds=function(bounds){if(center_===null){return false;}
if(!bounds){bounds=map_.getBounds();}
var sw=map_.fromLatLngToDivPixel(bounds.getSouthWest());var ne=map_.fromLatLngToDivPixel(bounds.getNorthEast());var centerxy=map_.fromLatLngToDivPixel(center_);var inViewport=true;var gridSize=markerClusterer.getGridSize_();if(zoom_!==map_.getZoom()){var dl=map_.getZoom()-zoom_;gridSize=Math.pow(2,dl)*gridSize;}
if(ne.x!==sw.x&&(centerxy.x+gridSize<sw.x||centerxy.x-gridSize>ne.x)){inViewport=false;}
if(inViewport&&(centerxy.y+gridSize<ne.y||centerxy.y-gridSize>sw.y)){inViewport=false;}
return inViewport;};this.getCenter=function(){return center_;};this.addMarker=function(marker){if(center_===null){center_=marker.marker.getLatLng();}
markers_.push(marker);};this.removeMarker=function(marker){for(var i=0;i<markers_.length;++i){if(marker===markers_[i].marker){if(markers_[i].isAdded){map_.removeOverlay(markers_[i].marker);}
markers_.splice(i,1);return true;}}
return false;};this.getCurrentZoom=function(){return zoom_;};this.redraw_=function(isForce){if(!isForce&&!this.isInBounds()){return;}
zoom_=map_.getZoom();var i=0;var mz=markerClusterer.getMaxZoom_();if(mz===null){mz=map_.getCurrentMapType().getMaximumResolution();}
if(zoom_>=mz||this.getTotalMarkers()===1){for(i=0;i<markers_.length;++i){if(markers_[i].isAdded){if(markers_[i].marker.isHidden()){markers_[i].marker.show();}}else{map_.addOverlay(markers_[i].marker);markers_[i].isAdded=true;}}
if(clusterMarker_!==null){clusterMarker_.hide();}}else{for(i=0;i<markers_.length;++i){if(markers_[i].isAdded&&(!markers_[i].marker.isHidden())){markers_[i].marker.hide();}}
if(clusterMarker_===null){clusterMarker_=new ClusterMarker_(center_,this.getTotalMarkers(),markerClusterer_.getStyles_(),markerClusterer_.getGridSize_());map_.addOverlay(clusterMarker_);}else{if(clusterMarker_.isHidden()){clusterMarker_.show();}
clusterMarker_.redraw(true);}}};this.clearMarkers=function(){if(clusterMarker_!==null){map_.removeOverlay(clusterMarker_);}
for(var i=0;i<markers_.length;++i){if(markers_[i].isAdded){map_.removeOverlay(markers_[i].marker);}}
markers_=[];};this.getTotalMarkers=function(){return markers_.length;};}
function ClusterMarker_(latlng,count,styles,padding){var index=0;var dv=count;while(dv!==0){dv=parseInt(dv/10,10);index++;}
if(styles.length<index){index=styles.length;}
this.url_=styles[index-1].url;this.height_=styles[index-1].height;this.width_=styles[index-1].width;this.textColor_=styles[index-1].opt_textColor;this.anchor_=styles[index-1].opt_anchor;this.latlng_=latlng;this.index_=index;this.styles_=styles;this.text_=count;this.padding_=padding;}
ClusterMarker_.prototype=new GOverlay();ClusterMarker_.prototype.initialize=function(map){this.map_=map;var div=document.createElement("div");var latlng=this.latlng_;var pos=map.fromLatLngToDivPixel(latlng);pos.x-=parseInt(this.width_/2,10);pos.y-=parseInt(this.height_/2,10);var mstyle="";if(document.all){mstyle='filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale,src="'+this.url_+'");';}else{mstyle="background:url("+this.url_+");";}
if(typeof this.anchor_==="object"){if(typeof this.anchor_[0]==="number"&&this.anchor_[0]>0&&this.anchor_[0]<this.height_){mstyle+='height:'+(this.height_-this.anchor_[0])+'px;padding-top:'+this.anchor_[0]+'px;';}else{mstyle+='height:'+this.height_+'px;line-height:'+this.height_+'px;';}
if(typeof this.anchor_[1]==="number"&&this.anchor_[1]>0&&this.anchor_[1]<this.width_){mstyle+='width:'+(this.width_-this.anchor_[1])+'px;padding-left:'+this.anchor_[1]+'px;';}else{mstyle+='width:'+this.width_+'px;text-align:center;';}}else{mstyle+='height:'+this.height_+'px;line-height:'+this.height_+'px;';mstyle+='width:'+this.width_+'px;text-align:center;';}
var txtColor=this.textColor_?this.textColor_:'black';div.style.cssText=mstyle+'cursor:pointer;top:'+pos.y+"px;left:"+
pos.x+"px;color:"+txtColor+";position:absolute;font-size:11px;"+'font-family:Arial,sans-serif;font-weight:bold';div.innerHTML=this.text_;map.getPane(G_MAP_MAP_PANE).appendChild(div);var padding=this.padding_;GEvent.addDomListener(div,"click",function(){var pos=map.fromLatLngToDivPixel(latlng);var sw=new GPoint(pos.x-padding,pos.y+padding);sw=map.fromDivPixelToLatLng(sw);var ne=new GPoint(pos.x+padding,pos.y-padding);ne=map.fromDivPixelToLatLng(ne);var zoom=map.getBoundsZoomLevel(new GLatLngBounds(sw,ne),map.getSize());map.setCenter(latlng,zoom);});this.div_=div;};ClusterMarker_.prototype.remove=function(){this.div_.parentNode.removeChild(this.div_);};ClusterMarker_.prototype.copy=function(){return new ClusterMarker_(this.latlng_,this.index_,this.text_,this.styles_,this.padding_);};ClusterMarker_.prototype.redraw=function(force){if(!force){return;}
var pos=this.map_.fromLatLngToDivPixel(this.latlng_);pos.x-=parseInt(this.width_/2,10);pos.y-=parseInt(this.height_/2,10);this.div_.style.top=pos.y+"px";this.div_.style.left=pos.x+"px";};ClusterMarker_.prototype.hide=function(){this.div_.style.display="none";};ClusterMarker_.prototype.show=function(){this.div_.style.display="";};ClusterMarker_.prototype.isHidden=function(){return this.div_.style.display==="none";};