UNPKG

@react-google-maps/marker-clusterer

Version:
996 lines (990 loc) 46.1 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.markerClusterer = {})); })(this, (function (exports) { 'use strict'; var ClusterIcon = /** @class */ (function () { function ClusterIcon(cluster, styles) { cluster.getClusterer().extend(ClusterIcon, google.maps.OverlayView); this.cluster = cluster; this.clusterClassName = this.cluster.getClusterer().getClusterClass(); this.className = this.clusterClassName; this.styles = styles; this.center = undefined; this.div = null; this.sums = null; this.visible = false; this.boundsChangedListener = null; this.url = ''; this.height = 0; this.width = 0; this.anchorText = [0, 0]; this.anchorIcon = [0, 0]; this.textColor = 'black'; this.textSize = 11; this.textDecoration = 'none'; this.fontWeight = 'bold'; this.fontStyle = 'normal'; this.fontFamily = 'Arial,sans-serif'; this.backgroundPosition = '0 0'; this.cMouseDownInCluster = null; this.cDraggingMapByCluster = null; this.timeOut = null; this.setMap(cluster.getMap()); // Note: this causes onAdd to be called this.onBoundsChanged = this.onBoundsChanged.bind(this); this.onMouseDown = this.onMouseDown.bind(this); this.onClick = this.onClick.bind(this); this.onMouseOver = this.onMouseOver.bind(this); this.onMouseOut = this.onMouseOut.bind(this); this.onAdd = this.onAdd.bind(this); this.onRemove = this.onRemove.bind(this); this.draw = this.draw.bind(this); this.hide = this.hide.bind(this); this.show = this.show.bind(this); this.useStyle = this.useStyle.bind(this); this.setCenter = this.setCenter.bind(this); this.getPosFromLatLng = this.getPosFromLatLng.bind(this); } ClusterIcon.prototype.onBoundsChanged = function () { this.cDraggingMapByCluster = this.cMouseDownInCluster; }; ClusterIcon.prototype.onMouseDown = function () { this.cMouseDownInCluster = true; this.cDraggingMapByCluster = false; }; ClusterIcon.prototype.onClick = function (event) { this.cMouseDownInCluster = false; if (!this.cDraggingMapByCluster) { var markerClusterer_1 = this.cluster.getClusterer(); /** * This event is fired when a cluster marker is clicked. * @name MarkerClusterer#click * @param {Cluster} c The cluster that was clicked. * @event */ google.maps.event.trigger(markerClusterer_1, 'click', this.cluster); google.maps.event.trigger(markerClusterer_1, 'clusterclick', this.cluster); // deprecated name // The default click handler follows. Disable it by setting // the zoomOnClick property to false. if (markerClusterer_1.getZoomOnClick()) { // Zoom into the cluster. var maxZoom_1 = markerClusterer_1.getMaxZoom(); var bounds_1 = this.cluster.getBounds(); var map = markerClusterer_1.getMap(); if (map !== null && 'fitBounds' in map) { map.fitBounds(bounds_1); } // There is a fix for Issue 170 here: this.timeOut = window.setTimeout(function () { var map = markerClusterer_1.getMap(); if (map !== null) { if ('fitBounds' in map) { map.fitBounds(bounds_1); } var zoom = map.getZoom() || 0; // Don't zoom beyond the max zoom level if (maxZoom_1 !== null && zoom > maxZoom_1) { map.setZoom(maxZoom_1 + 1); } } }, 100); } // Prevent event propagation to the map: event.cancelBubble = true; if (event.stopPropagation) { event.stopPropagation(); } } }; ClusterIcon.prototype.onMouseOver = function () { /** * This event is fired when the mouse moves over a cluster marker. * @name MarkerClusterer#mouseover * @param {Cluster} c The cluster that the mouse moved over. * @event */ google.maps.event.trigger(this.cluster.getClusterer(), 'mouseover', this.cluster); }; ClusterIcon.prototype.onMouseOut = function () { /** * This event is fired when the mouse moves out of a cluster marker. * @name MarkerClusterer#mouseout * @param {Cluster} c The cluster that the mouse moved out of. * @event */ google.maps.event.trigger(this.cluster.getClusterer(), 'mouseout', this.cluster); }; ClusterIcon.prototype.onAdd = function () { var _a; this.div = document.createElement('div'); this.div.className = this.className; if (this.visible) { this.show(); } (_a = this.getPanes()) === null || _a === void 0 ? void 0 : _a.overlayMouseTarget.appendChild(this.div); var map = this.getMap(); if (map !== null) { // Fix for Issue 157 this.boundsChangedListener = google.maps.event.addListener(map, 'bounds_changed', this.onBoundsChanged); this.div.addEventListener('mousedown', this.onMouseDown); this.div.addEventListener('click', this.onClick); this.div.addEventListener('mouseover', this.onMouseOver); this.div.addEventListener('mouseout', this.onMouseOut); } }; ClusterIcon.prototype.onRemove = function () { if (this.div && this.div.parentNode) { this.hide(); if (this.boundsChangedListener !== null) { google.maps.event.removeListener(this.boundsChangedListener); } this.div.removeEventListener('mousedown', this.onMouseDown); this.div.removeEventListener('click', this.onClick); this.div.removeEventListener('mouseover', this.onMouseOver); this.div.removeEventListener('mouseout', this.onMouseOut); this.div.parentNode.removeChild(this.div); if (this.timeOut !== null) { window.clearTimeout(this.timeOut); this.timeOut = null; } this.div = null; } }; ClusterIcon.prototype.draw = function () { if (this.visible && this.div !== null && this.center) { var pos = this.getPosFromLatLng(this.center); this.div.style.top = pos !== null ? "".concat(pos.y, "px") : '0'; this.div.style.left = pos !== null ? "".concat(pos.x, "px") : '0'; } }; ClusterIcon.prototype.hide = function () { if (this.div) { this.div.style.display = 'none'; } this.visible = false; }; ClusterIcon.prototype.show = function () { var _a, _b, _c, _d, _e, _f; if (this.div && this.center) { var divTitle = this.sums === null || typeof this.sums.title === 'undefined' || this.sums.title === '' ? this.cluster.getClusterer().getTitle() : this.sums.title; // NOTE: values must be specified in px units var bp = this.backgroundPosition.split(' '); var spriteH = parseInt(((_a = bp[0]) === null || _a === void 0 ? void 0 : _a.replace(/^\s+|\s+$/g, '')) || '0', 10); var spriteV = parseInt(((_b = bp[1]) === null || _b === void 0 ? void 0 : _b.replace(/^\s+|\s+$/g, '')) || '0', 10); var pos = this.getPosFromLatLng(this.center); this.div.className = this.className; this.div.setAttribute('style', "cursor: pointer; position: absolute; top: ".concat(pos !== null ? "".concat(pos.y, "px") : '0', "; left: ").concat(pos !== null ? "".concat(pos.x, "px") : '0', "; width: ").concat(this.width, "px; height: ").concat(this.height, "px; ")); var img = document.createElement('img'); img.alt = divTitle; img.src = this.url; img.width = this.width; img.height = this.height; img.setAttribute('style', "position: absolute; top: ".concat(spriteV, "px; left: ").concat(spriteH, "px")); if (!this.cluster.getClusterer().enableRetinaIcons) { img.style.clip = "rect(-".concat(spriteV, "px, -").concat(spriteH + this.width, "px, -").concat(spriteV + this.height, ", -").concat(spriteH, ")"); } var textElm = document.createElement('div'); textElm.setAttribute('style', "position: absolute; top: ".concat(this.anchorText[0], "px; left: ").concat(this.anchorText[1], "px; color: ").concat(this.textColor, "; font-size: ").concat(this.textSize, "px; font-family: ").concat(this.fontFamily, "; font-weight: ").concat(this.fontWeight, "; fontStyle: ").concat(this.fontStyle, "; text-decoration: ").concat(this.textDecoration, "; text-align: center; width: ").concat(this.width, "px; line-height: ").concat(this.height, "px")); if ((_c = this.sums) === null || _c === void 0 ? void 0 : _c.text) textElm.innerText = "".concat((_d = this.sums) === null || _d === void 0 ? void 0 : _d.text); if ((_e = this.sums) === null || _e === void 0 ? void 0 : _e.html) textElm.innerHTML = "".concat((_f = this.sums) === null || _f === void 0 ? void 0 : _f.html); this.div.innerHTML = ''; this.div.appendChild(img); this.div.appendChild(textElm); this.div.title = divTitle; this.div.style.display = ''; } this.visible = true; }; ClusterIcon.prototype.useStyle = function (sums) { this.sums = sums; var styles = this.cluster.getClusterer().getStyles(); var style = styles[Math.min(styles.length - 1, Math.max(0, sums.index - 1))]; if (style) { this.url = style.url; this.height = style.height; this.width = style.width; if (style.className) { this.className = "".concat(this.clusterClassName, " ").concat(style.className); } this.anchorText = style.anchorText || [0, 0]; this.anchorIcon = style.anchorIcon || [this.height / 2, this.width / 2]; this.textColor = style.textColor || 'black'; this.textSize = style.textSize || 11; this.textDecoration = style.textDecoration || 'none'; this.fontWeight = style.fontWeight || 'bold'; this.fontStyle = style.fontStyle || 'normal'; this.fontFamily = style.fontFamily || 'Arial,sans-serif'; this.backgroundPosition = style.backgroundPosition || '0 0'; } }; ClusterIcon.prototype.setCenter = function (center) { this.center = center; }; ClusterIcon.prototype.getPosFromLatLng = function (latlng) { var pos = this.getProjection().fromLatLngToDivPixel(latlng); if (pos !== null) { pos.x -= this.anchorIcon[1]; pos.y -= this.anchorIcon[0]; } return pos; }; return ClusterIcon; }()); /* global google */ var Cluster = /** @class */ (function () { function Cluster(markerClusterer) { this.markerClusterer = markerClusterer; this.map = this.markerClusterer.getMap(); this.gridSize = this.markerClusterer.getGridSize(); this.minClusterSize = this.markerClusterer.getMinimumClusterSize(); this.averageCenter = this.markerClusterer.getAverageCenter(); this.markers = []; this.center = undefined; this.bounds = null; this.clusterIcon = new ClusterIcon(this, this.markerClusterer.getStyles()); this.getSize = this.getSize.bind(this); this.getMarkers = this.getMarkers.bind(this); this.getCenter = this.getCenter.bind(this); this.getMap = this.getMap.bind(this); this.getClusterer = this.getClusterer.bind(this); this.getBounds = this.getBounds.bind(this); this.remove = this.remove.bind(this); this.addMarker = this.addMarker.bind(this); this.isMarkerInClusterBounds = this.isMarkerInClusterBounds.bind(this); this.calculateBounds = this.calculateBounds.bind(this); this.updateIcon = this.updateIcon.bind(this); this.isMarkerAlreadyAdded = this.isMarkerAlreadyAdded.bind(this); } Cluster.prototype.getSize = function () { return this.markers.length; }; Cluster.prototype.getMarkers = function () { return this.markers; }; Cluster.prototype.getCenter = function () { return this.center; }; Cluster.prototype.getMap = function () { return this.map; }; Cluster.prototype.getClusterer = function () { return this.markerClusterer; }; Cluster.prototype.getBounds = function () { var bounds = new google.maps.LatLngBounds(this.center, this.center); var markers = this.getMarkers(); for (var _i = 0, markers_1 = markers; _i < markers_1.length; _i++) { var marker = markers_1[_i]; var position = marker.getPosition(); if (position) { bounds.extend(position); } } return bounds; }; Cluster.prototype.remove = function () { this.clusterIcon.setMap(null); this.markers = []; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore delete this.markers; }; Cluster.prototype.addMarker = function (marker) { var _a; if (this.isMarkerAlreadyAdded(marker)) { return false; } if (!this.center) { var position = marker.getPosition(); if (position) { this.center = position; this.calculateBounds(); } } else { if (this.averageCenter) { var position = marker.getPosition(); if (position) { var length_1 = this.markers.length + 1; this.center = new google.maps.LatLng((this.center.lat() * (length_1 - 1) + position.lat()) / length_1, (this.center.lng() * (length_1 - 1) + position.lng()) / length_1); this.calculateBounds(); } } } marker.isAdded = true; this.markers.push(marker); var mCount = this.markers.length; var maxZoom = this.markerClusterer.getMaxZoom(); var zoom = (_a = this.map) === null || _a === void 0 ? void 0 : _a.getZoom(); if (maxZoom !== null && typeof zoom !== 'undefined' && zoom > maxZoom) { // Zoomed in past max zoom, so show the marker. if (marker.getMap() !== this.map) { marker.setMap(this.map); } } else if (mCount < this.minClusterSize) { // Min cluster size not reached so show the marker. if (marker.getMap() !== this.map) { marker.setMap(this.map); } } else if (mCount === this.minClusterSize) { // Hide the markers that were showing. for (var _i = 0, _b = this.markers; _i < _b.length; _i++) { var markerElement = _b[_i]; markerElement.setMap(null); } } else { marker.setMap(null); } return true; }; Cluster.prototype.isMarkerInClusterBounds = function (marker) { if (this.bounds !== null) { var position = marker.getPosition(); if (position) { return this.bounds.contains(position); } } return false; }; Cluster.prototype.calculateBounds = function () { this.bounds = this.markerClusterer.getExtendedBounds(new google.maps.LatLngBounds(this.center, this.center)); }; Cluster.prototype.updateIcon = function () { var _a; var mCount = this.markers.length; var maxZoom = this.markerClusterer.getMaxZoom(); var zoom = (_a = this.map) === null || _a === void 0 ? void 0 : _a.getZoom(); if (maxZoom !== null && typeof zoom !== 'undefined' && zoom > maxZoom) { this.clusterIcon.hide(); return; } if (mCount < this.minClusterSize) { // Min cluster size not yet reached. this.clusterIcon.hide(); return; } if (this.center) { this.clusterIcon.setCenter(this.center); } this.clusterIcon.useStyle(this.markerClusterer.getCalculator()(this.markers, this.markerClusterer.getStyles().length)); this.clusterIcon.show(); }; Cluster.prototype.isMarkerAlreadyAdded = function (marker) { if (this.markers.includes) { return this.markers.includes(marker); } for (var i = 0; i < this.markers.length; i++) { if (marker === this.markers[i]) { return true; } } return false; }; return Cluster; }()); /* global google */ /* eslint-disable filenames/match-regex */ /** * Supports up to 9007199254740991 (Number.MAX_SAFE_INTEGER) markers * which is not a problem as max array length is 4294967296 (2**32) */ function CALCULATOR(markers, numStyles) { var count = markers.length; var numberOfDigits = count.toString().length; var index = Math.min(numberOfDigits, numStyles); return { text: count.toString(), index: index, title: '', }; } var BATCH_SIZE = 2000; var BATCH_SIZE_IE = 500; var IMAGE_PATH = 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'; var IMAGE_EXTENSION = 'png'; var IMAGE_SIZES = [53, 56, 66, 78, 90]; var CLUSTERER_CLASS = 'cluster'; var Clusterer = /** @class */ (function () { function Clusterer(map, optMarkers, optOptions) { if (optMarkers === void 0) { optMarkers = []; } if (optOptions === void 0) { optOptions = {}; } this.getMinimumClusterSize = this.getMinimumClusterSize.bind(this); this.setMinimumClusterSize = this.setMinimumClusterSize.bind(this); this.getEnableRetinaIcons = this.getEnableRetinaIcons.bind(this); this.setEnableRetinaIcons = this.setEnableRetinaIcons.bind(this); this.addToClosestCluster = this.addToClosestCluster.bind(this); this.getImageExtension = this.getImageExtension.bind(this); this.setImageExtension = this.setImageExtension.bind(this); this.getExtendedBounds = this.getExtendedBounds.bind(this); this.getAverageCenter = this.getAverageCenter.bind(this); this.setAverageCenter = this.setAverageCenter.bind(this); this.getTotalClusters = this.getTotalClusters.bind(this); this.fitMapToMarkers = this.fitMapToMarkers.bind(this); this.getIgnoreHidden = this.getIgnoreHidden.bind(this); this.setIgnoreHidden = this.setIgnoreHidden.bind(this); this.getClusterClass = this.getClusterClass.bind(this); this.setClusterClass = this.setClusterClass.bind(this); this.getTotalMarkers = this.getTotalMarkers.bind(this); this.getZoomOnClick = this.getZoomOnClick.bind(this); this.setZoomOnClick = this.setZoomOnClick.bind(this); this.getBatchSizeIE = this.getBatchSizeIE.bind(this); this.setBatchSizeIE = this.setBatchSizeIE.bind(this); this.createClusters = this.createClusters.bind(this); this.onZoomChanged = this.onZoomChanged.bind(this); this.getImageSizes = this.getImageSizes.bind(this); this.setImageSizes = this.setImageSizes.bind(this); this.getCalculator = this.getCalculator.bind(this); this.setCalculator = this.setCalculator.bind(this); this.removeMarkers = this.removeMarkers.bind(this); this.resetViewport = this.resetViewport.bind(this); this.getImagePath = this.getImagePath.bind(this); this.setImagePath = this.setImagePath.bind(this); this.pushMarkerTo = this.pushMarkerTo.bind(this); this.removeMarker = this.removeMarker.bind(this); this.clearMarkers = this.clearMarkers.bind(this); this.setupStyles = this.setupStyles.bind(this); this.getGridSize = this.getGridSize.bind(this); this.setGridSize = this.setGridSize.bind(this); this.getClusters = this.getClusters.bind(this); this.getMaxZoom = this.getMaxZoom.bind(this); this.setMaxZoom = this.setMaxZoom.bind(this); this.getMarkers = this.getMarkers.bind(this); this.addMarkers = this.addMarkers.bind(this); this.getStyles = this.getStyles.bind(this); this.setStyles = this.setStyles.bind(this); this.addMarker = this.addMarker.bind(this); this.onRemove = this.onRemove.bind(this); this.getTitle = this.getTitle.bind(this); this.setTitle = this.setTitle.bind(this); this.repaint = this.repaint.bind(this); this.onIdle = this.onIdle.bind(this); this.redraw = this.redraw.bind(this); this.onAdd = this.onAdd.bind(this); this.draw = this.draw.bind(this); this.extend = this.extend.bind(this); this.extend(Clusterer, google.maps.OverlayView); this.markers = []; this.clusters = []; this.listeners = []; this.activeMap = null; this.ready = false; this.gridSize = optOptions.gridSize || 60; this.minClusterSize = optOptions.minimumClusterSize || 2; this.maxZoom = optOptions.maxZoom || null; this.styles = optOptions.styles || []; this.title = optOptions.title || ''; this.zoomOnClick = true; if (optOptions.zoomOnClick !== undefined) { this.zoomOnClick = optOptions.zoomOnClick; } this.averageCenter = false; if (optOptions.averageCenter !== undefined) { this.averageCenter = optOptions.averageCenter; } this.ignoreHidden = false; if (optOptions.ignoreHidden !== undefined) { this.ignoreHidden = optOptions.ignoreHidden; } this.enableRetinaIcons = false; if (optOptions.enableRetinaIcons !== undefined) { this.enableRetinaIcons = optOptions.enableRetinaIcons; } this.imagePath = optOptions.imagePath || IMAGE_PATH; this.imageExtension = optOptions.imageExtension || IMAGE_EXTENSION; this.imageSizes = optOptions.imageSizes || IMAGE_SIZES; this.calculator = optOptions.calculator || CALCULATOR; this.batchSize = optOptions.batchSize || BATCH_SIZE; this.batchSizeIE = optOptions.batchSizeIE || BATCH_SIZE_IE; this.clusterClass = optOptions.clusterClass || CLUSTERER_CLASS; if (navigator.userAgent.toLowerCase().indexOf('msie') !== -1) { // Try to avoid IE timeout when processing a huge number of markers: this.batchSize = this.batchSizeIE; } this.timerRefStatic = null; this.setupStyles(); this.addMarkers(optMarkers, true); this.setMap(map); // Note: this causes onAdd to be called } Clusterer.prototype.onZoomChanged = function () { var _a, _b; this.resetViewport(false); // Workaround for this Google bug: when map is at level 0 and "-" of // zoom slider is clicked, a "zoom_changed" event is fired even though // the map doesn't zoom out any further. In this situation, no "idle" // event is triggered so the cluster markers that have been removed // do not get redrawn. Same goes for a zoom in at maxZoom. if (((_a = this.getMap()) === null || _a === void 0 ? void 0 : _a.getZoom()) === (this.get('minZoom') || 0) || ((_b = this.getMap()) === null || _b === void 0 ? void 0 : _b.getZoom()) === this.get('maxZoom')) { google.maps.event.trigger(this, 'idle'); } }; Clusterer.prototype.onIdle = function () { this.redraw(); }; Clusterer.prototype.onAdd = function () { var map = this.getMap(); this.activeMap = map; this.ready = true; this.repaint(); if (map !== null) { // Add the map event listeners this.listeners = [ google.maps.event.addListener(map, 'zoom_changed', this.onZoomChanged), google.maps.event.addListener(map, 'idle', this.onIdle), ]; } }; Clusterer.prototype.onRemove = function () { // Put all the managed markers back on the map: for (var _i = 0, _a = this.markers; _i < _a.length; _i++) { var marker = _a[_i]; if (marker.getMap() !== this.activeMap) { marker.setMap(this.activeMap); } } // Remove all clusters: for (var _b = 0, _c = this.clusters; _b < _c.length; _b++) { var cluster = _c[_b]; cluster.remove(); } this.clusters = []; // Remove map event listeners: for (var _d = 0, _e = this.listeners; _d < _e.length; _d++) { var listener = _e[_d]; google.maps.event.removeListener(listener); } this.listeners = []; this.activeMap = null; this.ready = false; }; Clusterer.prototype.draw = function () { return; }; Clusterer.prototype.getMap = function () { return null; }; Clusterer.prototype.getPanes = function () { return null; }; Clusterer.prototype.getProjection = function () { return { fromContainerPixelToLatLng: function () { return null; }, fromDivPixelToLatLng: function () { return null; }, fromLatLngToContainerPixel: function () { return null; }, fromLatLngToDivPixel: function () { return null; }, getVisibleRegion: function () { return null; }, getWorldWidth: function () { return 0; } }; }; Clusterer.prototype.setMap = function () { return; }; Clusterer.prototype.addListener = function () { return { remove: function () { return; } }; }; Clusterer.prototype.bindTo = function () { return; }; Clusterer.prototype.get = function () { return; }; Clusterer.prototype.notify = function () { return; }; Clusterer.prototype.set = function () { return; }; Clusterer.prototype.setValues = function () { return; }; Clusterer.prototype.unbind = function () { return; }; Clusterer.prototype.unbindAll = function () { return; }; Clusterer.prototype.setupStyles = function () { if (this.styles.length > 0) { return; } for (var i = 0; i < this.imageSizes.length; i++) { this.styles.push({ url: "".concat(this.imagePath + (i + 1), ".").concat(this.imageExtension), height: this.imageSizes[i] || 0, width: this.imageSizes[i] || 0, }); } }; Clusterer.prototype.fitMapToMarkers = function () { var markers = this.getMarkers(); var bounds = new google.maps.LatLngBounds(); for (var _i = 0, markers_1 = markers; _i < markers_1.length; _i++) { var marker = markers_1[_i]; var position = marker.getPosition(); if (position) { bounds.extend(position); } } var map = this.getMap(); if (map !== null && 'fitBounds' in map) { map.fitBounds(bounds); } }; Clusterer.prototype.getGridSize = function () { return this.gridSize; }; Clusterer.prototype.setGridSize = function (gridSize) { this.gridSize = gridSize; }; Clusterer.prototype.getMinimumClusterSize = function () { return this.minClusterSize; }; Clusterer.prototype.setMinimumClusterSize = function (minimumClusterSize) { this.minClusterSize = minimumClusterSize; }; Clusterer.prototype.getMaxZoom = function () { return this.maxZoom; }; Clusterer.prototype.setMaxZoom = function (maxZoom) { this.maxZoom = maxZoom; }; Clusterer.prototype.getStyles = function () { return this.styles; }; Clusterer.prototype.setStyles = function (styles) { this.styles = styles; }; Clusterer.prototype.getTitle = function () { return this.title; }; Clusterer.prototype.setTitle = function (title) { this.title = title; }; Clusterer.prototype.getZoomOnClick = function () { return this.zoomOnClick; }; Clusterer.prototype.setZoomOnClick = function (zoomOnClick) { this.zoomOnClick = zoomOnClick; }; Clusterer.prototype.getAverageCenter = function () { return this.averageCenter; }; Clusterer.prototype.setAverageCenter = function (averageCenter) { this.averageCenter = averageCenter; }; Clusterer.prototype.getIgnoreHidden = function () { return this.ignoreHidden; }; Clusterer.prototype.setIgnoreHidden = function (ignoreHidden) { this.ignoreHidden = ignoreHidden; }; Clusterer.prototype.getEnableRetinaIcons = function () { return this.enableRetinaIcons; }; Clusterer.prototype.setEnableRetinaIcons = function (enableRetinaIcons) { this.enableRetinaIcons = enableRetinaIcons; }; Clusterer.prototype.getImageExtension = function () { return this.imageExtension; }; Clusterer.prototype.setImageExtension = function (imageExtension) { this.imageExtension = imageExtension; }; Clusterer.prototype.getImagePath = function () { return this.imagePath; }; Clusterer.prototype.setImagePath = function (imagePath) { this.imagePath = imagePath; }; Clusterer.prototype.getImageSizes = function () { return this.imageSizes; }; Clusterer.prototype.setImageSizes = function (imageSizes) { this.imageSizes = imageSizes; }; Clusterer.prototype.getCalculator = function () { return this.calculator; }; Clusterer.prototype.setCalculator = function (calculator) { this.calculator = calculator; }; Clusterer.prototype.getBatchSizeIE = function () { return this.batchSizeIE; }; Clusterer.prototype.setBatchSizeIE = function (batchSizeIE) { this.batchSizeIE = batchSizeIE; }; Clusterer.prototype.getClusterClass = function () { return this.clusterClass; }; Clusterer.prototype.setClusterClass = function (clusterClass) { this.clusterClass = clusterClass; }; Clusterer.prototype.getMarkers = function () { return this.markers; }; Clusterer.prototype.getTotalMarkers = function () { return this.markers.length; }; Clusterer.prototype.getClusters = function () { return this.clusters; }; Clusterer.prototype.getTotalClusters = function () { return this.clusters.length; }; Clusterer.prototype.addMarker = function (marker, optNoDraw) { this.pushMarkerTo(marker); if (!optNoDraw) { this.redraw(); } }; Clusterer.prototype.addMarkers = function (markers, optNoDraw) { for (var key in markers) { if (Object.prototype.hasOwnProperty.call(markers, key)) { var marker = markers[key]; if (marker) { this.pushMarkerTo(marker); } } } if (!optNoDraw) { this.redraw(); } }; Clusterer.prototype.pushMarkerTo = function (marker) { var _this = this; // If the marker is draggable add a listener so we can update the clusters on the dragend: if (marker.getDraggable()) { google.maps.event.addListener(marker, 'dragend', function () { if (_this.ready) { marker.isAdded = false; _this.repaint(); } }); } marker.isAdded = false; this.markers.push(marker); }; Clusterer.prototype.removeMarker_ = function (marker) { var index = -1; if (this.markers.indexOf) { index = this.markers.indexOf(marker); } else { for (var i = 0; i < this.markers.length; i++) { if (marker === this.markers[i]) { index = i; break; } } } if (index === -1) { // Marker is not in our list of markers, so do nothing: return false; } marker.setMap(null); this.markers.splice(index, 1); // Remove the marker from the list of managed markers return true; }; Clusterer.prototype.removeMarker = function (marker, optNoDraw) { var removed = this.removeMarker_(marker); if (!optNoDraw && removed) { this.repaint(); } return removed; }; Clusterer.prototype.removeMarkers = function (markers, optNoDraw) { var removed = false; for (var _i = 0, markers_2 = markers; _i < markers_2.length; _i++) { var marker = markers_2[_i]; removed = removed || this.removeMarker_(marker); } if (!optNoDraw && removed) { this.repaint(); } return removed; }; Clusterer.prototype.clearMarkers = function () { this.resetViewport(true); this.markers = []; }; Clusterer.prototype.repaint = function () { var oldClusters = this.clusters.slice(); this.clusters = []; this.resetViewport(false); this.redraw(); // Remove the old clusters. // Do it in a timeout to prevent blinking effect. setTimeout(function timeout() { for (var _i = 0, oldClusters_1 = oldClusters; _i < oldClusters_1.length; _i++) { var oldCluster = oldClusters_1[_i]; oldCluster.remove(); } }, 0); }; Clusterer.prototype.getExtendedBounds = function (bounds) { var projection = this.getProjection(); // Convert the points to pixels and the extend out by the grid size. var trPix = projection.fromLatLngToDivPixel( // Turn the bounds into latlng. new google.maps.LatLng(bounds.getNorthEast().lat(), bounds.getNorthEast().lng())); if (trPix !== null) { trPix.x += this.gridSize; trPix.y -= this.gridSize; } var blPix = projection.fromLatLngToDivPixel( // Turn the bounds into latlng. new google.maps.LatLng(bounds.getSouthWest().lat(), bounds.getSouthWest().lng())); if (blPix !== null) { blPix.x -= this.gridSize; blPix.y += this.gridSize; } // Extend the bounds to contain the new bounds. if (trPix !== null) { // Convert the pixel points back to LatLng nw var point1 = projection.fromDivPixelToLatLng(trPix); if (point1 !== null) { bounds.extend(point1); } } if (blPix !== null) { // Convert the pixel points back to LatLng sw var point2 = projection.fromDivPixelToLatLng(blPix); if (point2 !== null) { bounds.extend(point2); } } return bounds; }; Clusterer.prototype.redraw = function () { // Redraws all the clusters. this.createClusters(0); }; Clusterer.prototype.resetViewport = function (optHide) { // Remove all the clusters for (var _i = 0, _a = this.clusters; _i < _a.length; _i++) { var cluster = _a[_i]; cluster.remove(); } this.clusters = []; // Reset the markers to not be added and to be removed from the map. for (var _b = 0, _c = this.markers; _b < _c.length; _b++) { var marker = _c[_b]; marker.isAdded = false; if (optHide) { marker.setMap(null); } } }; Clusterer.prototype.distanceBetweenPoints = function (p1, p2) { var R = 6371; // Radius of the Earth in km var dLat = ((p2.lat() - p1.lat()) * Math.PI) / 180; var dLon = ((p2.lng() - p1.lng()) * Math.PI) / 180; var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos((p1.lat() * Math.PI) / 180) * Math.cos((p2.lat() * Math.PI) / 180) * Math.sin(dLon / 2) * Math.sin(dLon / 2); return R * (2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))); }; Clusterer.prototype.isMarkerInBounds = function (marker, bounds) { var position = marker.getPosition(); if (position) { return bounds.contains(position); } return false; }; Clusterer.prototype.addToClosestCluster = function (marker) { var cluster; var distance = 40000; // Some large number var clusterToAddTo = null; for (var _i = 0, _a = this.clusters; _i < _a.length; _i++) { var clusterElement = _a[_i]; cluster = clusterElement; var center = cluster.getCenter(); var position = marker.getPosition(); if (center && position) { var d = this.distanceBetweenPoints(center, position); if (d < distance) { distance = d; clusterToAddTo = cluster; } } } if (clusterToAddTo && clusterToAddTo.isMarkerInClusterBounds(marker)) { clusterToAddTo.addMarker(marker); } else { cluster = new Cluster(this); cluster.addMarker(marker); this.clusters.push(cluster); } }; Clusterer.prototype.createClusters = function (iFirst) { var _this = this; if (!this.ready) { return; } // Cancel previous batch processing if we're working on the first batch: if (iFirst === 0) { /** * This event is fired when the <code>Clusterer</code> begins * clustering markers. * @name Clusterer#clusteringbegin * @param {Clusterer} mc The Clusterer whose markers are being clustered. * @event */ google.maps.event.trigger(this, 'clusteringbegin', this); if (this.timerRefStatic !== null) { window.clearTimeout(this.timerRefStatic); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore delete this.timerRefStatic; } } var map = this.getMap(); var bounds = map !== null && 'getBounds' in map ? map.getBounds() : null; var zoom = (map === null || map === void 0 ? void 0 : map.getZoom()) || 0; // Get our current map view bounds. // Create a new bounds object so we don't affect the map. // // See Comments 9 & 11 on Issue 3651 relating to this workaround for a Google Maps bug: var mapBounds = zoom > 3 ? new google.maps.LatLngBounds(bounds === null || bounds === void 0 ? void 0 : bounds.getSouthWest(), bounds === null || bounds === void 0 ? void 0 : bounds.getNorthEast()) : new google.maps.LatLngBounds(new google.maps.LatLng(85.02070771743472, -178.48388434375), new google.maps.LatLng(-85.08136444384544, 178.00048865625)); var extendedMapBounds = this.getExtendedBounds(mapBounds); var iLast = Math.min(iFirst + this.batchSize, this.markers.length); for (var i = iFirst; i < iLast; i++) { var marker = this.markers[i]; if (marker && !marker.isAdded && this.isMarkerInBounds(marker, extendedMapBounds) && (!this.ignoreHidden || (this.ignoreHidden && marker.getVisible()))) { this.addToClosestCluster(marker); } } if (iLast < this.markers.length) { this.timerRefStatic = window.setTimeout(function () { _this.createClusters(iLast); }, 0); } else { this.timerRefStatic = null; /** * This event is fired when the <code>Clusterer</code> stops * clustering markers. * @name Clusterer#clusteringend * @param {Clusterer} mc The Clusterer whose markers are being clustered. * @event */ google.maps.event.trigger(this, 'clusteringend', this); for (var _i = 0, _a = this.clusters; _i < _a.length; _i++) { var cluster = _a[_i]; cluster.updateIcon(); } } }; Clusterer.prototype.extend = function (obj1, obj2) { return function applyExtend(object) { for (var property in object.prototype) { // eslint-disable-next-line @typescript-eslint/ban-types var prop = property; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore this.prototype[prop] = object.prototype[prop]; } return this; }.apply(obj1, [obj2]); }; return Clusterer; }()); exports.Cluster = Cluster; exports.ClusterIcon = ClusterIcon; exports.Clusterer = Clusterer; })); //# sourceMappingURL=umd.js.map