1var __extends = (this && this.__extends) || function (d, b) { 2 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 3 function __() { this.constructor = d; } 4 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 5}; 6var PruneCluster; 7(function (PruneCluster_1) { 8 var Point = (function () { 9 function Point() { 10 } 11 return Point; 12 })(); 13 PruneCluster_1.Point = Point; 14 var ClusterObject = (function () { 15 function ClusterObject() { 16 } 17 return ClusterObject; 18 })(); 19 PruneCluster_1.ClusterObject = ClusterObject; 20 var hashCodeCounter = 1; 21 var maxHashCodeValue = Math.pow(2, 53) - 1; 22 var Marker = (function (_super) { 23 __extends(Marker, _super); 24 function Marker(lat, lng, data, category, weight, filtered) { 25 if (data === void 0) { data = {}; } 26 if (weight === void 0) { weight = 1; } 27 if (filtered === void 0) { filtered = false; } 28 _super.call(this); 29 this.data = data; 30 this.position = { lat: +lat, lng: +lng }; 31 this.weight = weight; 32 this.category = category; 33 this.filtered = filtered; 34 this.hashCode = hashCodeCounter++; 35 } 36 Marker.prototype.Move = function (lat, lng) { 37 this.position.lat = +lat; 38 this.position.lng = +lng; 39 }; 40 Marker.prototype.SetData = function (data) { 41 for (var key in data) { 42 this.data[key] = data[key]; 43 } 44 }; 45 return Marker; 46 })(ClusterObject); 47 PruneCluster_1.Marker = Marker; 48 var Cluster = (function (_super) { 49 __extends(Cluster, _super); 50 function Cluster(marker) { 51 _super.call(this); 52 this.stats = [0, 0, 0, 0, 0, 0, 0, 0]; 53 this.data = {}; 54 if (!marker) { 55 this.hashCode = 1; 56 if (Cluster.ENABLE_MARKERS_LIST) { 57 this._clusterMarkers = []; 58 } 59 return; 60 } 61 if (Cluster.ENABLE_MARKERS_LIST) { 62 this._clusterMarkers = [marker]; 63 } 64 this.lastMarker = marker; 65 this.hashCode = 31 + marker.hashCode; 66 this.population = 1; 67 if (marker.category !== undefined) { 68 this.stats[marker.category] = 1; 69 } 70 this.totalWeight = marker.weight; 71 this.position = { 72 lat: marker.position.lat, 73 lng: marker.position.lng 74 }; 75 this.averagePosition = { 76 lat: marker.position.lat, 77 lng: marker.position.lng 78 }; 79 } 80 Cluster.prototype.AddMarker = function (marker) { 81 if (Cluster.ENABLE_MARKERS_LIST) { 82 this._clusterMarkers.push(marker); 83 } 84 var h = this.hashCode; 85 h = ((h << 5) - h) + marker.hashCode; 86 if (h >= maxHashCodeValue) { 87 this.hashCode = h % maxHashCodeValue; 88 } 89 else { 90 this.hashCode = h; 91 } 92 this.lastMarker = marker; 93 var weight = marker.weight, currentTotalWeight = this.totalWeight, newWeight = weight + currentTotalWeight; 94 this.averagePosition.lat = 95 (this.averagePosition.lat * currentTotalWeight + 96 marker.position.lat * weight) / newWeight; 97 this.averagePosition.lng = 98 (this.averagePosition.lng * currentTotalWeight + 99 marker.position.lng * weight) / newWeight; 100 ++this.population; 101 this.totalWeight = newWeight; 102 if (marker.category !== undefined) { 103 this.stats[marker.category] = (this.stats[marker.category] + 1) || 1; 104 } 105 }; 106 Cluster.prototype.Reset = function () { 107 this.hashCode = 1; 108 this.lastMarker = undefined; 109 this.population = 0; 110 this.totalWeight = 0; 111 this.stats = [0, 0, 0, 0, 0, 0, 0, 0]; 112 if (Cluster.ENABLE_MARKERS_LIST) { 113 this._clusterMarkers = []; 114 } 115 }; 116 Cluster.prototype.ComputeBounds = function (cluster) { 117 var proj = cluster.Project(this.position.lat, this.position.lng); 118 var size = cluster.Size; 119 var nbX = Math.floor(proj.x / size), nbY = Math.floor(proj.y / size), startX = nbX * size, startY = nbY * size; 120 var a = cluster.UnProject(startX, startY), b = cluster.UnProject(startX + size, startY + size); 121 this.bounds = { 122 minLat: b.lat, 123 maxLat: a.lat, 124 minLng: a.lng, 125 maxLng: b.lng 126 }; 127 }; 128 Cluster.prototype.GetClusterMarkers = function () { 129 return this._clusterMarkers; 130 }; 131 Cluster.prototype.ApplyCluster = function (newCluster) { 132 this.hashCode = this.hashCode * 41 + newCluster.hashCode * 43; 133 if (this.hashCode > maxHashCodeValue) { 134 this.hashCode = this.hashCode = maxHashCodeValue; 135 } 136 var weight = newCluster.totalWeight, currentTotalWeight = this.totalWeight, newWeight = weight + currentTotalWeight; 137 this.averagePosition.lat = 138 (this.averagePosition.lat * currentTotalWeight + 139 newCluster.averagePosition.lat * weight) / newWeight; 140 this.averagePosition.lng = 141 (this.averagePosition.lng * currentTotalWeight + 142 newCluster.averagePosition.lng * weight) / newWeight; 143 this.population += newCluster.population; 144 this.totalWeight = newWeight; 145 this.bounds.minLat = Math.min(this.bounds.minLat, newCluster.bounds.minLat); 146 this.bounds.minLng = Math.min(this.bounds.minLng, newCluster.bounds.minLng); 147 this.bounds.maxLat = Math.max(this.bounds.maxLat, newCluster.bounds.maxLat); 148 this.bounds.maxLng = Math.max(this.bounds.maxLng, newCluster.bounds.maxLng); 149 for (var category in newCluster.stats) { 150 if (newCluster.stats.hasOwnProperty(category)) { 151 if (this.stats.hasOwnProperty(category)) { 152 this.stats[category] += newCluster.stats[category]; 153 } 154 else { 155 this.stats[category] = newCluster.stats[category]; 156 } 157 } 158 } 159 if (Cluster.ENABLE_MARKERS_LIST) { 160 this._clusterMarkers = this._clusterMarkers.concat(newCluster.GetClusterMarkers()); 161 } 162 }; 163 Cluster.ENABLE_MARKERS_LIST = false;
164 return Cluster; 165 })(ClusterObject); 166 PruneCluster_1.Cluster = Cluster; 167 function checkPositionInsideBounds(a, b) { 168 return (a.lat >= b.minLat && a.lat <= b.maxLat) && 169 a.lng >= b.minLng && a.lng <= b.maxLng; 170 } 171 function insertionSort(list) { 172 for (var i = 1, j, tmp, tmpLng, length = list.length; i < length; ++i) { 173 tmp = list[i]; 174 tmpLng = tmp.position.lng; 175 for (j = i - 1; j >= 0 && list[j].position.lng > tmpLng; --j) { 176 list[j + 1] = list[j]; 177 } 178 list[j + 1] = tmp; 179 } 180 } 181 function shouldUseInsertionSort(total, nbChanges) { 182 if (nbChanges > 300) { 183 return false; 184 } 185 else { 186 return (nbChanges / total) < 0.2; 187 } 188 } 189 var PruneCluster = (function () { 190 function PruneCluster() { 191 this._markers = []; 192 this._nbChanges = 0; 193 this._clusters = []; 194 this.Size = 166; 195 this.ViewPadding = 0.2; 196 } 197 PruneCluster.prototype.RegisterMarker = function (marker) { 198 if (marker._removeFlag) { 199 delete marker._removeFlag; 200 } 201 this._markers.push(marker); 202 this._nbChanges += 1; 203 }; 204 PruneCluster.prototype.RegisterMarkers = function (markers) { 205 var _this = this; 206 markers.forEach(function (marker) { 207 _this.RegisterMarker(marker); 208 }); 209 }; 210 PruneCluster.prototype._sortMarkers = function () { 211 var markers = this._markers, length = markers.length; 212 if (this._nbChanges && !shouldUseInsertionSort(length, this._nbChanges)) { 213 this._markers.sort(function (a, b) { return a.position.lng - b.position.lng; }); 214 } 215 else { 216 insertionSort(markers); 217 } 218 this._nbChanges = 0; 219 }; 220 PruneCluster.prototype._sortClusters = function () { 221 insertionSort(this._clusters); 222 }; 223 PruneCluster.prototype._indexLowerBoundLng = function (lng) { 224 var markers = this._markers, it, step, first = 0, count = markers.length; 225 while (count > 0) { 226 step = Math.floor(count / 2); 227 it = first + step; 228 if (markers[it].position.lng < lng) { 229 first = ++it; 230 count -= step + 1; 231 } 232 else { 233 count = step; 234 } 235 } 236 return first; 237 }; 238 PruneCluster.prototype._resetClusterViews = function () { 239 for (var i = 0, l = this._clusters.length; i < l; ++i) { 240 var cluster = this._clusters[i]; 241 cluster.Reset(); 242 cluster.ComputeBounds(this); 243 } 244 }; 245 PruneCluster.prototype.ProcessView = function (bounds) { 246 var heightBuffer = Math.abs(bounds.maxLat - bounds.minLat) * this.ViewPadding, widthBuffer = Math.abs(bounds.maxLng - bounds.minLng) * this.ViewPadding; 247 var extendedBounds = { 248 minLat: bounds.minLat - heightBuffer - heightBuffer, 249 maxLat: bounds.maxLat + heightBuffer + heightBuffer, 250 minLng: bounds.minLng - widthBuffer - widthBuffer, 251 maxLng: bounds.maxLng + widthBuffer + widthBuffer 252 }; 253 this._sortMarkers(); 254 this._resetClusterViews(); 255 var firstIndex = this._indexLowerBoundLng(extendedBounds.minLng); 256 var markers = this._markers, clusters = this._clusters; 257 var workingClusterList = clusters.slice(0); 258 for (var i = firstIndex, l = markers.length; i < l; ++i) { 259 var marker = markers[i], markerPosition = marker.position; 260 if (markerPosition.lng > extendedBounds.maxLng) { 261 break; 262 } 263 if (markerPosition.lat > extendedBounds.minLat && 264 markerPosition.lat < extendedBounds.maxLat && 265 !marker.filtered) { 266 var clusterFound = false, cluster; 267 for (var j = 0, ll = workingClusterList.length; j < ll; ++j) { 268 cluster = workingClusterList[j]; 269 if (cluster.bounds.maxLng < marker.position.lng) { 270 workingClusterList.splice(j, 1); 271 --j; 272 --ll; 273 continue; 274 } 275 if (checkPositionInsideBounds(markerPosition, cluster.bounds)) { 276 cluster.AddMarker(marker); 277 clusterFound = true; 278 break; 279 } 280 } 281 if (!clusterFound) { 282 cluster = new Cluster(marker); 283 cluster.ComputeBounds(this);
284 clusters.push(cluster); 285 workingClusterList.push(cluster); 286 } 287 } 288 } 289 var newClustersList = []; 290 for (i = 0, l = clusters.length; i < l; ++i) { 291 cluster = clusters[i]; 292 if (cluster.population > 0) { 293 newClustersList.push(cluster); 294 } 295 } 296 this._clusters = newClustersList; 297 this._sortClusters(); 298 return this._clusters; 299 }; 300 PruneCluster.prototype.RemoveMarkers = function (markers) { 301 if (!markers) { 302 this._markers = []; 303 return; 304 } 305 for (var i = 0, l = markers.length; i < l; ++i) { 306 markers[i]._removeFlag = true; 307 } 308 var newMarkersList = []; 309 for (i = 0, l = this._markers.length; i < l; ++i) { 310 if (!this._markers[i]._removeFlag) { 311 newMarkersList.push(this._markers[i]); 312 } 313 else { 314 delete this._markers[i]._removeFlag; 315 } 316 } 317 this._markers = newMarkersList; 318 }; 319 PruneCluster.prototype.FindMarkersInArea = function (area) { 320 var aMinLat = area.minLat, aMaxLat = area.maxLat, aMinLng = area.minLng, aMaxLng = area.maxLng, markers = this._markers, result = []; 321 var firstIndex = this._indexLowerBoundLng(aMinLng); 322 for (var i = firstIndex, l = markers.length; i < l; ++i) { 323 var pos = markers[i].position; 324 if (pos.lng > aMaxLng) { 325 break; 326 } 327 if (pos.lat >= aMinLat && pos.lat <= aMaxLat && 328 pos.lng >= aMinLng) { 329 result.push(markers[i]); 330 } 331 } 332 return result; 333 }; 334 PruneCluster.prototype.ComputeBounds = function (markers, withFiltered) { 335 if (withFiltered === void 0) { withFiltered = true; } 336 if (!markers || !markers.length) { 337 return null; 338 } 339 var rMinLat = Number.MAX_VALUE, rMaxLat = -Number.MAX_VALUE, rMinLng = Number.MAX_VALUE, rMaxLng = -Number.MAX_VALUE; 340 for (var i = 0, l = markers.length; i < l; ++i) { 341 if (!withFiltered && markers[i].filtered) { 342 continue; 343 } 344 var pos = markers[i].position; 345 if (pos.lat < rMinLat) 346 rMinLat = pos.lat; 347 if (pos.lat > rMaxLat) 348 rMaxLat = pos.lat; 349 if (pos.lng < rMinLng) 350 rMinLng = pos.lng; 351 if (pos.lng > rMaxLng) 352 rMaxLng = pos.lng; 353 } 354 return { 355 minLat: rMinLat, 356 maxLat: rMaxLat, 357 minLng: rMinLng, 358 maxLng: rMaxLng 359 }; 360 }; 361 PruneCluster.prototype.FindMarkersBoundsInArea = function (area) { 362 return this.ComputeBounds(this.FindMarkersInArea(area)); 363 }; 364 PruneCluster.prototype.ComputeGlobalBounds = function (withFiltered) { 365 if (withFiltered === void 0) { withFiltered = true; } 366 return this.ComputeBounds(this._markers, withFiltered); 367 }; 368 PruneCluster.prototype.GetMarkers = function () { 369 return this._markers; 370 }; 371 PruneCluster.prototype.GetPopulation = function () { 372 return this._markers.length; 373 }; 374 PruneCluster.prototype.ResetClusters = function () { 375 this._clusters = []; 376 }; 377 return PruneCluster; 378 })(); 379 PruneCluster_1.PruneCluster = PruneCluster; 380})(PruneCluster || (PruneCluster = {})); 381var PruneCluster; 382(function (PruneCluster) { 383})(PruneCluster || (PruneCluster = {})); 384var PruneClusterForLeaflet = (L.Layer ? L.Layer : L.Class).extend({ 385 initialize: function (size, clusterMargin) { 386 var _this = this; 387 if (size === void 0) { size = 120; } 388 if (clusterMargin === void 0) { clusterMargin = 20; } 389 this.Cluster = new PruneCluster.PruneCluster(); 390 this.Cluster.Size = size; 391 this.clusterMargin = Math.min(clusterMargin, size / 4); 392 this.Cluster.Project = function (lat, lng) { 393 return _this._map.project(new L.LatLng(lat, lng), Math.floor(_this._map.getZoom())); 394 }; 395 this.Cluster.UnProject = function (x, y) { 396 return _this._map.unproject(new L.Point(x, y), Math.floor(_this._map.getZoom())); 397 }; 398 this._objectsOnMap = []; 399 this.spiderfier = new PruneClusterLeafletSpiderfier(this); 400 this._hardMove = false;
401 this._resetIcons = false; 402 this._removeTimeoutId = 0; 403 this._markersRemoveListTimeout = []; 404 }, 405 RegisterMarker: function (marker) { 406 this.Cluster.RegisterMarker(marker); 407 }, 408 RegisterMarkers: function (markers) { 409 this.Cluster.RegisterMarkers(markers); 410 }, 411 RemoveMarkers: function (markers) { 412 this.Cluster.RemoveMarkers(markers); 413 }, 414 BuildLeafletCluster: function (cluster, position) { 415 var _this = this; 416 var m = new L.Marker(position, { 417 icon: this.BuildLeafletClusterIcon(cluster) 418 }); 419 m._leafletClusterBounds = cluster.bounds; 420 m.on('click', function () { 421 var cbounds = m._leafletClusterBounds; 422 var markersArea = _this.Cluster.FindMarkersInArea(cbounds); 423 var b = _this.Cluster.ComputeBounds(markersArea); 424 if (b) { 425 var bounds = new L.LatLngBounds(new L.LatLng(b.minLat, b.maxLng), new L.LatLng(b.maxLat, b.minLng)); 426 var zoomLevelBefore = _this._map.getZoom(), zoomLevelAfter = _this._map.getBoundsZoom(bounds, false, new L.Point(20, 20)); 427 if (zoomLevelAfter === zoomLevelBefore) { 428 var filteredBounds = []; 429 for (var i = 0, l = _this._objectsOnMap.length; i < l; ++i) { 430 var o = _this._objectsOnMap[i]; 431 if (o.data._leafletMarker !== m) { 432 if (o.bounds.minLat >= cbounds.minLat && 433 o.bounds.maxLat <= cbounds.maxLat && 434 o.bounds.minLng >= cbounds.minLng && 435 o.bounds.maxLng <= cbounds.maxLng) { 436 filteredBounds.push(o.bounds); 437 } 438 } 439 } 440 if (filteredBounds.length > 0) { 441 var newMarkersArea = []; 442 var ll = filteredBounds.length; 443 for (i = 0, l = markersArea.length; i < l; ++i) { 444 var markerPos = markersArea[i].position; 445 var isFiltered = false; 446 for (var j = 0; j < ll; ++j) { 447 var currentFilteredBounds = filteredBounds[j]; 448 if (markerPos.lat >= currentFilteredBounds.minLat && 449 markerPos.lat <= currentFilteredBounds.maxLat && 450 markerPos.lng >= currentFilteredBounds.minLng && 451 markerPos.lng <= currentFilteredBounds.maxLng) { 452 isFiltered = true; 453 break; 454 } 455 } 456 if (!isFiltered) { 457 newMarkersArea.push(markersArea[i]); 458 } 459 } 460 markersArea = newMarkersArea; 461 } 462 if (markersArea.length < 200) { 463 _this._map.fire('overlappingmarkers', { 464 cluster: _this, 465 markers: markersArea, 466 center: m.getLatLng(), 467 marker: m 468 }); 469 } 470 else if (zoomLevelAfter < _this._map.getMaxZoom()) { 471 zoomLevelAfter++; 472 }
473 _this._map.setView(m.getLatLng(), zoomLevelAfter); 474 } 475 else { 476 _this._map.fitBounds(bounds); 477 } 478 } 479 }); 480 return m; 481 }, 482 BuildLeafletClusterIcon: function (cluster) { 483 var c = 'prunecluster prunecluster-'; 484 var iconSize = 38; 485 var maxPopulation = this.Cluster.GetPopulation(); 486 if (cluster.population < Math.max(10, maxPopulation * 0.01)) { 487 c += 'small'; 488 } 489 else if (cluster.population < Math.max(100, maxPopulation * 0.05)) { 490 c += 'medium'; 491 iconSize = 40; 492 } 493 else { 494 c += 'large'; 495 iconSize = 44; 496 } 497 return new L.DivIcon({ 498 html: "<div><span>" + cluster.population + "</span></div>", 499 className: c, 500 iconSize: L.point(iconSize, iconSize) 501 }); 502 }, 503 BuildLeafletMarker: function (marker, position) { 504 var m = new L.Marker(position); 505 this.PrepareLeafletMarker(m, marker.data, marker.category); 506 return m; 507 }, 508 PrepareLeafletMarker: function (marker, data, category) { 509 if (data.icon) { 510 if (typeof data.icon === 'function') { 511 marker.setIcon(data.icon(data, category)); 512 } 513 else { 514 marker.setIcon(data.icon); 515 } 516 } 517 if (data.popup) { 518 var content = typeof data.popup === 'function' ? data.popup(data, category) : data.popup; 519 if (marker.getPopup()) { 520 marker.setPopupContent(content, data.popupOptions); 521 } 522 else { 523 marker.bindPopup(content, data.popupOptions); 524 } 525 } 526 }, 527 onAdd: function (map) { 528 this._map = map; 529 map.on('movestart', this._moveStart, this); 530 map.on('moveend', this._moveEnd, this); 531 map.on('zoomend', this._zoomStart, this); 532 map.on('zoomend', this._zoomEnd, this); 533 this.ProcessView(); 534 map.addLayer(this.spiderfier); 535 }, 536 onRemove: function (map) { 537 map.off('movestart', this._moveStart, this); 538 map.off('moveend', this._moveEnd, this); 539 map.off('zoomend', this._zoomStart, this); 540 map.off('zoomend', this._zoomEnd, this); 541 for (var i = 0, l = this._objectsOnMap.length; i < l; ++i) { 542 map.removeLayer(this._objectsOnMap[i].data._leafletMarker); 543 } 544 this._objectsOnMap = []; 545 this.Cluster.ResetClusters(); 546 map.removeLayer(this.spiderfier); 547 this._map = null; 548 }, 549 _moveStart: function () { 550 this._moveInProgress = true; 551 }, 552 _moveEnd: function (e) { 553 this._moveInProgress = false; 554 this._hardMove = e.hard; 555 this.ProcessView(); 556 }, 557 _zoomStart: function () { 558 this._zoomInProgress = true; 559 }, 560 _zoomEnd: function () { 561 this._zoomInProgress = false; 562 this.ProcessView(); 563 }, 564 ProcessView: function () { 565 var _this = this; 566 if (!this._map || this._zoomInProgress || this._moveInProgress) { 567 return; 568 } 569 var map = this._map, bounds = map.getBounds(), zoom = Math.floor(map.getZoom()), marginRatio = this.clusterMargin / this.Cluster.Size, resetIcons = this._resetIcons;
570 var southWest = bounds.getSouthWest(), northEast = bounds.getNorthEast(); 571 var clusters = this.Cluster.ProcessView({ 572 minLat: southWest.lat, 573 minLng: southWest.lng, 574 maxLat: northEast.lat, 575 maxLng: northEast.lng 576 }); 577 var objectsOnMap = this._objectsOnMap, newObjectsOnMap = [], markersOnMap = new Array(objectsOnMap.length); 578 for (var i = 0, l = objectsOnMap.length; i < l; ++i) { 579 var marker = objectsOnMap[i].data._leafletMarker; 580 markersOnMap[i] = marker; 581 marker._removeFromMap = true; 582 } 583 var clusterCreationList = []; 584 var clusterCreationListPopOne = []; 585 var opacityUpdateList = []; 586 var workingList = []; 587 for (i = 0, l = clusters.length; i < l; ++i) { 588 var icluster = clusters[i], iclusterData = icluster.data; 589 var latMargin = (icluster.bounds.maxLat - icluster.bounds.minLat) * marginRatio, lngMargin = (icluster.bounds.maxLng - icluster.bounds.minLng) * marginRatio; 590 for (var j = 0, ll = workingList.length; j < ll; ++j) { 591 var c = workingList[j]; 592 if (c.bounds.maxLng < icluster.bounds.minLng) { 593 workingList.splice(j, 1); 594 --j; 595 --ll; 596 continue; 597 } 598 var oldMaxLng = c.averagePosition.lng + lngMargin, oldMinLat = c.averagePosition.lat - latMargin, oldMaxLat = c.averagePosition.lat + latMargin, newMinLng = icluster.averagePosition.lng - lngMargin, newMinLat = icluster.averagePosition.lat - latMargin, newMaxLat = icluster.averagePosition.lat + latMargin; 599 if (oldMaxLng > newMinLng && oldMaxLat > newMinLat && oldMinLat < newMaxLat) { 600 iclusterData._leafletCollision = true; 601 c.ApplyCluster(icluster); 602 break; 603 } 604 } 605 if (!iclusterData._leafletCollision) { 606 workingList.push(icluster); 607 } 608 } 609 clusters.forEach(function (cluster) { 610 var m = undefined; 611 var data = cluster.data; 612 if (data._leafletCollision) { 613 data._leafletCollision = false; 614 data._leafletOldPopulation = 0; 615 data._leafletOldHashCode = 0; 616 return; 617 } 618 var position = new L.LatLng(cluster.averagePosition.lat, cluster.averagePosition.lng); 619 var oldMarker = data._leafletMarker; 620 if (oldMarker) { 621 if (cluster.population === 1 && data._leafletOldPopulation === 1 && cluster.hashCode === oldMarker._hashCode) { 622 if (resetIcons || oldMarker._zoomLevel !== zoom || cluster.lastMarker.data.forceIconRedraw) { 623 _this.PrepareLeafletMarker(oldMarker, cluster.lastMarker.data, cluster.lastMarker.category); 624 if (cluster.lastMarker.data.forceIconRedraw) { 625 cluster.lastMarker.data.forceIconRedraw = false; 626 } 627 } 628 oldMarker.setLatLng(position); 629 m = oldMarker; 630 } 631 else if (cluster.population > 1 && data._leafletOldPopulation > 1 && (oldMarker._zoomLevel === zoom || 632 data._leafletPosition.equals(position))) { 633 oldMarker.setLatLng(position); 634 if (resetIcons || cluster.population != data._leafletOldPopulation || 635 cluster.hashCode !== data._leafletOldHashCode) { 636 var boundsCopy = {}; 637 L.Util.extend(boundsCopy, cluster.bounds); 638 oldMarker._leafletClusterBounds = boundsCopy; 639 oldMarker.setIcon(_this.BuildLeafletClusterIcon(cluster)); 640 } 641 data._leafletOldPopulation = cluster.population; 642 data._leafletOldHashCode = cluster.hashCode; 643 m = oldMarker; 644 } 645 } 646 if (!m) { 647 if (cluster.population === 1) { 648 clusterCreationListPopOne.push(cluster); 649 } 650 else { 651 clusterCreationList.push(cluster); 652 } 653 data._leafletPosition = position; 654 data._leafletOldPopulation = cluster.population; 655 data._leafletOldHashCode = cluster.hashCode; 656 } 657 else { 658 m._removeFromMap = false;
659 newObjectsOnMap.push(cluster); 660 m._zoomLevel = zoom; 661 m._hashCode = cluster.hashCode; 662 m._population = cluster.population; 663 data._leafletMarker = m; 664 data._leafletPosition = position; 665 } 666 }); 667 clusterCreationList = clusterCreationListPopOne.concat(clusterCreationList); 668 for (i = 0, l = objectsOnMap.length; i < l; ++i) { 669 icluster = objectsOnMap[i]; 670 var idata = icluster.data; 671 marker = idata._leafletMarker; 672 if (idata._leafletMarker._removeFromMap) { 673 var remove = true; 674 if (marker._zoomLevel === zoom) { 675 var pa = icluster.averagePosition; 676 latMargin = (icluster.bounds.maxLat - icluster.bounds.minLat) * marginRatio, 677 lngMargin = (icluster.bounds.maxLng - icluster.bounds.minLng) * marginRatio; 678 for (j = 0, ll = clusterCreationList.length; j < ll; ++j) { 679 var jcluster = clusterCreationList[j], jdata = jcluster.data; 680 if (marker._population === 1 && jcluster.population === 1 && 681 marker._hashCode === jcluster.hashCode) { 682 if (resetIcons || jcluster.lastMarker.data.forceIconRedraw) { 683 this.PrepareLeafletMarker(marker, jcluster.lastMarker.data, jcluster.lastMarker.category); 684 if (jcluster.lastMarker.data.forceIconRedraw) { 685 jcluster.lastMarker.data.forceIconRedraw = false; 686 } 687 } 688 marker.setLatLng(jdata._leafletPosition); 689 remove = false; 690 } 691 else { 692 var pb = jcluster.averagePosition; 693 var oldMinLng = pa.lng - lngMargin, newMaxLng = pb.lng + lngMargin; 694 oldMaxLng = pa.lng + lngMargin; 695 oldMinLat = pa.lat - latMargin; 696 oldMaxLat = pa.lat + latMargin; 697 newMinLng = pb.lng - lngMargin; 698 newMinLat = pb.lat - latMargin; 699 newMaxLat = pb.lat + latMargin; 700 if ((marker._population > 1 && jcluster.population > 1) && 701 (oldMaxLng > newMinLng && oldMinLng < newMaxLng && oldMaxLat > newMinLat && oldMinLat < newMaxLat)) { 702 marker.setLatLng(jdata._leafletPosition); 703 marker.setIcon(this.BuildLeafletClusterIcon(jcluster)); 704 var poisson = {}; 705 L.Util.extend(poisson, jcluster.bounds); 706 marker._leafletClusterBounds = poisson; 707 jdata._leafletOldPopulation = jcluster.population; 708 jdata._leafletOldHashCode = jcluster.hashCode; 709 marker._population = jcluster.population; 710 remove = false; 711 } 712 } 713 if (!remove) { 714 jdata._leafletMarker = marker; 715 marker._removeFromMap = false; 716 newObjectsOnMap.push(jcluster); 717 clusterCreationList.splice(j, 1); 718 --j; 719 --ll; 720 break; 721 } 722 } 723 } 724 if (remove) { 725 if (!marker._removeFromMap) 726 console.error("wtf"); 727 } 728 } 729 } 730 for (i = 0, l = clusterCreationList.length; i < l; ++i) { 731 icluster = clusterCreationList[i], 732 idata = icluster.data; 733 var iposition = idata._leafletPosition; 734 var creationMarker; 735 if (icluster.population === 1) { 736 creationMarker = this.BuildLeafletMarker(icluster.lastMarker, iposition); 737 } 738 else { 739 creationMarker = this.BuildLeafletCluster(icluster, iposition); 740 } 741 creationMarker.addTo(map); 742 creationMarker.setOpacity(0); 743 opacityUpdateList.push(creationMarker); 744 idata._leafletMarker = creationMarker; 745 creationMarker._zoomLevel = zoom; 746 creationMarker._hashCode = icluster.hashCode; 747 creationMarker._population = icluster.population; 748 newObjectsOnMap.push(icluster); 749 } 750 window.setTimeout(function () { 751 for (i = 0, l = opacityUpdateList.length; i < l; ++i) { 752 var m = opacityUpdateList[i]; 753 if (m._icon) 754 L.DomUtil.addClass(m._icon, "prunecluster-anim"); 755 if (m._shadow) 756 L.DomUtil.addClass(m._shadow, "prunecluster-anim"); 757 m.setOpacity(1); 758 } 759 }, 1); 760 if (this._hardMove) { 761 for (i = 0, l = markersOnMap.length; i < l; ++i) { 762 marker = markersOnMap[i]; 763 if (marker._removeFromMap) { 764 map.removeLayer(marker); 765 } 766 } 767 } 768 else { 769 if (this._removeTimeoutId !== 0) { 770 window.clearTimeout(this._removeTimeoutId); 771 for (i = 0, l = this._markersRemoveListTimeout.length; i < l; ++i) { 772 map.removeLayer(this._markersRemoveListTimeout[i]); 773 } 774 } 775 var toRemove = []; 776 for (i = 0, l = markersOnMap.length; i < l; ++i) { 777 marker = markersOnMap[i]; 778 if (marker._removeFromMap) { 779 marker.setOpacity(0); 780 toRemove.push(marker); 781 } 782 } 783 if (toRemove.length > 0) { 784 this._removeTimeoutId = window.setTimeout(function () { 785 for (i = 0, l = toRemove.length; i < l; ++i) { 786 map.removeLayer(toRemove[i]); 787 } 788 _this._removeTimeoutId = 0; 789 }, 300); 790 } 791 this._markersRemoveListTimeout = toRemove; 792 } 793 this._objectsOnMap = newObjectsOnMap; 794 this._hardMove = false;
795 this._resetIcons = false; 796 }, 797 FitBounds: function (withFiltered) { 798 if (withFiltered === void 0) { withFiltered = true; } 799 var bounds = this.Cluster.ComputeGlobalBounds(withFiltered); 800 if (bounds) { 801 this._map.fitBounds(new L.LatLngBounds(new L.LatLng(bounds.minLat, bounds.maxLng), new L.LatLng(bounds.maxLat, bounds.minLng))); 802 } 803 }, 804 GetMarkers: function () { 805 return this.Cluster.GetMarkers(); 806 }, 807 RedrawIcons: function (processView) { 808 if (processView === void 0) { processView = true; } 809 this._resetIcons = true; 810 if (processView) { 811 this.ProcessView(); 812 } 813 } 814}); 815var PruneClusterLeafletSpiderfier = (L.Layer ? L.Layer : L.Class).extend({ 816 _2PI: Math.PI * 2, 817 _circleFootSeparation: 25, 818 _circleStartAngle: Math.PI / 6, 819 _spiralFootSeparation: 28, 820 _spiralLengthStart: 11, 821 _spiralLengthFactor: 5, 822 _spiralCountTrigger: 8, 823 spiderfyDistanceMultiplier: 1, 824 initialize: function (cluster) { 825 this._cluster = cluster; 826 this._currentMarkers = []; 827 this._multiLines = !!L.multiPolyline; 828 this._lines = this._multiLines ? 829 L.multiPolyline([], { weight: 1.5, color: '#222' }) : 830 L.polyline([], { weight: 1.5, color: '#222' }); 831 }, 832 onAdd: function (map) { 833 this._map = map; 834 this._map.on('overlappingmarkers', this.Spiderfy, this); 835 this._map.on('click', this.Unspiderfy, this); 836 this._map.on('zoomend', this.Unspiderfy, this); 837 }, 838 Spiderfy: function (data) { 839 var _this = this; 840 if (data.cluster !== this._cluster) { 841 return; 842 } 843 this.Unspiderfy(); 844 var markers = data.markers.filter(function (marker) { 845 return !marker.filtered; 846 }); 847 this._currentCenter = data.center; 848 var centerPoint = this._map.latLngToLayerPoint(data.center); 849 var points; 850 if (markers.length >= this._spiralCountTrigger) { 851 points = this._generatePointsSpiral(markers.length, centerPoint); 852 } 853 else { 854 if (this._multiLines) { 855 centerPoint.y += 10; 856 } 857 points = this._generatePointsCircle(markers.length, centerPoint); 858 } 859 var polylines = []; 860 var leafletMarkers = []; 861 var projectedPoints = []; 862 for (var i = 0, l = points.length; i < l; ++i) { 863 var pos = this._map.layerPointToLatLng(points[i]); 864 var m = this._cluster.BuildLeafletMarker(markers[i], data.center); 865 m.setZIndexOffset(5000); 866 m.setOpacity(0); 867 this._currentMarkers.push(m); 868 this._map.addLayer(m); 869 leafletMarkers.push(m); 870 projectedPoints.push(pos); 871 } 872 window.setTimeout(function () { 873 for (i = 0, l = points.length; i < l; ++i) { 874 leafletMarkers[i].setLatLng(projectedPoints[i]) 875 .setOpacity(1); 876 } 877 var startTime = +new Date(); 878 var interval = 42, duration = 290; 879 var anim = window.setInterval(function () { 880 polylines = []; 881 var now = +new Date(); 882 var d = now - startTime; 883 if (d >= duration) { 884 window.clearInterval(anim); 885 stepRatio = 1.0; 886 } 887 else { 888 var stepRatio = d / duration; 889 } 890 var center = data.center; 891 for (i = 0, l = points.length; i < l; ++i) { 892 var p = projectedPoints[i], diffLat = p.lat - center.lat, diffLng = p.lng - center.lng; 893 polylines.push([center, new L.LatLng(center.lat + diffLat * stepRatio, center.lng + diffLng * stepRatio)]); 894 } 895 _this._lines.setLatLngs(polylines); 896 }, interval); 897 }, 1); 898 this._lines.setLatLngs(polylines); 899 this._map.addLayer(this._lines); 900 if (data.marker) { 901 this._clusterMarker = data.marker.setOpacity(0.3); 902 } 903 }, 904 _generatePointsCircle: function (count, centerPt) { 905 var circumference = this.spiderfyDistanceMultiplier * this._circleFootSeparation * (2 + count), legLength = cir
905cumference / this._2PI, angleStep = this._2PI / count, res = [], i, angle; 906 res.length = count; 907 for (i = count - 1; i >= 0; i--) { 908 angle = this._circleStartAngle + i * angleStep; 909 res[i] = new L.Point(Math.round(centerPt.x + legLength * Math.cos(angle)), Math.round(centerPt.y + legLength * Math.sin(angle))); 910 } 911 return res; 912 }, 913 _generatePointsSpiral: function (count, centerPt) { 914 var legLength = this.spiderfyDistanceMultiplier * this._spiralLengthStart, separation = this.spiderfyDistanceMultiplier * this._spiralFootSeparation, lengthFactor = this.spiderfyDistanceMultiplier * this._spiralLengthFactor, angle = 0, res = [], i; 915 res.length = count; 916 for (i = count - 1; i >= 0; i--) { 917 angle += separation / legLength + i * 0.0005; 918 res[i] = new L.Point(Math.round(centerPt.x + legLength * Math.cos(angle)), Math.round(centerPt.y + legLength * Math.sin(angle))); 919 legLength += this._2PI * lengthFactor / angle; 920 } 921 return res; 922 }, 923 Unspiderfy: function () { 924 var _this = this; 925 for (var i = 0, l = this._currentMarkers.length; i < l; ++i) { 926 this._currentMarkers[i].setLatLng(this._currentCenter).setOpacity(0); 927 } 928 var markers = this._currentMarkers; 929 window.setTimeout(function () { 930 for (i = 0, l = markers.length; i < l; ++i) { 931 _this._map.removeLayer(markers[i]); 932 } 933 }, 300); 934 this._currentMarkers = []; 935 this._map.removeLayer(this._lines); 936 if (this._clusterMarker) { 937 this._clusterMarker.setOpacity(1); 938 } 939 }, 940 onRemove: function (map) { 941 this.Unspiderfy(); 942 map.off('overlappingmarkers', this.Spiderfy, this); 943 map.off('click', this.Unspiderfy, this); 944 map.off('zoomend', this.Unspiderfy, this); 945 } 946}); 947//# sourceMappingURL=PruneCluster.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.