JAVASCRIPT   70

MarkerClusterer

Guest on 29th June 2022 01:56:11 PM

  1. function MarkerClusterer(t, e, r) {
  2.     this.extend(MarkerClusterer, google.maps.OverlayView), this.map_ = t, this.markers_ = [], this.clusters_ = [], this.sizes = [53, 56, 66, 78, 90], this.styles_ = [], this.ready_ = !1;
  3.     var s = r || {};
  4.     this.gridSize_ = s.gridSize || 60, this.minClusterSize_ = s.minimumClusterSize || 2, this.maxZoom_ = s.maxZoom || null, this.styles_ = s.styles || [], this.imagePath_ = s.imagePath || this.MARKER_CLUSTER_IMAGE_PATH_, this.imageExtension_ = s.imageExtension || this.MARKER_CLUSTER_IMAGE_EXTENSION_, this.zoomOnClick_ = !0, void 0 != s.zoomOnClick && (this.zoomOnClick_ = s.zoomOnClick), this.averageCenter_ = !1, void 0 != s.averageCenter && (this.averageCenter_ = s.averageCenter), this.setupStyles_(), this.setMap(t), this.prevZoom_ = this.map_.getZoom();
  5.     var o = this;
  6.     google.maps.event.addListener(this.map_, "zoom_changed", function() {
  7.         var t = o.map_.getZoom();
  8.         o.prevZoom_ != t && (o.prevZoom_ = t, o.resetViewport())
  9.     }), google.maps.event.addListener(this.map_, "idle", function() {
  10.         o.redraw()
  11.     }), e && e.length && this.addMarkers(e, !1)
  12. }
  13.  
  14. function Cluster(t) {
  15.     this.markerClusterer_ = t, this.map_ = t.getMap(), this.gridSize_ = t.getGridSize(), this.minClusterSize_ = t.getMinClusterSize(), this.averageCenter_ = t.isAverageCenter(), this.center_ = null, this.markers_ = [], this.bounds_ = null, this.clusterIcon_ = new ClusterIcon(this, t.getStyles(), t.getGridSize())
  16. }
  17.  
  18. function ClusterIcon(t, e, r) {
  19.     t.getMarkerClusterer().extend(ClusterIcon, google.maps.OverlayView), this.styles_ = e, this.padding_ = r || 0, this.cluster_ = t, this.center_ = null, this.map_ = t.getMap(), this.div_ = null, this.sums_ = null, this.visible_ = !1, this.setMap(this.map_)
  20. }
  21. MarkerClusterer.prototype.MARKER_CLUSTER_IMAGE_PATH_ = "https://googlemaps.github.io/js-marker-clusterer/images/m", MarkerClusterer.prototype.MARKER_CLUSTER_IMAGE_EXTENSION_ = "png", MarkerClusterer.prototype.extend = function(t, e) {
  22.     return function(t) {
  23.         for (var e in t.prototype) this.prototype[e] = t.prototype[e];
  24.         return this
  25.     }.apply(t, [e])
  26. }, MarkerClusterer.prototype.onAdd = function() {
  27.     this.setReady_(!0)
  28. }, MarkerClusterer.prototype.draw = function() {}, MarkerClusterer.prototype.setupStyles_ = function() {
  29.     if (!this.styles_.length)
  30.         for (var t, e = 0; t = this.sizes[e]; e++) this.styles_.push({
  31.             url: this.imagePath_ + (e + 1) + "." + this.imageExtension_,
  32.             height: t,
  33.             width: t
  34.         })
  35. }, MarkerClusterer.prototype.fitMapToMarkers = function() {
  36.     for (var t, e = this.getMarkers(), r = new google.maps.LatLngBounds, s = 0; t = e[s]; s++) r.extend(t.getPosition());
  37.     this.map_.fitBounds(r)
  38. }, MarkerClusterer.prototype.setStyles = function(t) {
  39.     this.styles_ = t
  40. }, MarkerClusterer.prototype.getStyles = function() {
  41.     return this.styles_
  42. }, MarkerClusterer.prototype.isZoomOnClick = function() {
  43.     return this.zoomOnClick_
  44. }, MarkerClusterer.prototype.isAverageCenter = function() {
  45.     return this.averageCenter_
  46. }, MarkerClusterer.prototype.getMarkers = function() {
  47.     return this.markers_
  48. }, MarkerClusterer.prototype.getTotalMarkers = function() {
  49.     return this.markers_.length
  50. }, MarkerClusterer.prototype.setMaxZoom = function(t) {
  51.     this.maxZoom_ = t
  52. }, MarkerClusterer.prototype.getMaxZoom = function() {
  53.     return this.maxZoom_
  54. }, MarkerClusterer.prototype.calculator_ = function(t, e) {
  55.     for (var r = 0, s = t.length, o = s; 0 !== o;) o = parseInt(o / 10, 10), r++;
  56.     return r = Math.min(r, e), {
  57.         text: s,
  58.         index: r
  59.     }
  60. }, MarkerClusterer.prototype.setCalculator = function(t) {
  61.     this.calculator_ = t
  62. }, MarkerClusterer.prototype.getCalculator = function() {
  63.     return this.calculator_
  64. }, MarkerClusterer.prototype.addMarkers = function(t, e) {
  65.     for (var r, s = 0; r = t[s]; s++) this.pushMarkerTo_(r);
  66.     e || this.redraw()
  67. }, MarkerClusterer.prototype.pushMarkerTo_ = function(t) {
  68.     if (t.isAdded = !1, t.draggable) {
  69.         var e = this;
  70.         google.maps.event.addListener(t, "dragend", function() {
  71.             t.isAdded = !1, e.repaint()
  72.         })
  73.     }
  74.     this.markers_.push(t)
  75. }, MarkerClusterer.prototype.addMarker = function(t, e) {
  76.     this.pushMarkerTo_(t), e || this.redraw()
  77. }, MarkerClusterer.prototype.removeMarker_ = function(t) {
  78.     var e = -1;
  79.     if (this.markers_.indexOf) e = this.markers_.indexOf(t);
  80.     else
  81.         for (var r, s = 0; r = this.markers_[s]; s++)
  82.             if (r == t) {
  83.                 e = s;
  84.                 break
  85.             } return -1 == e ? !1 : (t.setMap(null), this.markers_.splice(e, 1), !0)
  86. }, MarkerClusterer.prototype.removeMarker = function(t, e) {
  87.     var r = this.removeMarker_(t);
  88.     return !e && r ? (this.resetViewport(), this.redraw(), !0) : !1
  89. }, MarkerClusterer.prototype.removeMarkers = function(t, e) {
  90.     for (var r, s = !1, o = 0; r = t[o]; o++) {
  91.         var i = this.removeMarker_(r);
  92.         s = s || i
  93.     }
  94.     return !e && s ? (this.resetViewport(), this.redraw(), !0) : void 0
  95. }, MarkerClusterer.prototype.setReady_ = function(t) {
  96.     this.ready_ || (this.ready_ = t, this.createClusters_())
  97. }, MarkerClusterer.prototype.getTotalClusters = function() {
  98.     return this.clusters_.length
  99. }, MarkerClusterer.prototype.getMap = function() {
  100.     return this.map_
  101. }, MarkerClusterer.prototype.setMap = function(t) {
  102.     this.map_ = t
  103. }, MarkerClusterer.prototype.getGridSize = function() {
  104.     return this.gridSize_
  105. }, MarkerClusterer.prototype.setGridSize = function(t) {
  106.     this.gridSize_ = t
  107. }, MarkerClusterer.prototype.getMinClusterSize = function() {
  108.     return this.minClusterSize_
  109. }, MarkerClusterer.prototype.setMinClusterSize = function(t) {
  110.     this.minClusterSize_ = t
  111. }, MarkerClusterer.prototype.getExtendedBounds = function(t) {
  112.     var e = this.getProjection(),
  113.         r = new google.maps.LatLng(t.getNorthEast().lat(), t.getNorthEast().lng()),
  114.         s = new google.maps.LatLng(t.getSouthWest().lat(), t.getSouthWest().lng()),
  115.         o = e.fromLatLngToDivPixel(r);
  116.     o.x += this.gridSize_, o.y -= this.gridSize_;
  117.     var i = e.fromLatLngToDivPixel(s);
  118.     i.x -= this.gridSize_, i.y += this.gridSize_;
  119.     var n = e.fromDivPixelToLatLng(o),
  120.         a = e.fromDivPixelToLatLng(i);
  121.     return t.extend(n), t.extend(a), t
  122. }, MarkerClusterer.prototype.isMarkerInBounds_ = function(t, e) {
  123.     return e.contains(t.getPosition())
  124. }, MarkerClusterer.prototype.clearMarkers = function() {
  125.     this.resetViewport(!0), this.markers_ = []
  126. }, MarkerClusterer.prototype.resetViewport = function(t) {
  127.     for (var e, r = 0; e = this.clusters_[r]; r++) e.remove();
  128.     for (var s, r = 0; s = this.markers_[r]; r++) s.isAdded = !1, t && s.setMap(null);
  129.     this.clusters_ = []
  130. }, MarkerClusterer.prototype.repaint = function() {
  131.     var t = this.clusters_.slice();
  132.     this.clusters_.length = 0, this.resetViewport(), this.redraw(), window.setTimeout(function() {
  133.         for (var e, r = 0; e = t[r]; r++) e.remove()
  134.     }, 0)
  135. }, MarkerClusterer.prototype.redraw = function() {
  136.     this.createClusters_()
  137. }, MarkerClusterer.prototype.distanceBetweenPoints_ = function(t, e) {
  138.     if (!t || !e) return 0;
  139.     var r = 6371,
  140.         s = (e.lat() - t.lat()) * Math.PI / 180,
  141.         o = (e.lng() - t.lng()) * Math.PI / 180,
  142.         i = Math.sin(s / 2) * Math.sin(s / 2) + Math.cos(t.lat() * Math.PI / 180) * Math.cos(e.lat() * Math.PI / 180) * Math.sin(o / 2) * Math.sin(o / 2),
  143.         n = 2 * Math.atan2(Math.sqrt(i), Math.sqrt(1 - i)),
  144.         a = r * n;
  145.     return a
  146. }, MarkerClusterer.prototype.addToClosestCluster_ = function(t) {
  147.     for (var e, r = 4e4, s = null, o = (t.getPosition(), 0); e = this.clusters_[o]; o++) {
  148.         var i = e.getCenter();
  149.         if (i) {
  150.             var n = this.distanceBetweenPoints_(i, t.getPosition());
  151.             r > n && (r = n, s = e)
  152.         }
  153.     }
  154.     if (s && s.isMarkerInClusterBounds(t)) s.addMarker(t);
  155.     else {
  156.         var e = new Cluster(this);
  157.         e.addMarker(t), this.clusters_.push(e)
  158.     }
  159. }, MarkerClusterer.prototype.createClusters_ = function() {
  160.     if (this.ready_)
  161.         for (var t, e = new google.maps.LatLngBounds(this.map_.getBounds().getSouthWest(), this.map_.getBounds().getNorthEast()), r = this.getExtendedBounds(e), s = 0; t = this.markers_[s]; s++) !t.isAdded && this.isMarkerInBounds_(t, r) && this.addToClosestCluster_(t)
  162. }, Cluster.prototype.isMarkerAlreadyAdded = function(t) {
  163.     if (this.markers_.indexOf) return -1 != this.markers_.indexOf(t);
  164.     for (var e, r = 0; e = this.markers_[r]; r++)
  165.         if (e == t) return !0;
  166.     return !1
  167. }, Cluster.prototype.addMarker = function(t) {
  168.     if (this.isMarkerAlreadyAdded(t)) return !1;
  169.     if (this.center_) {
  170.         if (this.averageCenter_) {
  171.             var e = this.markers_.length + 1,
  172.                 r = (this.center_.lat() * (e - 1) + t.getPosition().lat()) / e,
  173.                 s = (this.center_.lng() * (e - 1) + t.getPosition().lng()) / e;
  174.             this.center_ = new google.maps.LatLng(r, s), this.calculateBounds_()
  175.         }
  176.     } else this.center_ = t.getPosition(), this.calculateBounds_();
  177.     t.isAdded = !0, this.markers_.push(t);
  178.     var o = this.getVisibleMarkers(),
  179.         i = o.length;
  180.     if (i < this.minClusterSize_ && t.getMap() != this.map_ && t.setMap(this.map_), i == this.minClusterSize_)
  181.         for (var n = 0; i > n; n++) o[n].setMap(null);
  182.     return i >= this.minClusterSize_ && t.setMap(null), this.updateIcon(), !0
  183. }, Cluster.prototype.getMarkerClusterer = function() {
  184.     return this.markerClusterer_
  185. }, Cluster.prototype.getBounds = function() {
  186.     for (var t, e = new google.maps.LatLngBounds(this.center_, this.center_), r = this.getMarkers(), s = 0; t = r[s]; s++) e.extend(t.getPosition());
  187.     return e
  188. }, Cluster.prototype.remove = function() {
  189.     this.clusterIcon_.remove(), this.markers_.length = 0, delete this.markers_
  190. }, Cluster.prototype.getSize = function() {
  191.     return this.markers_.length
  192. }, Cluster.prototype.getMarkers = function() {
  193.     return this.markers_
  194. }, Cluster.prototype.getVisibleMarkers = function() {
  195.     var t = [];
  196.     for (var e in this.markers_) {
  197.         var r = this.markers_[e];
  198.         r.visible && t.push(r)
  199.     }
  200.     return t
  201. }, Cluster.prototype.getCenter = function() {
  202.     return this.center_
  203. }, Cluster.prototype.calculateBounds_ = function() {
  204.     var t = new google.maps.LatLngBounds(this.center_, this.center_);
  205.     this.bounds_ = this.markerClusterer_.getExtendedBounds(t)
  206. }, Cluster.prototype.isMarkerInClusterBounds = function(t) {
  207.     return this.bounds_.contains(t.getPosition())
  208. }, Cluster.prototype.getMap = function() {
  209.     return this.map_
  210. }, Cluster.prototype.updateIcon = function() {
  211.     var t = this.map_.getZoom(),
  212.         e = this.markerClusterer_.getMaxZoom(),
  213.         r = this.getVisibleMarkers();
  214.     if (e && t > e)
  215.         for (var s, o = 0; s = r[o]; o++) s.setMap(this.map_);
  216.     else {
  217.         if (this.markers_.length < this.minClusterSize_) return void this.clusterIcon_.hide();
  218.         var i = this.markerClusterer_.getStyles().length,
  219.             n = this.markerClusterer_.getCalculator()(r, i);
  220.         "0" == n.text ? this.clusterIcon_.hide() : (this.clusterIcon_.setCenter(this.center_), this.clusterIcon_.setSums(n), this.clusterIcon_.show())
  221.     }
  222. }, ClusterIcon.prototype.triggerClusterClick = function(t) {
  223.     var e = this.cluster_.getMarkerClusterer();
  224.     google.maps.event.trigger(e, "clusterclick", this.cluster_, t), e.isZoomOnClick() && this.map_.fitBounds(this.cluster_.getBounds())
  225. }, ClusterIcon.prototype.onAdd = function() {
  226.     if (this.div_ = document.createElement("DIV"), this.visible_) {
  227.         var t = this.getPosFromLatLng_(this.center_);
  228.         this.div_.style.cssText = this.createCss(t), this.div_.innerHTML = this.sums_.text
  229.     }
  230.     var e = this.getPanes();
  231.     e.overlayMouseTarget.appendChild(this.div_);
  232.     var r = this;
  233.     google.maps.event.addDomListener(this.div_, "click", function(t) {
  234.         r.triggerClusterClick(t)
  235.     })
  236. }, ClusterIcon.prototype.getPosFromLatLng_ = function(t) {
  237.     var e = this.getProjection().fromLatLngToDivPixel(t);
  238.     return "object" == typeof this.iconAnchor_ && 2 === this.iconAnchor_.length ? (e.x -= this.iconAnchor_[0], e.y -= this.iconAnchor_[1]) : (e.x -= parseInt(this.width_ / 2, 10), e.y -= parseInt(this.height_ / 2, 10)), e
  239. }, ClusterIcon.prototype.draw = function() {
  240.     if (this.visible_) {
  241.         var t = this.getPosFromLatLng_(this.center_);
  242.         this.div_.style.top = t.y + "px", this.div_.style.left = t.x + "px"
  243.     }
  244. }, ClusterIcon.prototype.hide = function() {
  245.     this.div_ && (this.div_.style.display = "none"), this.visible_ = !1
  246. }, ClusterIcon.prototype.show = function() {
  247.     if (this.div_) {
  248.         var t = this.getPosFromLatLng_(this.center_);
  249.         this.div_.style.cssText = this.createCss(t), this.div_.style.display = ""
  250.     }
  251.     this.visible_ = !0
  252. }, ClusterIcon.prototype.remove = function() {
  253.     this.setMap(null)
  254. }, ClusterIcon.prototype.onRemove = function() {
  255.     this.div_ && this.div_.parentNode && (this.hide(), this.div_.parentNode.removeChild(this.div_), this.div_ = null)
  256. }, ClusterIcon.prototype.setSums = function(t) {
  257.     this.sums_ = t, this.text_ = t.text, this.index_ = t.index, this.div_ && (this.div_.innerHTML = t.text), this.useStyle()
  258. }, ClusterIcon.prototype.useStyle = function() {
  259.     var t = Math.max(0, this.sums_.index - 1);
  260.     t = Math.min(this.styles_.length - 1, t);
  261.     var e = this.styles_[t];
  262.     this.url_ = e.url, this.height_ = e.height, this.width_ = e.width, this.textColor_ = e.textColor, this.anchor_ = e.anchor, this.textSize_ = e.textSize, this.backgroundPosition_ = e.backgroundPosition, this.iconAnchor_ = e.iconAnchor
  263. }, ClusterIcon.prototype.setCenter = function(t) {
  264.     this.center_ = t
  265. }, ClusterIcon.prototype.createCss = function(t) {
  266.     var e = [];
  267.     e.push("background-image:url(" + this.url_ + ");");
  268.     var r = this.backgroundPosition_ ? this.backgroundPosition_ : "0 0";
  269.     e.push("background-position:" + r + ";"), "object" == typeof this.anchor_ ? ("number" == typeof this.anchor_[0] && this.anchor_[0] > 0 && this.anchor_[0] < this.height_ ? e.push("height:" + (this.height_ - this.anchor_[0]) + "px; padding-top:" + this.anchor_[0] + "px;") : "number" == typeof this.anchor_[0] && this.anchor_[0] < 0 && -this.anchor_[0] < this.height_ ? e.push("height:" + this.height_ + "px; line-height:" + (this.height_ + this.anchor_[0]) + "px;") : e.push("height:" + this.height_ + "px; line-height:" + this.height_ + "px;"), "number" == typeof this.anchor_[1] && this.anchor_[1] > 0 && this.anchor_[1] < this.width_ ? e.push("width:" + (this.width_ - this.anchor_[1]) + "px; padding-left:" + this.anchor_[1] + "px;") : e.push("width:" + this.width_ + "px; text-align:center;")) : e.push("height:" + this.height_ + "px; line-height:" + this.height_ + "px; width:" + this.width_ + "px; text-align:center;");
  270.     var s = this.textColor_ ? this.textColor_ : "black",
  271.         o = this.textSize_ ? this.textSize_ : 11;
  272.     return e.push("cursor:pointer; top:" + t.y + "px; left:" + t.x + "px; color:" + s + "; position:absolute; font-size:" + o + "px; font-family:Arial,sans-serif; font-weight:bold"), e.join("")
  273. }, window.MarkerClusterer = MarkerClusterer, MarkerClusterer.prototype.addMarker = MarkerClusterer.prototype.addMarker, MarkerClusterer.prototype.addMarkers = MarkerClusterer.prototype.addMarkers, MarkerClusterer.prototype.clearMarkers = MarkerClusterer.prototype.clearMarkers, MarkerClusterer.prototype.fitMapToMarkers = MarkerClusterer.prototype.fitMapToMarkers, MarkerClusterer.prototype.getCalculator = MarkerClusterer.prototype.getCalculator, MarkerClusterer.prototype.getGridSize = MarkerClusterer.prototype.getGridSize, MarkerClusterer.prototype.getExtendedBounds = MarkerClusterer.prototype.getExtendedBounds, MarkerClusterer.prototype.getMap = MarkerClusterer.prototype.getMap, MarkerClusterer.prototype.getMarkers = MarkerClusterer.prototype.getMarkers, MarkerClusterer.prototype.getMaxZoom = MarkerClusterer.prototype.getMaxZoom, MarkerClusterer.prototype.getStyles = MarkerClusterer.prototype.getStyles, MarkerClusterer.prototype.getTotalClusters = MarkerClusterer.prototype.getTotalClusters, MarkerClusterer.prototype.getTotalMarkers = MarkerClusterer.prototype.getTotalMarkers, MarkerClusterer.prototype.redraw = MarkerClusterer.prototype.redraw, MarkerClusterer.prototype.removeMarker = MarkerClusterer.prototype.removeMarker, MarkerClusterer.prototype.removeMarkers = MarkerClusterer.prototype.removeMarkers, MarkerClusterer.prototype.resetViewport = MarkerClusterer.prototype.resetViewport, MarkerClusterer.prototype.repaint = MarkerClusterer.prototype.repaint, MarkerClusterer.prototype.setCalculator = MarkerClusterer.prototype.setCalculator, MarkerClusterer.prototype.setGridSize = MarkerClusterer.prototype.setGridSize, MarkerClusterer.prototype.setMaxZoom = MarkerClusterer.prototype.setMaxZoom, MarkerClusterer.prototype.onAdd = MarkerClusterer.prototype.onAdd, MarkerClusterer.prototype.draw = MarkerClusterer.prototype.draw, Cluster.prototype.getCenter = Cluster.prototype.getCenter, Cluster.prototype.getSize = Cluster.prototype.getSize, Cluster.prototype.getMarkers = Cluster.prototype.getMarkers, Cluster.prototype.getVisibleMarkers = Cluster.prototype.getVisibleMarkers, ClusterIcon.prototype.onAdd = ClusterIcon.prototype.onAdd, ClusterIcon.prototype.draw = ClusterIcon.prototype.draw, ClusterIcon.prototype.onRemove = ClusterIcon.prototype.onRemove;

Raw Paste


Login or Register to edit or fork this paste. It's free.