/** * @name MarkerClustererPlus for Google Maps V3 * @version 2.1.1 [November 4, 2013] * @author Gary Little * @fileoverview * The library creates and manages per-zoom-level clusters for large amounts of markers. *
* This is an enhanced V3 implementation of the * V2 MarkerClusterer by Xiaoxi Wu. It is based on the * V3 MarkerClusterer port by Luke Mahe. MarkerClustererPlus was created by Gary Little. *
* v2.0 release: MarkerClustererPlus v2.0 is backward compatible with MarkerClusterer v1.0. It
* adds support for the ignoreHidden
, title
, batchSizeIE
,
* and calculator
properties as well as support for four more events. It also allows
* greater control over the styling of the text that appears on the cluster marker. The
* documentation has been significantly improved and the overall code has been simplified and
* polished. Very large numbers of markers can now be managed without causing Javascript timeout
* errors on Internet Explorer. Note that the name of the clusterclick
event has been
* deprecated. The new name is click
, so please change your application code now.
*/
/**
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @name ClusterIconStyle
* @class This class represents the object for values in the styles
array passed
* to the {@link MarkerClusterer} constructor. The element in this array that is used to
* style the cluster icon is determined by calling the calculator
function.
*
* @property {string} url The URL of the cluster icon image file. Required.
* @property {number} height The display height (in pixels) of the cluster icon. Required.
* @property {number} width The display width (in pixels) of the cluster icon. Required.
* @property {Array} [anchorText] The position (in pixels) from the center of the cluster icon to
* where the text label is to be centered and drawn. The format is [yoffset, xoffset]
* where yoffset
increases as you go down from center and xoffset
* increases to the right of center. The default is [0, 0]
.
* @property {Array} [anchorIcon] The anchor position (in pixels) of the cluster icon. This is the
* spot on the cluster icon that is to be aligned with the cluster position. The format is
* [yoffset, xoffset]
where yoffset
increases as you go down and
* xoffset
increases to the right of the top-left corner of the icon. The default
* anchor position is the center of the cluster icon.
* @property {string} [textColor="black"] The color of the label text shown on the
* cluster icon.
* @property {number} [textSize=11] The size (in pixels) of the label text shown on the
* cluster icon.
* @property {string} [textDecoration="none"] The value of the CSS text-decoration
* property for the label text shown on the cluster icon.
* @property {string} [fontWeight="bold"] The value of the CSS font-weight
* property for the label text shown on the cluster icon.
* @property {string} [fontStyle="normal"] The value of the CSS font-style
* property for the label text shown on the cluster icon.
* @property {string} [fontFamily="Arial,sans-serif"] The value of the CSS font-family
* property for the label text shown on the cluster icon.
* @property {string} [backgroundPosition="0 0"] The position of the cluster icon image
* within the image defined by url
. The format is "xpos ypos"
* (the same format as for the CSS background-position
property). You must set
* this property appropriately when the image defined by url
represents a sprite
* containing multiple images. Note that the position must be specified in px units.
*/
/**
* @name ClusterIconInfo
* @class This class is an object containing general information about a cluster icon. This is
* the object that a calculator
function returns.
*
* @property {string} text The text of the label to be shown on the cluster icon.
* @property {number} index The index plus 1 of the element in the styles
* array to be used to style the cluster icon.
* @property {string} title The tooltip to display when the mouse moves over the cluster icon.
* If this value is undefined
or ""
, title
is set to the
* value of the title
property passed to the MarkerClusterer.
*/
/**
* A cluster icon.
*
* @constructor
* @extends google.maps.OverlayView
* @param {Cluster} cluster The cluster with which the icon is to be associated.
* @param {Array} [styles] An array of {@link ClusterIconStyle} defining the cluster icons
* to use for various cluster sizes.
* @private
*/
function ClusterIcon(a,b){a.getMarkerClusterer().extend(ClusterIcon,google.maps.OverlayView),this.cluster_=a,this.className_=a.getMarkerClusterer().getClusterClass(),this.styles_=b,this.center_=null,this.div_=null,this.sums_=null,this.visible_=!1,this.setMap(a.getMap())}function Cluster(a){this.markerClusterer_=a,this.map_=a.getMap(),this.gridSize_=a.getGridSize(),this.minClusterSize_=a.getMinimumClusterSize(),this.averageCenter_=a.getAverageCenter(),this.markers_=[],this.center_=null,this.bounds_=null,this.clusterIcon_=new ClusterIcon(this,a.getStyles())}function MarkerClusterer(a,b,c){this.extend(MarkerClusterer,google.maps.OverlayView),b=b||[],c=c||{},this.markers_=[],this.clusters_=[],this.listeners_=[],this.activeMap_=null,this.ready_=!1,this.gridSize_=c.gridSize||60,this.minClusterSize_=c.minimumClusterSize||2,this.maxZoom_=c.maxZoom||null,this.styles_=c.styles||[],this.title_=c.title||"",this.zoomOnClick_=!0,void 0!==c.zoomOnClick&&(this.zoomOnClick_=c.zoomOnClick),this.averageCenter_=!1,void 0!==c.averageCenter&&(this.averageCenter_=c.averageCenter),this.ignoreHidden_=!1,void 0!==c.ignoreHidden&&(this.ignoreHidden_=c.ignoreHidden),this.enableRetinaIcons_=!1,void 0!==c.enableRetinaIcons&&(this.enableRetinaIcons_=c.enableRetinaIcons),this.imagePath_=c.imagePath||MarkerClusterer.IMAGE_PATH,this.imageExtension_=c.imageExtension||MarkerClusterer.IMAGE_EXTENSION,this.imageSizes_=c.imageSizes||MarkerClusterer.IMAGE_SIZES,this.calculator_=c.calculator||MarkerClusterer.CALCULATOR,this.batchSize_=c.batchSize||MarkerClusterer.BATCH_SIZE,this.batchSizeIE_=c.batchSizeIE||MarkerClusterer.BATCH_SIZE_IE,this.clusterClass_=c.clusterClass||"cluster",navigator.userAgent.toLowerCase().indexOf("msie")!==-1&&(this.batchSize_=this.batchSizeIE_),this.setupStyles_(),this.addMarkers(b,!0),this.setMap(a)}ClusterIcon.prototype.onAdd=function(){var b,c,a=this;this.div_=document.createElement("div"),this.div_.className=this.className_,this.visible_&&this.show(),this.getPanes().overlayMouseTarget.appendChild(this.div_),this.boundsChangedListener_=google.maps.event.addListener(this.getMap(),"bounds_changed",function(){c=b}),google.maps.event.addDomListener(this.div_,"mousedown",function(){b=!0,c=!1}),google.maps.event.addDomListener(this.div_,"click",function(d){if(b=!1,!c){var e,f,g=a.cluster_.getMarkerClusterer();google.maps.event.trigger(g,"click",a.cluster_),google.maps.event.trigger(g,"clusterclick",a.cluster_),g.getZoomOnClick()&&(f=g.getMaxZoom(),e=a.cluster_.getBounds(),g.getMap().fitBounds(e),setTimeout(function(){g.getMap().fitBounds(e),null!==f&&g.getMap().getZoom()>f&&g.getMap().setZoom(f+1)},100)),d.cancelBubble=!0,d.stopPropagation&&d.stopPropagation()}}),google.maps.event.addDomListener(this.div_,"mouseover",function(){var b=a.cluster_.getMarkerClusterer();google.maps.event.trigger(b,"mouseover",a.cluster_)}),google.maps.event.addDomListener(this.div_,"mouseout",function(){var b=a.cluster_.getMarkerClusterer();google.maps.event.trigger(b,"mouseout",a.cluster_)})},ClusterIcon.prototype.onRemove=function(){this.div_&&this.div_.parentNode&&(this.hide(),google.maps.event.removeListener(this.boundsChangedListener_),google.maps.event.clearInstanceListeners(this.div_),this.div_.parentNode.removeChild(this.div_),this.div_=null)},ClusterIcon.prototype.draw=function(){if(this.visible_){var a=this.getPosFromLatLng_(this.center_);this.div_.style.top=a.y+"px",this.div_.style.left=a.x+"px"}},ClusterIcon.prototype.hide=function(){this.div_&&(this.div_.style.display="none"),this.visible_=!1},ClusterIcon.prototype.show=function(){if(this.div_){var a="",b=this.backgroundPosition_.split(" "),c=parseInt(b[0].trim(),10),d=parseInt(b[1].trim(),10),e=this.getPosFromLatLng_(this.center_);this.div_.style.cssText=this.createCss(e),a="",this.div_.innerHTML=a+"