@react-google-maps/marker-clusterer 2.10.0 → 2.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"umd.min.js","sources":["../src/ClusterIcon.tsx","../src/Cluster.tsx","../src/Clusterer.tsx"],"sourcesContent":["/* global google */\n/* eslint-disable filenames/match-regex */\nimport { Cluster } from './Cluster'\n\nimport { ClusterIconStyle, ClusterIconInfo } from './types'\n\nexport class ClusterIcon {\n cluster: Cluster\n className: string\n clusterClassName: string\n styles: ClusterIconStyle[]\n center: google.maps.LatLng | undefined\n div: HTMLDivElement | null\n sums: ClusterIconInfo | null\n visible: boolean\n url: string\n height: number\n width: number\n anchorText: number[]\n anchorIcon: number[]\n textColor: string\n textSize: number\n textDecoration: string\n fontWeight: string\n fontStyle: string\n fontFamily: string\n backgroundPosition: string\n\n boundsChangedListener: google.maps.MapsEventListener | null\n\n constructor(cluster: Cluster, styles: ClusterIconStyle[]) {\n cluster.getClusterer().extend(ClusterIcon, google.maps.OverlayView)\n this.cluster = cluster\n this.clusterClassName = this.cluster.getClusterer().getClusterClass()\n this.className = this.clusterClassName\n this.styles = styles\n this.center = undefined\n this.div = null\n this.sums = null\n this.visible = false\n this.boundsChangedListener = null\n this.url = ''\n this.height = 0\n this.width = 0\n this.anchorText = [0, 0]\n this.anchorIcon = [0, 0]\n this.textColor = 'black'\n this.textSize = 11\n this.textDecoration = 'none'\n this.fontWeight = 'bold'\n this.fontStyle = 'normal'\n this.fontFamily = 'Arial,sans-serif'\n this.backgroundPosition = '0 0'\n // @ts-ignore\n this.setMap(cluster.getMap()) // Note: this causes onAdd to be called\n }\n\n onAdd() {\n let cMouseDownInCluster: boolean\n let cDraggingMapByCluster: boolean\n\n this.div = document.createElement('div')\n this.div.className = this.className\n if (this.visible) {\n this.show()\n }\n\n // @ts-ignore\n this.getPanes().overlayMouseTarget.appendChild(this.div)\n\n // Fix for Issue 157\n this.boundsChangedListener = google.maps.event.addListener(\n // @ts-ignore\n this.getMap(),\n 'boundschanged',\n function boundsChanged() {\n cDraggingMapByCluster = cMouseDownInCluster\n }\n )\n\n google.maps.event.addListener(this.div, 'mousedown', function onMouseDown() {\n cMouseDownInCluster = true\n cDraggingMapByCluster = false\n })\n\n google.maps.event.addListener(\n this.div,\n 'click',\n (event: Event) => {\n cMouseDownInCluster = false\n\n if (!cDraggingMapByCluster) {\n const markerClusterer = this.cluster.getClusterer()\n\n /**\n * This event is fired when a cluster marker is clicked.\n * @name MarkerClusterer#click\n * @param {Cluster} c The cluster that was clicked.\n * @event\n */\n google.maps.event.trigger(markerClusterer, 'click', this.cluster)\n google.maps.event.trigger(markerClusterer, 'clusterclick', this.cluster) // deprecated name\n\n // The default click handler follows. Disable it by setting\n // the zoomOnClick property to false.\n if (markerClusterer.getZoomOnClick()) {\n // Zoom into the cluster.\n const maxZoom = markerClusterer.getMaxZoom()\n\n const bounds = this.cluster.getBounds()\n\n // @ts-ignore\n markerClusterer.getMap().fitBounds(bounds)\n\n // There is a fix for Issue 170 here:\n setTimeout(function timeout() {\n // @ts-ignore\n markerClusterer.getMap().fitBounds(bounds)\n\n // Don't zoom beyond the max zoom level\n // @ts-ignore\n if (maxZoom !== null && markerClusterer.getMap().getZoom() > maxZoom) {\n // @ts-ignore\n markerClusterer.getMap().setZoom(maxZoom + 1)\n }\n }, 100)\n }\n\n // Prevent event propagation to the map:\n event.cancelBubble = true\n\n if (event.stopPropagation) {\n event.stopPropagation()\n }\n }\n }\n )\n\n google.maps.event.addListener(\n this.div,\n 'mouseover',\n () => {\n /**\n * This event is fired when the mouse moves over a cluster marker.\n * @name MarkerClusterer#mouseover\n * @param {Cluster} c The cluster that the mouse moved over.\n * @event\n */\n google.maps.event.trigger(this.cluster.getClusterer(), 'mouseover', this.cluster)\n }\n )\n\n google.maps.event.addListener(\n this.div,\n 'mouseout',\n () => {\n /**\n * This event is fired when the mouse moves out of a cluster marker.\n * @name MarkerClusterer#mouseout\n * @param {Cluster} c The cluster that the mouse moved out of.\n * @event\n */\n google.maps.event.trigger(this.cluster.getClusterer(), 'mouseout', this.cluster)\n }\n )\n }\n\n onRemove() {\n if (this.div && this.div.parentNode) {\n this.hide()\n\n if (this.boundsChangedListener !== null) {\n google.maps.event.removeListener(this.boundsChangedListener)\n }\n\n google.maps.event.clearInstanceListeners(this.div)\n\n this.div.parentNode.removeChild(this.div)\n\n this.div = null\n }\n }\n\n draw() {\n if (this.visible && this.div !== null && this.center) {\n const { x, y } = this.getPosFromLatLng(this.center)\n\n this.div.style.top = y + 'px'\n this.div.style.left = x + 'px'\n }\n }\n\n hide() {\n if (this.div) {\n this.div.style.display = 'none'\n }\n\n this.visible = false\n }\n\n show() {\n if (this.div && this.center) {\n let divTitle = ''\n\n // NOTE: values must be specified in px units\n const bp = this.backgroundPosition.split(' ')\n\n const spriteH = parseInt(bp[0].replace(/^\\s+|\\s+$/g, ''), 10)\n const spriteV = parseInt(bp[1].replace(/^\\s+|\\s+$/g, ''), 10)\n\n const pos = this.getPosFromLatLng(this.center)\n\n if (this.sums === null || typeof this.sums.title === 'undefined' || this.sums.title === '') {\n divTitle = this.cluster.getClusterer().getTitle()\n } else {\n divTitle = this.sums.title\n }\n\n this.div.style.cursor = 'pointer'\n this.div.style.position = 'absolute'\n this.div.style.top = `${pos.y}px`\n this.div.style.left = `${pos.x}px`\n this.div.style.width = `${this.width}px`\n this.div.style.height = `${this.height}px`\n\n const img = document.createElement('img')\n img.alt = divTitle\n img.src = this.url\n img.style.position = 'absolute'\n img.style.top = `${spriteV}px`\n img.style.left = `${spriteH}px`\n\n if (!this.cluster.getClusterer().enableRetinaIcons) {\n img.style.clip = `rect(-${spriteV}px, -${spriteH + this.width}px, -${spriteV + this.height}, -${spriteH})`\n }\n\n const textElm = document.createElement('div')\n textElm.style.position = 'absolute'\n textElm.style.top = `${this.anchorText[0]}px`\n textElm.style.left = `${this.anchorText[1]}px`\n textElm.style.color = this.textColor\n textElm.style.fontSize = `${this.textSize}px`\n textElm.style.fontFamily = this.fontFamily\n textElm.style.fontWeight = this.fontWeight\n textElm.style.fontStyle = this.fontStyle\n textElm.style.textDecoration = this.textDecoration\n textElm.style.textAlign = 'center'\n textElm.style.width = `${this.width}px`\n textElm.style.lineHeight = `${this.height}px`\n textElm.innerText = `${this.sums?.text}`\n\n this.div.innerHTML = ''\n this.div.appendChild(img)\n this.div.appendChild(textElm)\n this.div.title = divTitle\n this.div.style.display = ''\n }\n\n this.visible = true\n }\n\n useStyle(sums: ClusterIconInfo) {\n this.sums = sums\n const styles = this.cluster.getClusterer().getStyles()\n const style = styles[Math.min(styles.length - 1, Math.max(0, sums.index - 1))]\n\n this.url = style.url\n this.height = style.height\n this.width = style.width\n\n if (style.className) this.className = `${this.clusterClassName} ${style.className}`\n\n this.anchorText = style.anchorText || [0, 0]\n this.anchorIcon = style.anchorIcon || [this.height / 2, this.width / 2]\n\n this.textColor = style.textColor || 'black'\n\n this.textSize = style.textSize || 11\n\n this.textDecoration = style.textDecoration || 'none'\n\n this.fontWeight = style.fontWeight || 'bold'\n\n this.fontStyle = style.fontStyle || 'normal'\n\n this.fontFamily = style.fontFamily || 'Arial,sans-serif'\n\n this.backgroundPosition = style.backgroundPosition || '0 0'\n }\n\n setCenter(center: google.maps.LatLng) {\n this.center = center\n }\n\n getPosFromLatLng(latlng: google.maps.LatLng): google.maps.Point {\n // @ts-ignore\n const pos = this.getProjection().fromLatLngToDivPixel(latlng)\n\n pos.x -= this.anchorIcon[1]\n\n pos.y -= this.anchorIcon[0]\n\n // pos.x = pos.x\n\n // pos.y = pos.y\n\n return pos\n }\n}\n","/* global google */\n/* eslint-disable filenames/match-regex */\nimport { Clusterer } from './Clusterer'\n\nimport { ClusterIcon } from './ClusterIcon'\n\nimport { MarkerExtended } from './types'\n\nexport class Cluster {\n markerClusterer: Clusterer\n map: google.maps.Map | google.maps.StreetViewPanorama\n gridSize: number\n minClusterSize: number\n averageCenter: boolean\n markers: MarkerExtended[]\n center: google.maps.LatLng | undefined\n bounds: google.maps.LatLngBounds | null\n clusterIcon: ClusterIcon\n\n constructor(markerClusterer: Clusterer) {\n this.markerClusterer = markerClusterer\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.map = this.markerClusterer.getMap()\n\n this.gridSize = this.markerClusterer.getGridSize()\n\n this.minClusterSize = this.markerClusterer.getMinimumClusterSize()\n\n this.averageCenter = this.markerClusterer.getAverageCenter()\n\n this.markers = []\n\n this.center = undefined\n\n this.bounds = null\n\n this.clusterIcon = new ClusterIcon(this, this.markerClusterer.getStyles())\n }\n\n getSize(): number {\n return this.markers.length\n }\n\n getMarkers(): MarkerExtended[] {\n return this.markers\n }\n\n getCenter(): google.maps.LatLng | undefined {\n return this.center\n }\n\n getMap(): google.maps.Map | google.maps.StreetViewPanorama {\n return this.map\n }\n\n getClusterer(): Clusterer {\n return this.markerClusterer\n }\n\n getBounds(): google.maps.LatLngBounds {\n const bounds = new google.maps.LatLngBounds(this.center, this.center)\n\n const markers = this.getMarkers()\n\n for (let i = 0; i < markers.length; i++) {\n const position = markers[i].getPosition()\n\n if (position) {\n bounds.extend(position)\n }\n }\n\n return bounds\n }\n\n remove() {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.clusterIcon.setMap(null)\n\n this.markers = []\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n delete this.markers\n }\n\n addMarker(marker: MarkerExtended): boolean {\n if (this.isMarkerAlreadyAdded(marker)) {\n return false\n }\n\n if (!this.center) {\n const position = marker.getPosition()\n\n if (position) {\n this.center = position\n\n this.calculateBounds()\n }\n } else {\n if (this.averageCenter) {\n const position = marker.getPosition()\n\n if (position) {\n const length = this.markers.length + 1\n\n this.center = new google.maps.LatLng(\n (this.center.lat() * (length - 1) + position.lat()) / length,\n (this.center.lng() * (length - 1) + position.lng()) / length\n )\n\n this.calculateBounds()\n }\n }\n }\n\n marker.isAdded = true\n\n this.markers.push(marker)\n\n const mCount = this.markers.length\n\n const maxZoom = this.markerClusterer.getMaxZoom()\n\n const zoom = this.map.getZoom()\n\n if (maxZoom !== null && typeof zoom !== 'undefined' && zoom > maxZoom) {\n // Zoomed in past max zoom, so show the marker.\n if (marker.getMap() !== this.map) {\n marker.setMap(this.map)\n }\n } else if (mCount < this.minClusterSize) {\n // Min cluster size not reached so show the marker.\n if (marker.getMap() !== this.map) {\n marker.setMap(this.map)\n }\n } else if (mCount === this.minClusterSize) {\n // Hide the markers that were showing.\n for (let i = 0; i < mCount; i++) {\n this.markers[i].setMap(null)\n }\n } else {\n marker.setMap(null)\n }\n\n return true\n }\n\n isMarkerInClusterBounds(marker: MarkerExtended): boolean {\n if (this.bounds !== null) {\n const position = marker.getPosition()\n\n if (position) {\n return this.bounds.contains(position)\n }\n }\n\n return false\n }\n\n calculateBounds() {\n this.bounds = this.markerClusterer.getExtendedBounds(\n new google.maps.LatLngBounds(this.center, this.center)\n )\n }\n\n updateIcon() {\n const mCount = this.markers.length\n\n const maxZoom = this.markerClusterer.getMaxZoom()\n\n const zoom = this.map.getZoom()\n\n if (maxZoom !== null && typeof zoom !== 'undefined' && zoom > maxZoom) {\n this.clusterIcon.hide()\n\n return\n }\n\n if (mCount < this.minClusterSize) {\n // Min cluster size not yet reached.\n this.clusterIcon.hide()\n\n return\n }\n\n if (this.center) {\n this.clusterIcon.setCenter(this.center)\n }\n\n this.clusterIcon.useStyle(\n this.markerClusterer.getCalculator()(this.markers, this.markerClusterer.getStyles().length)\n )\n\n this.clusterIcon.show()\n }\n\n isMarkerAlreadyAdded(marker: MarkerExtended): boolean {\n if (this.markers.includes) {\n return this.markers.includes(marker)\n }\n\n for (let i = 0; i < this.markers.length; i++) {\n if (marker === this.markers[i]) {\n return true\n }\n }\n\n return false\n }\n}\n","/* global google */\n/* eslint-disable filenames/match-regex */\nimport { Cluster } from './Cluster'\n\nimport {\n MarkerExtended,\n ClustererOptions,\n ClusterIconStyle,\n TCalculator,\n ClusterIconInfo,\n} from './types'\n\n/**\n * Supports up to 9007199254740991 (Number.MAX_SAFE_INTEGER) markers\n * which is not a problem as max array length is 4294967296 (2**32)\n */\nconst CALCULATOR = function CALCULATOR(\n markers: MarkerExtended[],\n numStyles: number\n): ClusterIconInfo {\n const count = markers.length\n\n const numberOfDigits = count.toString().length\n\n const index = Math.min(numberOfDigits, numStyles)\n\n return {\n text: count.toString(),\n index,\n title: '',\n }\n}\n\nconst BATCH_SIZE = 2000\n\nconst BATCH_SIZE_IE = 500\n\nconst IMAGE_PATH =\n 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'\n\nconst IMAGE_EXTENSION = 'png'\n\nconst IMAGE_SIZES = [53, 56, 66, 78, 90]\n\nconst CLUSTERER_CLASS = 'cluster'\n\nexport class Clusterer {\n markers: MarkerExtended[]\n clusters: Cluster[]\n listeners: google.maps.MapsEventListener[]\n activeMap: google.maps.Map | google.maps.StreetViewPanorama | null\n ready: boolean\n gridSize: number\n minClusterSize: number\n maxZoom: number | null\n styles: ClusterIconStyle[]\n title: string\n zoomOnClick: boolean\n averageCenter: boolean\n ignoreHidden: boolean\n enableRetinaIcons: boolean\n imagePath: string\n imageExtension: string\n imageSizes: number[]\n calculator: TCalculator\n batchSize: number\n batchSizeIE: number\n clusterClass: string\n timerRefStatic: number | null\n\n constructor(\n map: google.maps.Map,\n optMarkers: MarkerExtended[] = [],\n optOptions: ClustererOptions = {}\n ) {\n this.extend(Clusterer, google.maps.OverlayView)\n\n this.markers = []\n this.clusters = []\n this.listeners = []\n this.activeMap = null\n this.ready = false\n this.gridSize = optOptions.gridSize || 60\n this.minClusterSize = optOptions.minimumClusterSize || 2\n this.maxZoom = optOptions.maxZoom || null\n this.styles = optOptions.styles || []\n\n this.title = optOptions.title || ''\n\n this.zoomOnClick = true\n\n if (optOptions.zoomOnClick !== undefined) {\n this.zoomOnClick = optOptions.zoomOnClick\n }\n\n this.averageCenter = false\n\n if (optOptions.averageCenter !== undefined) {\n this.averageCenter = optOptions.averageCenter\n }\n\n this.ignoreHidden = false\n\n if (optOptions.ignoreHidden !== undefined) {\n this.ignoreHidden = optOptions.ignoreHidden\n }\n\n this.enableRetinaIcons = false\n\n if (optOptions.enableRetinaIcons !== undefined) {\n this.enableRetinaIcons = optOptions.enableRetinaIcons\n }\n this.imagePath = optOptions.imagePath || IMAGE_PATH\n\n this.imageExtension = optOptions.imageExtension || IMAGE_EXTENSION\n\n this.imageSizes = optOptions.imageSizes || IMAGE_SIZES\n\n this.calculator = optOptions.calculator || CALCULATOR\n\n this.batchSize = optOptions.batchSize || BATCH_SIZE\n\n this.batchSizeIE = optOptions.batchSizeIE || BATCH_SIZE_IE\n\n this.clusterClass = optOptions.clusterClass || CLUSTERER_CLASS\n\n if (navigator.userAgent.toLowerCase().indexOf('msie') !== -1) {\n // Try to avoid IE timeout when processing a huge number of markers:\n this.batchSize = this.batchSizeIE\n }\n\n this.timerRefStatic = null\n\n this.setupStyles()\n\n this.addMarkers(optMarkers, true)\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.setMap(map) // Note: this causes onAdd to be called\n }\n\n onAdd() {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.activeMap = this.getMap()\n\n this.ready = true\n\n this.repaint()\n\n // Add the map event listeners\n this.listeners = [\n google.maps.event.addListener(\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.getMap(),\n 'zoom_changed',\n () => {\n this.resetViewport(false)\n // Workaround for this Google bug: when map is at level 0 and \"-\" of\n // zoom slider is clicked, a \"zoom_changed\" event is fired even though\n // the map doesn't zoom out any further. In this situation, no \"idle\"\n // event is triggered so the cluster markers that have been removed\n // do not get redrawn. Same goes for a zoom in at maxZoom.\n if (\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.getMap().getZoom() === (this.get('minZoom') || 0) ||\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.getMap().getZoom() === this.get('maxZoom')\n ) {\n google.maps.event.trigger(this, 'idle')\n }\n }\n ),\n google.maps.event.addListener(\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.getMap(),\n 'idle',\n () => {\n this.redraw()\n }\n ),\n ]\n }\n\n onRemove() {\n // Put all the managed markers back on the map:\n for (let i = 0; i < this.markers.length; i++) {\n if (this.markers[i].getMap() !== this.activeMap) {\n this.markers[i].setMap(this.activeMap)\n }\n }\n\n // Remove all clusters:\n for (let i = 0; i < this.clusters.length; i++) {\n this.clusters[i].remove()\n }\n\n this.clusters = []\n\n // Remove map event listeners:\n for (let i = 0; i < this.listeners.length; i++) {\n google.maps.event.removeListener(this.listeners[i])\n }\n\n this.listeners = []\n\n this.activeMap = null\n\n this.ready = false\n }\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n draw() {}\n\n setupStyles() {\n if (this.styles.length > 0) {\n return\n }\n\n for (let i = 0; i < this.imageSizes.length; i++) {\n this.styles.push({\n url: this.imagePath + (i + 1) + '.' + this.imageExtension,\n height: this.imageSizes[i],\n width: this.imageSizes[i],\n })\n }\n }\n\n fitMapToMarkers() {\n const markers = this.getMarkers()\n\n const bounds = new google.maps.LatLngBounds()\n\n for (let i = 0; i < markers.length; i++) {\n const position = markers[i].getPosition()\n if (position) {\n bounds.extend(position)\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.getMap().fitBounds(bounds)\n }\n\n getGridSize(): number {\n return this.gridSize\n }\n\n setGridSize(gridSize: number) {\n this.gridSize = gridSize\n }\n\n getMinimumClusterSize(): number {\n return this.minClusterSize\n }\n\n setMinimumClusterSize(minimumClusterSize: number) {\n this.minClusterSize = minimumClusterSize\n }\n\n getMaxZoom(): number | null {\n return this.maxZoom\n }\n\n setMaxZoom(maxZoom: number) {\n this.maxZoom = maxZoom\n }\n\n getStyles(): ClusterIconStyle[] {\n return this.styles\n }\n\n setStyles(styles: ClusterIconStyle[]) {\n this.styles = styles\n }\n\n getTitle(): string {\n return this.title\n }\n\n setTitle(title: string) {\n this.title = title\n }\n\n getZoomOnClick(): boolean {\n return this.zoomOnClick\n }\n\n setZoomOnClick(zoomOnClick: boolean) {\n this.zoomOnClick = zoomOnClick\n }\n\n getAverageCenter(): boolean {\n return this.averageCenter\n }\n\n setAverageCenter(averageCenter: boolean) {\n this.averageCenter = averageCenter\n }\n\n getIgnoreHidden(): boolean {\n return this.ignoreHidden\n }\n\n setIgnoreHidden(ignoreHidden: boolean) {\n this.ignoreHidden = ignoreHidden\n }\n\n getEnableRetinaIcons(): boolean {\n return this.enableRetinaIcons\n }\n\n setEnableRetinaIcons(enableRetinaIcons: boolean) {\n this.enableRetinaIcons = enableRetinaIcons\n }\n\n getImageExtension(): string {\n return this.imageExtension\n }\n\n setImageExtension(imageExtension: string) {\n this.imageExtension = imageExtension\n }\n\n getImagePath(): string {\n return this.imagePath\n }\n\n setImagePath(imagePath: string) {\n this.imagePath = imagePath\n }\n\n getImageSizes(): number[] {\n return this.imageSizes\n }\n\n setImageSizes(imageSizes: number[]) {\n this.imageSizes = imageSizes\n }\n\n getCalculator(): TCalculator {\n return this.calculator\n }\n\n setCalculator(calculator: TCalculator) {\n this.calculator = calculator\n }\n\n getBatchSizeIE(): number {\n return this.batchSizeIE\n }\n\n setBatchSizeIE(batchSizeIE: number) {\n this.batchSizeIE = batchSizeIE\n }\n\n getClusterClass(): string {\n return this.clusterClass\n }\n\n setClusterClass(clusterClass: string) {\n this.clusterClass = clusterClass\n }\n\n getMarkers(): MarkerExtended[] {\n return this.markers\n }\n\n getTotalMarkers(): number {\n return this.markers.length\n }\n\n getClusters(): Cluster[] {\n return this.clusters\n }\n\n getTotalClusters(): number {\n return this.clusters.length\n }\n\n addMarker(marker: MarkerExtended, optNoDraw: boolean) {\n this.pushMarkerTo(marker)\n\n if (!optNoDraw) {\n this.redraw()\n }\n }\n\n addMarkers(markers: MarkerExtended[], optNoDraw: boolean) {\n for (const key in markers) {\n if (Object.prototype.hasOwnProperty.call(markers, key)) {\n this.pushMarkerTo(markers[key])\n }\n }\n\n if (!optNoDraw) {\n this.redraw()\n }\n }\n\n pushMarkerTo(marker: MarkerExtended) {\n // If the marker is draggable add a listener so we can update the clusters on the dragend:\n if (marker.getDraggable()) {\n google.maps.event.addListener(marker, 'dragend', () => {\n if (this.ready) {\n marker.isAdded = false\n\n this.repaint()\n }\n })\n }\n\n marker.isAdded = false\n\n this.markers.push(marker)\n }\n\n removeMarker_(marker: MarkerExtended): boolean {\n let index = -1\n\n if (this.markers.indexOf) {\n index = this.markers.indexOf(marker)\n } else {\n for (let i = 0; i < this.markers.length; i++) {\n if (marker === this.markers[i]) {\n index = i\n\n break\n }\n }\n }\n\n if (index === -1) {\n // Marker is not in our list of markers, so do nothing:\n return false\n }\n\n marker.setMap(null)\n\n this.markers.splice(index, 1) // Remove the marker from the list of managed markers\n\n return true\n }\n\n removeMarker(marker: MarkerExtended, optNoDraw: boolean): boolean {\n const removed = this.removeMarker_(marker)\n\n if (!optNoDraw && removed) {\n this.repaint()\n }\n\n return removed\n }\n\n removeMarkers(markers: MarkerExtended[], optNoDraw: boolean): boolean {\n let removed = false\n\n for (let i = 0; i < markers.length; i++) {\n removed = removed || this.removeMarker_(markers[i])\n }\n\n if (!optNoDraw && removed) {\n this.repaint()\n }\n\n return removed\n }\n\n clearMarkers() {\n this.resetViewport(true)\n\n this.markers = []\n }\n\n repaint() {\n const oldClusters = this.clusters.slice()\n\n this.clusters = []\n\n this.resetViewport(false)\n\n this.redraw()\n\n // Remove the old clusters.\n // Do it in a timeout to prevent blinking effect.\n setTimeout(function timeout() {\n for (let i = 0; i < oldClusters.length; i++) {\n oldClusters[i].remove()\n }\n }, 0)\n }\n\n getExtendedBounds(bounds: google.maps.LatLngBounds): google.maps.LatLngBounds {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const projection = this.getProjection()\n // Convert the points to pixels and the extend out by the grid size.\n const trPix = projection.fromLatLngToDivPixel(\n // Turn the bounds into latlng.\n new google.maps.LatLng(bounds.getNorthEast().lat(), bounds.getNorthEast().lng())\n )\n\n trPix.x += this.gridSize\n trPix.y -= this.gridSize\n\n const blPix = projection.fromLatLngToDivPixel(\n // Turn the bounds into latlng.\n new google.maps.LatLng(bounds.getSouthWest().lat(), bounds.getSouthWest().lng())\n )\n\n blPix.x -= this.gridSize\n blPix.y += this.gridSize\n\n // Extend the bounds to contain the new bounds.\n bounds.extend(\n // Convert the pixel points back to LatLng nw\n projection.fromDivPixelToLatLng(trPix)\n )\n\n bounds.extend(\n // Convert the pixel points back to LatLng sw\n projection.fromDivPixelToLatLng(blPix)\n )\n\n return bounds\n }\n\n redraw() {\n // Redraws all the clusters.\n this.createClusters(0)\n }\n\n resetViewport(optHide: boolean) {\n // Remove all the clusters\n for (let i = 0; i < this.clusters.length; i++) {\n this.clusters[i].remove()\n }\n\n this.clusters = []\n\n // Reset the markers to not be added and to be removed from the map.\n for (let i = 0; i < this.markers.length; i++) {\n const marker = this.markers[i]\n\n marker.isAdded = false\n\n if (optHide) {\n marker.setMap(null)\n }\n }\n }\n\n distanceBetweenPoints(p1: google.maps.LatLng, p2: google.maps.LatLng): number {\n const R = 6371 // Radius of the Earth in km\n\n const dLat = ((p2.lat() - p1.lat()) * Math.PI) / 180\n const dLon = ((p2.lng() - p1.lng()) * Math.PI) / 180\n\n const a =\n Math.sin(dLat / 2) * Math.sin(dLat / 2) +\n Math.cos((p1.lat() * Math.PI) / 180) *\n Math.cos((p2.lat() * Math.PI) / 180) *\n Math.sin(dLon / 2) *\n Math.sin(dLon / 2)\n\n return R * (2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)))\n }\n\n isMarkerInBounds(marker: MarkerExtended, bounds: google.maps.LatLngBounds): boolean {\n const position = marker.getPosition()\n\n if (position) {\n return bounds.contains(position)\n }\n\n return false\n }\n\n addToClosestCluster(marker: MarkerExtended) {\n let cluster\n\n let distance = 40000 // Some large number\n\n let clusterToAddTo = null\n\n for (let i = 0; i < this.clusters.length; i++) {\n cluster = this.clusters[i]\n\n const center = cluster.getCenter()\n\n const position = marker.getPosition()\n\n if (center && position) {\n const d = this.distanceBetweenPoints(center, position)\n\n if (d < distance) {\n distance = d\n\n clusterToAddTo = cluster\n }\n }\n }\n\n if (clusterToAddTo && clusterToAddTo.isMarkerInClusterBounds(marker)) {\n clusterToAddTo.addMarker(marker)\n } else {\n cluster = new Cluster(this)\n\n cluster.addMarker(marker)\n\n this.clusters.push(cluster)\n }\n }\n\n createClusters(iFirst: number) {\n if (!this.ready) {\n return\n }\n\n // Cancel previous batch processing if we're working on the first batch:\n if (iFirst === 0) {\n /**\n * This event is fired when the <code>Clusterer</code> begins\n * clustering markers.\n * @name Clusterer#clusteringbegin\n * @param {Clusterer} mc The Clusterer whose markers are being clustered.\n * @event\n */\n google.maps.event.trigger(this, 'clusteringbegin', this)\n\n if (this.timerRefStatic !== null) {\n window.clearTimeout(this.timerRefStatic)\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n delete this.timerRefStatic\n }\n }\n\n // Get our current map view bounds.\n // Create a new bounds object so we don't affect the map.\n //\n // See Comments 9 & 11 on Issue 3651 relating to this workaround for a Google Maps bug:\n const mapBounds =\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.getMap().getZoom() > 3\n ? new google.maps.LatLngBounds(\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.getMap()\n .getBounds()\n .getSouthWest(),\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.getMap()\n .getBounds()\n .getNorthEast()\n )\n : new google.maps.LatLngBounds(\n new google.maps.LatLng(85.02070771743472, -178.48388434375),\n new google.maps.LatLng(-85.08136444384544, 178.00048865625)\n )\n\n const bounds = this.getExtendedBounds(mapBounds)\n\n const iLast = Math.min(iFirst + this.batchSize, this.markers.length)\n\n for (let i = iFirst; i < iLast; i++) {\n const marker = this.markers[i]\n\n if (!marker.isAdded && this.isMarkerInBounds(marker, bounds) && (!this.ignoreHidden || (this.ignoreHidden && marker.getVisible()))) {\n this.addToClosestCluster(marker)\n }\n }\n\n if (iLast < this.markers.length) {\n this.timerRefStatic = window.setTimeout(\n () => {\n this.createClusters(iLast)\n },\n 0\n )\n } else {\n this.timerRefStatic = null\n\n /**\n * This event is fired when the <code>Clusterer</code> stops\n * clustering markers.\n * @name Clusterer#clusteringend\n * @param {Clusterer} mc The Clusterer whose markers are being clustered.\n * @event\n */\n google.maps.event.trigger(this, 'clusteringend', this)\n\n for (let i = 0; i < this.clusters.length; i++) {\n this.clusters[i].updateIcon()\n }\n }\n }\n\n extend(obj1: any, obj2: any): any {\n return function applyExtend(object: any) {\n // eslint-disable-next-line guard-for-in\n for (const property in object.prototype) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.prototype[property] = object.prototype[property]\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return this\n }.apply(obj1, [obj2])\n }\n}\n"],"names":["ClusterIcon","cluster","styles","getClusterer","extend","google","maps","OverlayView","this","clusterClassName","getClusterClass","className","center","undefined","div","sums","visible","boundsChangedListener","url","height","width","anchorText","anchorIcon","textColor","textSize","textDecoration","fontWeight","fontStyle","fontFamily","backgroundPosition","setMap","getMap","prototype","onAdd","cMouseDownInCluster","cDraggingMapByCluster","_this","document","createElement","show","getPanes","overlayMouseTarget","appendChild","event","addListener","markerClusterer_1","trigger","getZoomOnClick","maxZoom_1","getMaxZoom","bounds_1","getBounds","fitBounds","setTimeout","getZoom","setZoom","cancelBubble","stopPropagation","onRemove","parentNode","hide","removeListener","clearInstanceListeners","removeChild","draw","_a","getPosFromLatLng","x","y","style","top","left","display","divTitle","bp","split","spriteH","parseInt","replace","spriteV","pos","title","getTitle","cursor","position","concat","img","alt","src","enableRetinaIcons","clip","textElm","color","fontSize","textAlign","lineHeight","innerText","text","innerHTML","useStyle","getStyles","Math","min","length","max","index","setCenter","latlng","getProjection","fromLatLngToDivPixel","Cluster","markerClusterer","map","gridSize","getGridSize","minClusterSize","getMinimumClusterSize","averageCenter","getAverageCenter","markers","bounds","clusterIcon","getSize","getMarkers","getCenter","LatLngBounds","i","getPosition","remove","addMarker","marker","isMarkerAlreadyAdded","length_1","LatLng","lat","lng","calculateBounds","isAdded","push","mCount","maxZoom","zoom","isMarkerInClusterBounds","contains","getExtendedBounds","updateIcon","getCalculator","includes","CALCULATOR","numStyles","count","numberOfDigits","toString","IMAGE_SIZES","Clusterer","optMarkers","optOptions","clusters","listeners","activeMap","ready","minimumClusterSize","zoomOnClick","ignoreHidden","imagePath","imageExtension","imageSizes","calculator","batchSize","batchSizeIE","clusterClass","navigator","userAgent","toLowerCase","indexOf","timerRefStatic","setupStyles","addMarkers","repaint","resetViewport","get","redraw","fitMapToMarkers","setGridSize","setMinimumClusterSize","setMaxZoom","setStyles","setTitle","setZoomOnClick","setAverageCenter","getIgnoreHidden","setIgnoreHidden","getEnableRetinaIcons","setEnableRetinaIcons","getImageExtension","setImageExtension","getImagePath","setImagePath","getImageSizes","setImageSizes","setCalculator","getBatchSizeIE","setBatchSizeIE","setClusterClass","getTotalMarkers","getClusters","getTotalClusters","optNoDraw","pushMarkerTo","key","Object","hasOwnProperty","call","getDraggable","removeMarker_","splice","removeMarker","removed","removeMarkers","clearMarkers","oldClusters","slice","projection","trPix","getNorthEast","blPix","getSouthWest","fromDivPixelToLatLng","createClusters","optHide","distanceBetweenPoints","p1","p2","dLat","PI","dLon","a","sin","cos","atan2","sqrt","isMarkerInBounds","addToClosestCluster","distance","clusterToAddTo","d","iFirst","window","clearTimeout","mapBounds","iLast","getVisible","obj1","obj2","object","property","apply"],"mappings":"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"}
1
+ {"version":3,"file":"umd.min.js","sources":["../src/ClusterIcon.tsx","../src/Cluster.tsx","../src/Clusterer.tsx"],"sourcesContent":["/* global google */\n/* eslint-disable filenames/match-regex */\nimport { Cluster } from './Cluster'\n\nimport { ClusterIconStyle, ClusterIconInfo } from './types'\n\nexport class ClusterIcon {\n cluster: Cluster\n className: string\n clusterClassName: string\n styles: ClusterIconStyle[]\n center: google.maps.LatLng | undefined\n div: HTMLDivElement | null\n sums: ClusterIconInfo | null\n visible: boolean\n url: string\n height: number\n width: number\n anchorText: number[]\n anchorIcon: number[]\n textColor: string\n textSize: number\n textDecoration: string\n fontWeight: string\n fontStyle: string\n fontFamily: string\n backgroundPosition: string\n cMouseDownInCluster: boolean | null\n cDraggingMapByCluster: boolean | null\n timeOut: number | null\n\n boundsChangedListener: google.maps.MapsEventListener | null\n\n constructor(cluster: Cluster, styles: ClusterIconStyle[]) {\n cluster.getClusterer().extend(ClusterIcon, google.maps.OverlayView)\n this.cluster = cluster\n this.clusterClassName = this.cluster.getClusterer().getClusterClass()\n this.className = this.clusterClassName\n this.styles = styles\n this.center = undefined\n this.div = null\n this.sums = null\n this.visible = false\n this.boundsChangedListener = null\n this.url = ''\n this.height = 0\n this.width = 0\n this.anchorText = [0, 0]\n this.anchorIcon = [0, 0]\n this.textColor = 'black'\n this.textSize = 11\n this.textDecoration = 'none'\n this.fontWeight = 'bold'\n this.fontStyle = 'normal'\n this.fontFamily = 'Arial,sans-serif'\n this.backgroundPosition = '0 0'\n\n this.cMouseDownInCluster = null\n this.cDraggingMapByCluster = null\n this.timeOut = null\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.setMap(cluster.getMap()) // Note: this causes onAdd to be called\n }\n\n onBoundsChanged() {\n this.cDraggingMapByCluster = this.cMouseDownInCluster\n }\n\n onMouseDown() {\n this.cMouseDownInCluster = true\n\n this.cDraggingMapByCluster = false\n }\n\n onClick(event: Event) {\n this.cMouseDownInCluster = false\n\n if (!this.cDraggingMapByCluster) {\n const markerClusterer = this.cluster.getClusterer()\n\n /**\n * This event is fired when a cluster marker is clicked.\n * @name MarkerClusterer#click\n * @param {Cluster} c The cluster that was clicked.\n * @event\n */\n google.maps.event.trigger(markerClusterer, 'click', this.cluster)\n google.maps.event.trigger(markerClusterer, 'clusterclick', this.cluster) // deprecated name\n\n // The default click handler follows. Disable it by setting\n // the zoomOnClick property to false.\n if (markerClusterer.getZoomOnClick()) {\n // Zoom into the cluster.\n const maxZoom = markerClusterer.getMaxZoom()\n\n const bounds = this.cluster.getBounds()\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n markerClusterer.getMap().fitBounds(bounds)\n\n // There is a fix for Issue 170 here:\n this.timeOut = window.setTimeout(() => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n markerClusterer.getMap().fitBounds(bounds)\n\n // Don't zoom beyond the max zoom level\n if (\n maxZoom !== null &&\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n markerClusterer.getMap().getZoom() > maxZoom\n ) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n markerClusterer.getMap().setZoom(maxZoom + 1)\n }\n }, 100)\n }\n\n // Prevent event propagation to the map:\n event.cancelBubble = true\n\n if (event.stopPropagation) {\n event.stopPropagation()\n }\n }\n }\n\n onMouseOver() {\n /**\n * This event is fired when the mouse moves over a cluster marker.\n * @name MarkerClusterer#mouseover\n * @param {Cluster} c The cluster that the mouse moved over.\n * @event\n */\n google.maps.event.trigger(\n this.cluster.getClusterer(),\n 'mouseover',\n this.cluster\n )\n }\n\n onMouseOut() {\n /**\n * This event is fired when the mouse moves out of a cluster marker.\n * @name MarkerClusterer#mouseout\n * @param {Cluster} c The cluster that the mouse moved out of.\n * @event\n */\n google.maps.event.trigger(\n this.cluster.getClusterer(),\n 'mouseout',\n this.cluster\n )\n }\n\n onAdd() {\n this.div = document.createElement('div')\n this.div.className = this.className\n if (this.visible) {\n this.show()\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.getPanes().overlayMouseTarget.appendChild(this.div)\n // Fix for Issue 157\n this.boundsChangedListener = google.maps.event.addListener(\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.getMap(),\n 'bounds_changed',\n this.onBoundsChanged\n )\n\n this.div.addEventListener('mousedown', this.onMouseDown)\n\n this.div.addEventListener('click', this.onClick)\n\n this.div.addEventListener('mouseover', this.onMouseOver)\n\n this.div.addEventListener('mouseout', this.onMouseOut)\n }\n\n onRemove() {\n if (this.div && this.div.parentNode) {\n this.hide()\n\n if (this.boundsChangedListener !== null) {\n google.maps.event.removeListener(this.boundsChangedListener)\n }\n\n this.div.removeEventListener('mousedown', this.onMouseDown)\n\n this.div.removeEventListener('click', this.onClick)\n\n this.div.removeEventListener('mouseover', this.onMouseOver)\n\n this.div.removeEventListener('mouseout', this.onMouseOut)\n\n this.div.parentNode.removeChild(this.div)\n\n if (this.timeOut !== null) {\n window.clearTimeout(this.timeOut)\n\n this.timeOut = null\n }\n\n this.div = null\n }\n }\n\n draw() {\n if (this.visible && this.div !== null && this.center) {\n const { x, y } = this.getPosFromLatLng(this.center)\n\n this.div.style.top = `${y}px`\n this.div.style.left = `${x}px`\n }\n }\n\n hide() {\n if (this.div) {\n this.div.style.display = 'none'\n }\n\n this.visible = false\n }\n\n show() {\n if (this.div && this.center) {\n let divTitle = ''\n\n // NOTE: values must be specified in px units\n const bp = this.backgroundPosition.split(' ')\n\n const spriteH = parseInt(bp[0].replace(/^\\s+|\\s+$/g, ''), 10)\n const spriteV = parseInt(bp[1].replace(/^\\s+|\\s+$/g, ''), 10)\n\n const pos = this.getPosFromLatLng(this.center)\n\n if (\n this.sums === null ||\n typeof this.sums.title === 'undefined' ||\n this.sums.title === ''\n ) {\n divTitle = this.cluster.getClusterer().getTitle()\n } else {\n divTitle = this.sums.title\n }\n\n this.div.style.cursor = 'pointer'\n this.div.style.position = 'absolute'\n this.div.style.top = `${pos.y}px`\n this.div.style.left = `${pos.x}px`\n this.div.style.width = `${this.width}px`\n this.div.style.height = `${this.height}px`\n\n const img = document.createElement('img')\n img.alt = divTitle\n img.src = this.url\n img.style.position = 'absolute'\n img.style.top = `${spriteV}px`\n img.style.left = `${spriteH}px`\n\n if (!this.cluster.getClusterer().enableRetinaIcons) {\n img.style.clip = `rect(-${spriteV}px, -${spriteH + this.width}px, -${\n spriteV + this.height\n }, -${spriteH})`\n }\n\n const textElm = document.createElement('div')\n\n textElm.style.position = 'absolute'\n textElm.style.top = `${this.anchorText[0]}px`\n textElm.style.left = `${this.anchorText[1]}px`\n textElm.style.color = this.textColor\n textElm.style.fontSize = `${this.textSize}px`\n textElm.style.fontFamily = this.fontFamily\n textElm.style.fontWeight = this.fontWeight\n textElm.style.fontStyle = this.fontStyle\n textElm.style.textDecoration = this.textDecoration\n textElm.style.textAlign = 'center'\n textElm.style.width = `${this.width}px`\n textElm.style.lineHeight = `${this.height}px`\n textElm.innerText = `${this.sums?.text}`\n\n this.div.innerHTML = ''\n\n this.div.appendChild(img)\n this.div.appendChild(textElm)\n\n this.div.title = divTitle\n\n this.div.style.display = ''\n }\n\n this.visible = true\n }\n\n useStyle(sums: ClusterIconInfo) {\n this.sums = sums\n\n const styles = this.cluster.getClusterer().getStyles()\n\n const style =\n styles[Math.min(styles.length - 1, Math.max(0, sums.index - 1))]\n\n this.url = style.url\n this.height = style.height\n this.width = style.width\n\n if (style.className)\n this.className = `${this.clusterClassName} ${style.className}`\n\n this.anchorText = style.anchorText || [0, 0]\n this.anchorIcon = style.anchorIcon || [this.height / 2, this.width / 2]\n\n this.textColor = style.textColor || 'black'\n\n this.textSize = style.textSize || 11\n\n this.textDecoration = style.textDecoration || 'none'\n\n this.fontWeight = style.fontWeight || 'bold'\n\n this.fontStyle = style.fontStyle || 'normal'\n\n this.fontFamily = style.fontFamily || 'Arial,sans-serif'\n\n this.backgroundPosition = style.backgroundPosition || '0 0'\n }\n\n setCenter(center: google.maps.LatLng) {\n this.center = center\n }\n\n getPosFromLatLng(latlng: google.maps.LatLng): google.maps.Point {\n // @ts-ignore\n const pos = this.getProjection().fromLatLngToDivPixel(latlng)\n\n pos.x -= this.anchorIcon[1]\n\n pos.y -= this.anchorIcon[0]\n\n return pos\n }\n}\n","/* global google */\n/* eslint-disable filenames/match-regex */\nimport { Clusterer } from './Clusterer'\n\nimport { ClusterIcon } from './ClusterIcon'\n\nimport { MarkerExtended } from './types'\n\nexport class Cluster {\n markerClusterer: Clusterer\n map: google.maps.Map | google.maps.StreetViewPanorama\n gridSize: number\n minClusterSize: number\n averageCenter: boolean\n markers: MarkerExtended[]\n center: google.maps.LatLng | undefined\n bounds: google.maps.LatLngBounds | null\n clusterIcon: ClusterIcon\n\n constructor(markerClusterer: Clusterer) {\n this.markerClusterer = markerClusterer\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.map = this.markerClusterer.getMap()\n\n this.gridSize = this.markerClusterer.getGridSize()\n\n this.minClusterSize = this.markerClusterer.getMinimumClusterSize()\n\n this.averageCenter = this.markerClusterer.getAverageCenter()\n\n this.markers = []\n\n this.center = undefined\n\n this.bounds = null\n\n this.clusterIcon = new ClusterIcon(this, this.markerClusterer.getStyles())\n }\n\n getSize(): number {\n return this.markers.length\n }\n\n getMarkers(): MarkerExtended[] {\n return this.markers\n }\n\n getCenter(): google.maps.LatLng | undefined {\n return this.center\n }\n\n getMap(): google.maps.Map | google.maps.StreetViewPanorama {\n return this.map\n }\n\n getClusterer(): Clusterer {\n return this.markerClusterer\n }\n\n getBounds(): google.maps.LatLngBounds {\n const bounds = new google.maps.LatLngBounds(this.center, this.center)\n\n const markers = this.getMarkers()\n\n for (let i = 0; i < markers.length; i++) {\n const position = markers[i].getPosition()\n\n if (position) {\n bounds.extend(position)\n }\n }\n\n return bounds\n }\n\n remove() {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.clusterIcon.setMap(null)\n\n this.markers = []\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n delete this.markers\n }\n\n addMarker(marker: MarkerExtended): boolean {\n if (this.isMarkerAlreadyAdded(marker)) {\n return false\n }\n\n if (!this.center) {\n const position = marker.getPosition()\n\n if (position) {\n this.center = position\n\n this.calculateBounds()\n }\n } else {\n if (this.averageCenter) {\n const position = marker.getPosition()\n\n if (position) {\n const length = this.markers.length + 1\n\n this.center = new google.maps.LatLng(\n (this.center.lat() * (length - 1) + position.lat()) / length,\n (this.center.lng() * (length - 1) + position.lng()) / length\n )\n\n this.calculateBounds()\n }\n }\n }\n\n marker.isAdded = true\n\n this.markers.push(marker)\n\n const mCount = this.markers.length\n\n const maxZoom = this.markerClusterer.getMaxZoom()\n\n const zoom = this.map.getZoom()\n\n if (maxZoom !== null && typeof zoom !== 'undefined' && zoom > maxZoom) {\n // Zoomed in past max zoom, so show the marker.\n if (marker.getMap() !== this.map) {\n marker.setMap(this.map)\n }\n } else if (mCount < this.minClusterSize) {\n // Min cluster size not reached so show the marker.\n if (marker.getMap() !== this.map) {\n marker.setMap(this.map)\n }\n } else if (mCount === this.minClusterSize) {\n // Hide the markers that were showing.\n for (let i = 0; i < mCount; i++) {\n this.markers[i].setMap(null)\n }\n } else {\n marker.setMap(null)\n }\n\n return true\n }\n\n isMarkerInClusterBounds(marker: MarkerExtended): boolean {\n if (this.bounds !== null) {\n const position = marker.getPosition()\n\n if (position) {\n return this.bounds.contains(position)\n }\n }\n\n return false\n }\n\n calculateBounds() {\n this.bounds = this.markerClusterer.getExtendedBounds(\n new google.maps.LatLngBounds(this.center, this.center)\n )\n }\n\n updateIcon() {\n const mCount = this.markers.length\n\n const maxZoom = this.markerClusterer.getMaxZoom()\n\n const zoom = this.map.getZoom()\n\n if (maxZoom !== null && typeof zoom !== 'undefined' && zoom > maxZoom) {\n this.clusterIcon.hide()\n\n return\n }\n\n if (mCount < this.minClusterSize) {\n // Min cluster size not yet reached.\n this.clusterIcon.hide()\n\n return\n }\n\n if (this.center) {\n this.clusterIcon.setCenter(this.center)\n }\n\n this.clusterIcon.useStyle(\n this.markerClusterer.getCalculator()(this.markers, this.markerClusterer.getStyles().length)\n )\n\n this.clusterIcon.show()\n }\n\n isMarkerAlreadyAdded(marker: MarkerExtended): boolean {\n if (this.markers.includes) {\n return this.markers.includes(marker)\n }\n\n for (let i = 0; i < this.markers.length; i++) {\n if (marker === this.markers[i]) {\n return true\n }\n }\n\n return false\n }\n}\n","/* global google */\n/* eslint-disable filenames/match-regex */\nimport { Cluster } from './Cluster'\n\nimport {\n MarkerExtended,\n ClustererOptions,\n ClusterIconStyle,\n TCalculator,\n ClusterIconInfo,\n} from './types'\n\n/**\n * Supports up to 9007199254740991 (Number.MAX_SAFE_INTEGER) markers\n * which is not a problem as max array length is 4294967296 (2**32)\n */\nconst CALCULATOR = function CALCULATOR(\n markers: MarkerExtended[],\n numStyles: number\n): ClusterIconInfo {\n const count = markers.length\n\n const numberOfDigits = count.toString().length\n\n const index = Math.min(numberOfDigits, numStyles)\n\n return {\n text: count.toString(),\n index,\n title: '',\n }\n}\n\nconst BATCH_SIZE = 2000\n\nconst BATCH_SIZE_IE = 500\n\nconst IMAGE_PATH =\n 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'\n\nconst IMAGE_EXTENSION = 'png'\n\nconst IMAGE_SIZES = [53, 56, 66, 78, 90]\n\nconst CLUSTERER_CLASS = 'cluster'\n\nexport class Clusterer {\n markers: MarkerExtended[]\n clusters: Cluster[]\n listeners: google.maps.MapsEventListener[]\n activeMap: google.maps.Map | google.maps.StreetViewPanorama | null\n ready: boolean\n gridSize: number\n minClusterSize: number\n maxZoom: number | null\n styles: ClusterIconStyle[]\n title: string\n zoomOnClick: boolean\n averageCenter: boolean\n ignoreHidden: boolean\n enableRetinaIcons: boolean\n imagePath: string\n imageExtension: string\n imageSizes: number[]\n calculator: TCalculator\n batchSize: number\n batchSizeIE: number\n clusterClass: string\n timerRefStatic: number | null\n\n constructor(\n map: google.maps.Map,\n optMarkers: MarkerExtended[] = [],\n optOptions: ClustererOptions = {}\n ) {\n this.extend(Clusterer, google.maps.OverlayView)\n\n this.markers = []\n this.clusters = []\n this.listeners = []\n this.activeMap = null\n this.ready = false\n this.gridSize = optOptions.gridSize || 60\n this.minClusterSize = optOptions.minimumClusterSize || 2\n this.maxZoom = optOptions.maxZoom || null\n this.styles = optOptions.styles || []\n\n this.title = optOptions.title || ''\n\n this.zoomOnClick = true\n\n if (optOptions.zoomOnClick !== undefined) {\n this.zoomOnClick = optOptions.zoomOnClick\n }\n\n this.averageCenter = false\n\n if (optOptions.averageCenter !== undefined) {\n this.averageCenter = optOptions.averageCenter\n }\n\n this.ignoreHidden = false\n\n if (optOptions.ignoreHidden !== undefined) {\n this.ignoreHidden = optOptions.ignoreHidden\n }\n\n this.enableRetinaIcons = false\n\n if (optOptions.enableRetinaIcons !== undefined) {\n this.enableRetinaIcons = optOptions.enableRetinaIcons\n }\n this.imagePath = optOptions.imagePath || IMAGE_PATH\n\n this.imageExtension = optOptions.imageExtension || IMAGE_EXTENSION\n\n this.imageSizes = optOptions.imageSizes || IMAGE_SIZES\n\n this.calculator = optOptions.calculator || CALCULATOR\n\n this.batchSize = optOptions.batchSize || BATCH_SIZE\n\n this.batchSizeIE = optOptions.batchSizeIE || BATCH_SIZE_IE\n\n this.clusterClass = optOptions.clusterClass || CLUSTERER_CLASS\n\n if (navigator.userAgent.toLowerCase().indexOf('msie') !== -1) {\n // Try to avoid IE timeout when processing a huge number of markers:\n this.batchSize = this.batchSizeIE\n }\n\n this.timerRefStatic = null\n\n this.setupStyles()\n\n this.addMarkers(optMarkers, true)\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.setMap(map) // Note: this causes onAdd to be called\n }\n\n onAdd() {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.activeMap = this.getMap()\n\n this.ready = true\n\n this.repaint()\n\n // Add the map event listeners\n this.listeners = [\n google.maps.event.addListener(\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.getMap(),\n 'zoom_changed',\n () => {\n this.resetViewport(false)\n // Workaround for this Google bug: when map is at level 0 and \"-\" of\n // zoom slider is clicked, a \"zoom_changed\" event is fired even though\n // the map doesn't zoom out any further. In this situation, no \"idle\"\n // event is triggered so the cluster markers that have been removed\n // do not get redrawn. Same goes for a zoom in at maxZoom.\n if (\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.getMap().getZoom() === (this.get('minZoom') || 0) ||\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.getMap().getZoom() === this.get('maxZoom')\n ) {\n google.maps.event.trigger(this, 'idle')\n }\n }\n ),\n google.maps.event.addListener(\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.getMap(),\n 'idle',\n () => {\n this.redraw()\n }\n ),\n ]\n }\n\n onRemove() {\n // Put all the managed markers back on the map:\n for (let i = 0; i < this.markers.length; i++) {\n if (this.markers[i].getMap() !== this.activeMap) {\n this.markers[i].setMap(this.activeMap)\n }\n }\n\n // Remove all clusters:\n for (let i = 0; i < this.clusters.length; i++) {\n this.clusters[i].remove()\n }\n\n this.clusters = []\n\n // Remove map event listeners:\n for (let i = 0; i < this.listeners.length; i++) {\n google.maps.event.removeListener(this.listeners[i])\n }\n\n this.listeners = []\n\n this.activeMap = null\n\n this.ready = false\n }\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n draw() {}\n\n setupStyles() {\n if (this.styles.length > 0) {\n return\n }\n\n for (let i = 0; i < this.imageSizes.length; i++) {\n this.styles.push({\n url: this.imagePath + (i + 1) + '.' + this.imageExtension,\n height: this.imageSizes[i],\n width: this.imageSizes[i],\n })\n }\n }\n\n fitMapToMarkers() {\n const markers = this.getMarkers()\n\n const bounds = new google.maps.LatLngBounds()\n\n for (let i = 0; i < markers.length; i++) {\n const position = markers[i].getPosition()\n if (position) {\n bounds.extend(position)\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.getMap().fitBounds(bounds)\n }\n\n getGridSize(): number {\n return this.gridSize\n }\n\n setGridSize(gridSize: number) {\n this.gridSize = gridSize\n }\n\n getMinimumClusterSize(): number {\n return this.minClusterSize\n }\n\n setMinimumClusterSize(minimumClusterSize: number) {\n this.minClusterSize = minimumClusterSize\n }\n\n getMaxZoom(): number | null {\n return this.maxZoom\n }\n\n setMaxZoom(maxZoom: number) {\n this.maxZoom = maxZoom\n }\n\n getStyles(): ClusterIconStyle[] {\n return this.styles\n }\n\n setStyles(styles: ClusterIconStyle[]) {\n this.styles = styles\n }\n\n getTitle(): string {\n return this.title\n }\n\n setTitle(title: string) {\n this.title = title\n }\n\n getZoomOnClick(): boolean {\n return this.zoomOnClick\n }\n\n setZoomOnClick(zoomOnClick: boolean) {\n this.zoomOnClick = zoomOnClick\n }\n\n getAverageCenter(): boolean {\n return this.averageCenter\n }\n\n setAverageCenter(averageCenter: boolean) {\n this.averageCenter = averageCenter\n }\n\n getIgnoreHidden(): boolean {\n return this.ignoreHidden\n }\n\n setIgnoreHidden(ignoreHidden: boolean) {\n this.ignoreHidden = ignoreHidden\n }\n\n getEnableRetinaIcons(): boolean {\n return this.enableRetinaIcons\n }\n\n setEnableRetinaIcons(enableRetinaIcons: boolean) {\n this.enableRetinaIcons = enableRetinaIcons\n }\n\n getImageExtension(): string {\n return this.imageExtension\n }\n\n setImageExtension(imageExtension: string) {\n this.imageExtension = imageExtension\n }\n\n getImagePath(): string {\n return this.imagePath\n }\n\n setImagePath(imagePath: string) {\n this.imagePath = imagePath\n }\n\n getImageSizes(): number[] {\n return this.imageSizes\n }\n\n setImageSizes(imageSizes: number[]) {\n this.imageSizes = imageSizes\n }\n\n getCalculator(): TCalculator {\n return this.calculator\n }\n\n setCalculator(calculator: TCalculator) {\n this.calculator = calculator\n }\n\n getBatchSizeIE(): number {\n return this.batchSizeIE\n }\n\n setBatchSizeIE(batchSizeIE: number) {\n this.batchSizeIE = batchSizeIE\n }\n\n getClusterClass(): string {\n return this.clusterClass\n }\n\n setClusterClass(clusterClass: string) {\n this.clusterClass = clusterClass\n }\n\n getMarkers(): MarkerExtended[] {\n return this.markers\n }\n\n getTotalMarkers(): number {\n return this.markers.length\n }\n\n getClusters(): Cluster[] {\n return this.clusters\n }\n\n getTotalClusters(): number {\n return this.clusters.length\n }\n\n addMarker(marker: MarkerExtended, optNoDraw: boolean) {\n this.pushMarkerTo(marker)\n\n if (!optNoDraw) {\n this.redraw()\n }\n }\n\n addMarkers(markers: MarkerExtended[], optNoDraw: boolean) {\n for (const key in markers) {\n if (Object.prototype.hasOwnProperty.call(markers, key)) {\n this.pushMarkerTo(markers[key])\n }\n }\n\n if (!optNoDraw) {\n this.redraw()\n }\n }\n\n pushMarkerTo(marker: MarkerExtended) {\n // If the marker is draggable add a listener so we can update the clusters on the dragend:\n if (marker.getDraggable()) {\n google.maps.event.addListener(marker, 'dragend', () => {\n if (this.ready) {\n marker.isAdded = false\n\n this.repaint()\n }\n })\n }\n\n marker.isAdded = false\n\n this.markers.push(marker)\n }\n\n removeMarker_(marker: MarkerExtended): boolean {\n let index = -1\n\n if (this.markers.indexOf) {\n index = this.markers.indexOf(marker)\n } else {\n for (let i = 0; i < this.markers.length; i++) {\n if (marker === this.markers[i]) {\n index = i\n\n break\n }\n }\n }\n\n if (index === -1) {\n // Marker is not in our list of markers, so do nothing:\n return false\n }\n\n marker.setMap(null)\n\n this.markers.splice(index, 1) // Remove the marker from the list of managed markers\n\n return true\n }\n\n removeMarker(marker: MarkerExtended, optNoDraw: boolean): boolean {\n const removed = this.removeMarker_(marker)\n\n if (!optNoDraw && removed) {\n this.repaint()\n }\n\n return removed\n }\n\n removeMarkers(markers: MarkerExtended[], optNoDraw: boolean): boolean {\n let removed = false\n\n for (let i = 0; i < markers.length; i++) {\n removed = removed || this.removeMarker_(markers[i])\n }\n\n if (!optNoDraw && removed) {\n this.repaint()\n }\n\n return removed\n }\n\n clearMarkers() {\n this.resetViewport(true)\n\n this.markers = []\n }\n\n repaint() {\n const oldClusters = this.clusters.slice()\n\n this.clusters = []\n\n this.resetViewport(false)\n\n this.redraw()\n\n // Remove the old clusters.\n // Do it in a timeout to prevent blinking effect.\n setTimeout(function timeout() {\n for (let i = 0; i < oldClusters.length; i++) {\n oldClusters[i].remove()\n }\n }, 0)\n }\n\n getExtendedBounds(bounds: google.maps.LatLngBounds): google.maps.LatLngBounds {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const projection = this.getProjection()\n // Convert the points to pixels and the extend out by the grid size.\n const trPix = projection.fromLatLngToDivPixel(\n // Turn the bounds into latlng.\n new google.maps.LatLng(bounds.getNorthEast().lat(), bounds.getNorthEast().lng())\n )\n\n trPix.x += this.gridSize\n trPix.y -= this.gridSize\n\n const blPix = projection.fromLatLngToDivPixel(\n // Turn the bounds into latlng.\n new google.maps.LatLng(bounds.getSouthWest().lat(), bounds.getSouthWest().lng())\n )\n\n blPix.x -= this.gridSize\n blPix.y += this.gridSize\n\n // Extend the bounds to contain the new bounds.\n bounds.extend(\n // Convert the pixel points back to LatLng nw\n projection.fromDivPixelToLatLng(trPix)\n )\n\n bounds.extend(\n // Convert the pixel points back to LatLng sw\n projection.fromDivPixelToLatLng(blPix)\n )\n\n return bounds\n }\n\n redraw() {\n // Redraws all the clusters.\n this.createClusters(0)\n }\n\n resetViewport(optHide: boolean) {\n // Remove all the clusters\n for (let i = 0; i < this.clusters.length; i++) {\n this.clusters[i].remove()\n }\n\n this.clusters = []\n\n // Reset the markers to not be added and to be removed from the map.\n for (let i = 0; i < this.markers.length; i++) {\n const marker = this.markers[i]\n\n marker.isAdded = false\n\n if (optHide) {\n marker.setMap(null)\n }\n }\n }\n\n distanceBetweenPoints(p1: google.maps.LatLng, p2: google.maps.LatLng): number {\n const R = 6371 // Radius of the Earth in km\n\n const dLat = ((p2.lat() - p1.lat()) * Math.PI) / 180\n const dLon = ((p2.lng() - p1.lng()) * Math.PI) / 180\n\n const a =\n Math.sin(dLat / 2) * Math.sin(dLat / 2) +\n Math.cos((p1.lat() * Math.PI) / 180) *\n Math.cos((p2.lat() * Math.PI) / 180) *\n Math.sin(dLon / 2) *\n Math.sin(dLon / 2)\n\n return R * (2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)))\n }\n\n isMarkerInBounds(marker: MarkerExtended, bounds: google.maps.LatLngBounds): boolean {\n const position = marker.getPosition()\n\n if (position) {\n return bounds.contains(position)\n }\n\n return false\n }\n\n addToClosestCluster(marker: MarkerExtended) {\n let cluster\n\n let distance = 40000 // Some large number\n\n let clusterToAddTo = null\n\n for (let i = 0; i < this.clusters.length; i++) {\n cluster = this.clusters[i]\n\n const center = cluster.getCenter()\n\n const position = marker.getPosition()\n\n if (center && position) {\n const d = this.distanceBetweenPoints(center, position)\n\n if (d < distance) {\n distance = d\n\n clusterToAddTo = cluster\n }\n }\n }\n\n if (clusterToAddTo && clusterToAddTo.isMarkerInClusterBounds(marker)) {\n clusterToAddTo.addMarker(marker)\n } else {\n cluster = new Cluster(this)\n\n cluster.addMarker(marker)\n\n this.clusters.push(cluster)\n }\n }\n\n createClusters(iFirst: number) {\n if (!this.ready) {\n return\n }\n\n // Cancel previous batch processing if we're working on the first batch:\n if (iFirst === 0) {\n /**\n * This event is fired when the <code>Clusterer</code> begins\n * clustering markers.\n * @name Clusterer#clusteringbegin\n * @param {Clusterer} mc The Clusterer whose markers are being clustered.\n * @event\n */\n google.maps.event.trigger(this, 'clusteringbegin', this)\n\n if (this.timerRefStatic !== null) {\n window.clearTimeout(this.timerRefStatic)\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n delete this.timerRefStatic\n }\n }\n\n // Get our current map view bounds.\n // Create a new bounds object so we don't affect the map.\n //\n // See Comments 9 & 11 on Issue 3651 relating to this workaround for a Google Maps bug:\n const mapBounds =\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.getMap().getZoom() > 3\n ? new google.maps.LatLngBounds(\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.getMap()\n .getBounds()\n .getSouthWest(),\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.getMap()\n .getBounds()\n .getNorthEast()\n )\n : new google.maps.LatLngBounds(\n new google.maps.LatLng(85.02070771743472, -178.48388434375),\n new google.maps.LatLng(-85.08136444384544, 178.00048865625)\n )\n\n const bounds = this.getExtendedBounds(mapBounds)\n\n const iLast = Math.min(iFirst + this.batchSize, this.markers.length)\n\n for (let i = iFirst; i < iLast; i++) {\n const marker = this.markers[i]\n\n if (!marker.isAdded && this.isMarkerInBounds(marker, bounds) && (!this.ignoreHidden || (this.ignoreHidden && marker.getVisible()))) {\n this.addToClosestCluster(marker)\n }\n }\n\n if (iLast < this.markers.length) {\n this.timerRefStatic = window.setTimeout(\n () => {\n this.createClusters(iLast)\n },\n 0\n )\n } else {\n this.timerRefStatic = null\n\n /**\n * This event is fired when the <code>Clusterer</code> stops\n * clustering markers.\n * @name Clusterer#clusteringend\n * @param {Clusterer} mc The Clusterer whose markers are being clustered.\n * @event\n */\n google.maps.event.trigger(this, 'clusteringend', this)\n\n for (let i = 0; i < this.clusters.length; i++) {\n this.clusters[i].updateIcon()\n }\n }\n }\n\n extend(obj1: any, obj2: any): any {\n return function applyExtend(object: any) {\n // eslint-disable-next-line guard-for-in\n for (const property in object.prototype) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.prototype[property] = object.prototype[property]\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return this\n }.apply(obj1, [obj2])\n }\n}\n"],"names":["ClusterIcon","cluster","styles","getClusterer","extend","google","maps","OverlayView","this","clusterClassName","getClusterClass","className","center","undefined","div","sums","visible","boundsChangedListener","url","height","width","anchorText","anchorIcon","textColor","textSize","textDecoration","fontWeight","fontStyle","fontFamily","backgroundPosition","cMouseDownInCluster","cDraggingMapByCluster","timeOut","setMap","getMap","prototype","onBoundsChanged","onMouseDown","onClick","event","markerClusterer_1","trigger","getZoomOnClick","maxZoom_1","getMaxZoom","bounds_1","getBounds","fitBounds","window","setTimeout","getZoom","setZoom","cancelBubble","stopPropagation","onMouseOver","onMouseOut","onAdd","document","createElement","show","getPanes","overlayMouseTarget","appendChild","addListener","addEventListener","onRemove","parentNode","hide","removeListener","removeEventListener","removeChild","clearTimeout","draw","_a","getPosFromLatLng","x","y","style","top","concat","left","display","divTitle","bp","split","spriteH","parseInt","replace","spriteV","pos","title","getTitle","cursor","position","img","alt","src","enableRetinaIcons","clip","textElm","color","fontSize","textAlign","lineHeight","innerText","text","innerHTML","useStyle","getStyles","Math","min","length","max","index","setCenter","latlng","getProjection","fromLatLngToDivPixel","Cluster","markerClusterer","map","gridSize","getGridSize","minClusterSize","getMinimumClusterSize","averageCenter","getAverageCenter","markers","bounds","clusterIcon","getSize","getMarkers","getCenter","LatLngBounds","i","getPosition","remove","addMarker","marker","isMarkerAlreadyAdded","length_1","LatLng","lat","lng","calculateBounds","isAdded","push","mCount","maxZoom","zoom","isMarkerInClusterBounds","contains","getExtendedBounds","updateIcon","getCalculator","includes","CALCULATOR","numStyles","count","numberOfDigits","toString","IMAGE_SIZES","Clusterer","optMarkers","optOptions","clusters","listeners","activeMap","ready","minimumClusterSize","zoomOnClick","ignoreHidden","imagePath","imageExtension","imageSizes","calculator","batchSize","batchSizeIE","clusterClass","navigator","userAgent","toLowerCase","indexOf","timerRefStatic","setupStyles","addMarkers","_this","repaint","resetViewport","get","redraw","fitMapToMarkers","setGridSize","setMinimumClusterSize","setMaxZoom","setStyles","setTitle","setZoomOnClick","setAverageCenter","getIgnoreHidden","setIgnoreHidden","getEnableRetinaIcons","setEnableRetinaIcons","getImageExtension","setImageExtension","getImagePath","setImagePath","getImageSizes","setImageSizes","setCalculator","getBatchSizeIE","setBatchSizeIE","setClusterClass","getTotalMarkers","getClusters","getTotalClusters","optNoDraw","pushMarkerTo","key","Object","hasOwnProperty","call","getDraggable","removeMarker_","splice","removeMarker","removed","removeMarkers","clearMarkers","oldClusters","slice","projection","trPix","getNorthEast","blPix","getSouthWest","fromDivPixelToLatLng","createClusters","optHide","distanceBetweenPoints","p1","p2","dLat","PI","dLon","a","sin","cos","atan2","sqrt","isMarkerInBounds","addToClosestCluster","distance","clusterToAddTo","d","iFirst","mapBounds","iLast","getVisible","obj1","obj2","object","property","apply"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@react-google-maps/marker-clusterer",
3
3
  "sideEffects": false,
4
- "version": "2.10.0",
4
+ "version": "2.10.1",
5
5
  "description": "Marker Clusterer for React.js Google Maps API",
6
6
  "license": "MIT",
7
7
  "author": {
@@ -53,15 +53,15 @@
53
53
  },
54
54
  "devDependencies": {
55
55
  "@getify/eslint-plugin-proper-arrows": "11.0.3",
56
- "@rollup/plugin-commonjs": "21.1.0",
57
- "@rollup/plugin-node-resolve": "13.2.1",
56
+ "@rollup/plugin-commonjs": "22.0.0",
57
+ "@rollup/plugin-node-resolve": "13.3.0",
58
58
  "@rollup/plugin-typescript": "8.3.2",
59
59
  "@types/babel-types": "7.0.11",
60
- "@types/google.maps": "3.48.5",
61
- "jest": "27.5.1",
62
- "jest-cli": "27.5.1",
60
+ "@types/google.maps": "3.48.8",
61
+ "jest": "28.1.0",
62
+ "jest-cli": "28.1.0",
63
63
  "rimraf": "3.0.2",
64
- "rollup": "2.70.2",
64
+ "rollup": "2.73.0",
65
65
  "rollup-plugin-dts": "4.2.1",
66
66
  "rollup-plugin-terser": "7.0.2"
67
67
  },
@@ -25,6 +25,9 @@ export class ClusterIcon {
25
25
  fontStyle: string
26
26
  fontFamily: string
27
27
  backgroundPosition: string
28
+ cMouseDownInCluster: boolean | null
29
+ cDraggingMapByCluster: boolean | null
30
+ timeOut: number | null
28
31
 
29
32
  boundsChangedListener: google.maps.MapsEventListener | null
30
33
 
@@ -51,118 +54,135 @@ export class ClusterIcon {
51
54
  this.fontStyle = 'normal'
52
55
  this.fontFamily = 'Arial,sans-serif'
53
56
  this.backgroundPosition = '0 0'
57
+
58
+ this.cMouseDownInCluster = null
59
+ this.cDraggingMapByCluster = null
60
+ this.timeOut = null
61
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
54
62
  // @ts-ignore
55
63
  this.setMap(cluster.getMap()) // Note: this causes onAdd to be called
56
64
  }
57
65
 
58
- onAdd() {
59
- let cMouseDownInCluster: boolean
60
- let cDraggingMapByCluster: boolean
66
+ onBoundsChanged() {
67
+ this.cDraggingMapByCluster = this.cMouseDownInCluster
68
+ }
69
+
70
+ onMouseDown() {
71
+ this.cMouseDownInCluster = true
72
+
73
+ this.cDraggingMapByCluster = false
74
+ }
75
+
76
+ onClick(event: Event) {
77
+ this.cMouseDownInCluster = false
78
+
79
+ if (!this.cDraggingMapByCluster) {
80
+ const markerClusterer = this.cluster.getClusterer()
81
+
82
+ /**
83
+ * This event is fired when a cluster marker is clicked.
84
+ * @name MarkerClusterer#click
85
+ * @param {Cluster} c The cluster that was clicked.
86
+ * @event
87
+ */
88
+ google.maps.event.trigger(markerClusterer, 'click', this.cluster)
89
+ google.maps.event.trigger(markerClusterer, 'clusterclick', this.cluster) // deprecated name
90
+
91
+ // The default click handler follows. Disable it by setting
92
+ // the zoomOnClick property to false.
93
+ if (markerClusterer.getZoomOnClick()) {
94
+ // Zoom into the cluster.
95
+ const maxZoom = markerClusterer.getMaxZoom()
96
+
97
+ const bounds = this.cluster.getBounds()
98
+
99
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
100
+ // @ts-ignore
101
+ markerClusterer.getMap().fitBounds(bounds)
102
+
103
+ // There is a fix for Issue 170 here:
104
+ this.timeOut = window.setTimeout(() => {
105
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
106
+ // @ts-ignore
107
+ markerClusterer.getMap().fitBounds(bounds)
108
+
109
+ // Don't zoom beyond the max zoom level
110
+ if (
111
+ maxZoom !== null &&
112
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
113
+ // @ts-ignore
114
+ markerClusterer.getMap().getZoom() > maxZoom
115
+ ) {
116
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
117
+ // @ts-ignore
118
+ markerClusterer.getMap().setZoom(maxZoom + 1)
119
+ }
120
+ }, 100)
121
+ }
61
122
 
123
+ // Prevent event propagation to the map:
124
+ event.cancelBubble = true
125
+
126
+ if (event.stopPropagation) {
127
+ event.stopPropagation()
128
+ }
129
+ }
130
+ }
131
+
132
+ onMouseOver() {
133
+ /**
134
+ * This event is fired when the mouse moves over a cluster marker.
135
+ * @name MarkerClusterer#mouseover
136
+ * @param {Cluster} c The cluster that the mouse moved over.
137
+ * @event
138
+ */
139
+ google.maps.event.trigger(
140
+ this.cluster.getClusterer(),
141
+ 'mouseover',
142
+ this.cluster
143
+ )
144
+ }
145
+
146
+ onMouseOut() {
147
+ /**
148
+ * This event is fired when the mouse moves out of a cluster marker.
149
+ * @name MarkerClusterer#mouseout
150
+ * @param {Cluster} c The cluster that the mouse moved out of.
151
+ * @event
152
+ */
153
+ google.maps.event.trigger(
154
+ this.cluster.getClusterer(),
155
+ 'mouseout',
156
+ this.cluster
157
+ )
158
+ }
159
+
160
+ onAdd() {
62
161
  this.div = document.createElement('div')
63
162
  this.div.className = this.className
64
163
  if (this.visible) {
65
164
  this.show()
66
165
  }
67
166
 
167
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
68
168
  // @ts-ignore
69
169
  this.getPanes().overlayMouseTarget.appendChild(this.div)
70
-
71
170
  // Fix for Issue 157
72
171
  this.boundsChangedListener = google.maps.event.addListener(
172
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
73
173
  // @ts-ignore
74
174
  this.getMap(),
75
- 'boundschanged',
76
- function boundsChanged() {
77
- cDraggingMapByCluster = cMouseDownInCluster
78
- }
175
+ 'bounds_changed',
176
+ this.onBoundsChanged
79
177
  )
80
178
 
81
- google.maps.event.addListener(this.div, 'mousedown', function onMouseDown() {
82
- cMouseDownInCluster = true
83
- cDraggingMapByCluster = false
84
- })
85
-
86
- google.maps.event.addListener(
87
- this.div,
88
- 'click',
89
- (event: Event) => {
90
- cMouseDownInCluster = false
91
-
92
- if (!cDraggingMapByCluster) {
93
- const markerClusterer = this.cluster.getClusterer()
94
-
95
- /**
96
- * This event is fired when a cluster marker is clicked.
97
- * @name MarkerClusterer#click
98
- * @param {Cluster} c The cluster that was clicked.
99
- * @event
100
- */
101
- google.maps.event.trigger(markerClusterer, 'click', this.cluster)
102
- google.maps.event.trigger(markerClusterer, 'clusterclick', this.cluster) // deprecated name
103
-
104
- // The default click handler follows. Disable it by setting
105
- // the zoomOnClick property to false.
106
- if (markerClusterer.getZoomOnClick()) {
107
- // Zoom into the cluster.
108
- const maxZoom = markerClusterer.getMaxZoom()
109
-
110
- const bounds = this.cluster.getBounds()
179
+ this.div.addEventListener('mousedown', this.onMouseDown)
111
180
 
112
- // @ts-ignore
113
- markerClusterer.getMap().fitBounds(bounds)
114
-
115
- // There is a fix for Issue 170 here:
116
- setTimeout(function timeout() {
117
- // @ts-ignore
118
- markerClusterer.getMap().fitBounds(bounds)
119
-
120
- // Don't zoom beyond the max zoom level
121
- // @ts-ignore
122
- if (maxZoom !== null && markerClusterer.getMap().getZoom() > maxZoom) {
123
- // @ts-ignore
124
- markerClusterer.getMap().setZoom(maxZoom + 1)
125
- }
126
- }, 100)
127
- }
128
-
129
- // Prevent event propagation to the map:
130
- event.cancelBubble = true
131
-
132
- if (event.stopPropagation) {
133
- event.stopPropagation()
134
- }
135
- }
136
- }
137
- )
181
+ this.div.addEventListener('click', this.onClick)
138
182
 
139
- google.maps.event.addListener(
140
- this.div,
141
- 'mouseover',
142
- () => {
143
- /**
144
- * This event is fired when the mouse moves over a cluster marker.
145
- * @name MarkerClusterer#mouseover
146
- * @param {Cluster} c The cluster that the mouse moved over.
147
- * @event
148
- */
149
- google.maps.event.trigger(this.cluster.getClusterer(), 'mouseover', this.cluster)
150
- }
151
- )
183
+ this.div.addEventListener('mouseover', this.onMouseOver)
152
184
 
153
- google.maps.event.addListener(
154
- this.div,
155
- 'mouseout',
156
- () => {
157
- /**
158
- * This event is fired when the mouse moves out of a cluster marker.
159
- * @name MarkerClusterer#mouseout
160
- * @param {Cluster} c The cluster that the mouse moved out of.
161
- * @event
162
- */
163
- google.maps.event.trigger(this.cluster.getClusterer(), 'mouseout', this.cluster)
164
- }
165
- )
185
+ this.div.addEventListener('mouseout', this.onMouseOut)
166
186
  }
167
187
 
168
188
  onRemove() {
@@ -173,10 +193,22 @@ export class ClusterIcon {
173
193
  google.maps.event.removeListener(this.boundsChangedListener)
174
194
  }
175
195
 
176
- google.maps.event.clearInstanceListeners(this.div)
196
+ this.div.removeEventListener('mousedown', this.onMouseDown)
197
+
198
+ this.div.removeEventListener('click', this.onClick)
199
+
200
+ this.div.removeEventListener('mouseover', this.onMouseOver)
201
+
202
+ this.div.removeEventListener('mouseout', this.onMouseOut)
177
203
 
178
204
  this.div.parentNode.removeChild(this.div)
179
205
 
206
+ if (this.timeOut !== null) {
207
+ window.clearTimeout(this.timeOut)
208
+
209
+ this.timeOut = null
210
+ }
211
+
180
212
  this.div = null
181
213
  }
182
214
  }
@@ -185,8 +217,8 @@ export class ClusterIcon {
185
217
  if (this.visible && this.div !== null && this.center) {
186
218
  const { x, y } = this.getPosFromLatLng(this.center)
187
219
 
188
- this.div.style.top = y + 'px'
189
- this.div.style.left = x + 'px'
220
+ this.div.style.top = `${y}px`
221
+ this.div.style.left = `${x}px`
190
222
  }
191
223
  }
192
224
 
@@ -210,7 +242,11 @@ export class ClusterIcon {
210
242
 
211
243
  const pos = this.getPosFromLatLng(this.center)
212
244
 
213
- if (this.sums === null || typeof this.sums.title === 'undefined' || this.sums.title === '') {
245
+ if (
246
+ this.sums === null ||
247
+ typeof this.sums.title === 'undefined' ||
248
+ this.sums.title === ''
249
+ ) {
214
250
  divTitle = this.cluster.getClusterer().getTitle()
215
251
  } else {
216
252
  divTitle = this.sums.title
@@ -231,10 +267,13 @@ export class ClusterIcon {
231
267
  img.style.left = `${spriteH}px`
232
268
 
233
269
  if (!this.cluster.getClusterer().enableRetinaIcons) {
234
- img.style.clip = `rect(-${spriteV}px, -${spriteH + this.width}px, -${spriteV + this.height}, -${spriteH})`
270
+ img.style.clip = `rect(-${spriteV}px, -${spriteH + this.width}px, -${
271
+ spriteV + this.height
272
+ }, -${spriteH})`
235
273
  }
236
274
 
237
275
  const textElm = document.createElement('div')
276
+
238
277
  textElm.style.position = 'absolute'
239
278
  textElm.style.top = `${this.anchorText[0]}px`
240
279
  textElm.style.left = `${this.anchorText[1]}px`
@@ -250,9 +289,12 @@ export class ClusterIcon {
250
289
  textElm.innerText = `${this.sums?.text}`
251
290
 
252
291
  this.div.innerHTML = ''
292
+
253
293
  this.div.appendChild(img)
254
294
  this.div.appendChild(textElm)
295
+
255
296
  this.div.title = divTitle
297
+
256
298
  this.div.style.display = ''
257
299
  }
258
300
 
@@ -261,14 +303,18 @@ export class ClusterIcon {
261
303
 
262
304
  useStyle(sums: ClusterIconInfo) {
263
305
  this.sums = sums
306
+
264
307
  const styles = this.cluster.getClusterer().getStyles()
265
- const style = styles[Math.min(styles.length - 1, Math.max(0, sums.index - 1))]
308
+
309
+ const style =
310
+ styles[Math.min(styles.length - 1, Math.max(0, sums.index - 1))]
266
311
 
267
312
  this.url = style.url
268
313
  this.height = style.height
269
314
  this.width = style.width
270
315
 
271
- if (style.className) this.className = `${this.clusterClassName} ${style.className}`
316
+ if (style.className)
317
+ this.className = `${this.clusterClassName} ${style.className}`
272
318
 
273
319
  this.anchorText = style.anchorText || [0, 0]
274
320
  this.anchorIcon = style.anchorIcon || [this.height / 2, this.width / 2]
@@ -300,10 +346,6 @@ export class ClusterIcon {
300
346
 
301
347
  pos.y -= this.anchorIcon[0]
302
348
 
303
- // pos.x = pos.x
304
-
305
- // pos.y = pos.y
306
-
307
349
  return pos
308
350
  }
309
351
  }