@react-google-maps/marker-clusterer 2.3.0
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.
- package/README.md +12 -0
- package/dist/cjs.js +942 -0
- package/dist/cjs.js.map +1 -0
- package/dist/cjs.min.js +2 -0
- package/dist/cjs.min.js.map +1 -0
- package/dist/esm.js +936 -0
- package/dist/esm.js.map +1 -0
- package/dist/esm.min.js +2 -0
- package/dist/esm.min.js.map +1 -0
- package/dist/index.d.ts +218 -0
- package/dist/umd.js +948 -0
- package/dist/umd.js.map +1 -0
- package/dist/umd.min.js +2 -0
- package/dist/umd.min.js.map +1 -0
- package/package.json +98 -0
- package/src/Cluster.tsx +208 -0
- package/src/ClusterIcon.tsx +371 -0
- package/src/Clusterer.tsx +727 -0
- package/src/__tests__/clusterer.test.ts +84 -0
- package/src/index.ts +51 -0
- package/src/setup-tests.js +356 -0
- package/src/types.tsx +47 -0
package/dist/cjs.js
ADDED
|
@@ -0,0 +1,942 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var ClusterIcon = /** @class */ (function () {
|
|
6
|
+
function ClusterIcon(cluster, styles) {
|
|
7
|
+
cluster.getClusterer().extend(ClusterIcon, google.maps.OverlayView);
|
|
8
|
+
this.cluster = cluster;
|
|
9
|
+
this.className = this.cluster.getClusterer().getClusterClass();
|
|
10
|
+
this.styles = styles;
|
|
11
|
+
this.center = undefined;
|
|
12
|
+
this.div = null;
|
|
13
|
+
this.sums = null;
|
|
14
|
+
this.visible = false;
|
|
15
|
+
this.boundsChangedListener = null;
|
|
16
|
+
this.url = '';
|
|
17
|
+
this.height = 0;
|
|
18
|
+
this.width = 0;
|
|
19
|
+
this.anchorText = [0, 0];
|
|
20
|
+
this.anchorIcon = [0, 0];
|
|
21
|
+
this.textColor = 'black';
|
|
22
|
+
this.textSize = 11;
|
|
23
|
+
this.textDecoration = 'none';
|
|
24
|
+
this.fontWeight = 'bold';
|
|
25
|
+
this.fontStyle = 'normal';
|
|
26
|
+
this.fontFamily = 'Arial,sans-serif';
|
|
27
|
+
this.backgroundPosition = '0 0';
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
29
|
+
// @ts-ignore
|
|
30
|
+
this.setMap(cluster.getMap()); // Note: this causes onAdd to be called
|
|
31
|
+
}
|
|
32
|
+
ClusterIcon.prototype.onAdd = function () {
|
|
33
|
+
var _this = this;
|
|
34
|
+
var cMouseDownInCluster;
|
|
35
|
+
var cDraggingMapByCluster;
|
|
36
|
+
this.div = document.createElement('div');
|
|
37
|
+
this.div.className = this.className;
|
|
38
|
+
if (this.visible) {
|
|
39
|
+
this.show();
|
|
40
|
+
}
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
42
|
+
// @ts-ignore
|
|
43
|
+
this.getPanes().overlayMouseTarget.appendChild(this.div);
|
|
44
|
+
// Fix for Issue 157
|
|
45
|
+
this.boundsChangedListener = google.maps.event.addListener(
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
47
|
+
// @ts-ignore
|
|
48
|
+
this.getMap(), 'boundschanged', function boundsChanged() {
|
|
49
|
+
cDraggingMapByCluster = cMouseDownInCluster;
|
|
50
|
+
});
|
|
51
|
+
google.maps.event.addDomListener(this.div, 'mousedown', function onMouseDown() {
|
|
52
|
+
cMouseDownInCluster = true;
|
|
53
|
+
cDraggingMapByCluster = false;
|
|
54
|
+
});
|
|
55
|
+
// eslint-disable-next-line @getify/proper-arrows/this, @getify/proper-arrows/name
|
|
56
|
+
google.maps.event.addDomListener(this.div, 'click',
|
|
57
|
+
// eslint-disable-next-line @getify/proper-arrows/this, @getify/proper-arrows/name
|
|
58
|
+
function (event) {
|
|
59
|
+
cMouseDownInCluster = false;
|
|
60
|
+
if (!cDraggingMapByCluster) {
|
|
61
|
+
var markerClusterer_1 = _this.cluster.getClusterer();
|
|
62
|
+
/**
|
|
63
|
+
* This event is fired when a cluster marker is clicked.
|
|
64
|
+
* @name MarkerClusterer#click
|
|
65
|
+
* @param {Cluster} c The cluster that was clicked.
|
|
66
|
+
* @event
|
|
67
|
+
*/
|
|
68
|
+
google.maps.event.trigger(markerClusterer_1, 'click', _this.cluster);
|
|
69
|
+
google.maps.event.trigger(markerClusterer_1, 'clusterclick', _this.cluster); // deprecated name
|
|
70
|
+
// The default click handler follows. Disable it by setting
|
|
71
|
+
// the zoomOnClick property to false.
|
|
72
|
+
if (markerClusterer_1.getZoomOnClick()) {
|
|
73
|
+
// Zoom into the cluster.
|
|
74
|
+
var maxZoom_1 = markerClusterer_1.getMaxZoom();
|
|
75
|
+
var bounds_1 = _this.cluster.getBounds();
|
|
76
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
77
|
+
// @ts-ignore
|
|
78
|
+
markerClusterer_1.getMap().fitBounds(bounds_1);
|
|
79
|
+
// There is a fix for Issue 170 here:
|
|
80
|
+
setTimeout(function timeout() {
|
|
81
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
82
|
+
// @ts-ignore
|
|
83
|
+
markerClusterer_1.getMap().fitBounds(bounds_1);
|
|
84
|
+
// Don't zoom beyond the max zoom level
|
|
85
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
86
|
+
// @ts-ignore
|
|
87
|
+
if (maxZoom_1 !== null && markerClusterer_1.getMap().getZoom() > maxZoom_1) {
|
|
88
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
89
|
+
// @ts-ignore
|
|
90
|
+
markerClusterer_1.getMap().setZoom(maxZoom_1 + 1);
|
|
91
|
+
}
|
|
92
|
+
}, 100);
|
|
93
|
+
}
|
|
94
|
+
// Prevent event propagation to the map:
|
|
95
|
+
event.cancelBubble = true;
|
|
96
|
+
if (event.stopPropagation) {
|
|
97
|
+
event.stopPropagation();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
google.maps.event.addDomListener(this.div, 'mouseover',
|
|
102
|
+
// eslint-disable-next-line @getify/proper-arrows/this, @getify/proper-arrows/name
|
|
103
|
+
function () {
|
|
104
|
+
/**
|
|
105
|
+
* This event is fired when the mouse moves over a cluster marker.
|
|
106
|
+
* @name MarkerClusterer#mouseover
|
|
107
|
+
* @param {Cluster} c The cluster that the mouse moved over.
|
|
108
|
+
* @event
|
|
109
|
+
*/
|
|
110
|
+
google.maps.event.trigger(_this.cluster.getClusterer(), 'mouseover', _this.cluster);
|
|
111
|
+
});
|
|
112
|
+
// eslint-disable-next-line @getify/proper-arrows/this, @getify/proper-arrows/name
|
|
113
|
+
google.maps.event.addDomListener(this.div, 'mouseout',
|
|
114
|
+
// eslint-disable-next-line @getify/proper-arrows/this, @getify/proper-arrows/name
|
|
115
|
+
function () {
|
|
116
|
+
/**
|
|
117
|
+
* This event is fired when the mouse moves out of a cluster marker.
|
|
118
|
+
* @name MarkerClusterer#mouseout
|
|
119
|
+
* @param {Cluster} c The cluster that the mouse moved out of.
|
|
120
|
+
* @event
|
|
121
|
+
*/
|
|
122
|
+
google.maps.event.trigger(_this.cluster.getClusterer(), 'mouseout', _this.cluster);
|
|
123
|
+
});
|
|
124
|
+
};
|
|
125
|
+
ClusterIcon.prototype.onRemove = function () {
|
|
126
|
+
if (this.div && this.div.parentNode) {
|
|
127
|
+
this.hide();
|
|
128
|
+
if (this.boundsChangedListener !== null) {
|
|
129
|
+
google.maps.event.removeListener(this.boundsChangedListener);
|
|
130
|
+
}
|
|
131
|
+
google.maps.event.clearInstanceListeners(this.div);
|
|
132
|
+
this.div.parentNode.removeChild(this.div);
|
|
133
|
+
this.div = null;
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
ClusterIcon.prototype.draw = function () {
|
|
137
|
+
if (this.visible && this.div !== null && this.center) {
|
|
138
|
+
var _a = this.getPosFromLatLng(this.center), x = _a.x, y = _a.y;
|
|
139
|
+
this.div.style.top = y + 'px';
|
|
140
|
+
this.div.style.left = x + 'px';
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
ClusterIcon.prototype.hide = function () {
|
|
144
|
+
if (this.div) {
|
|
145
|
+
this.div.style.display = 'none';
|
|
146
|
+
}
|
|
147
|
+
this.visible = false;
|
|
148
|
+
};
|
|
149
|
+
ClusterIcon.prototype.show = function () {
|
|
150
|
+
if (this.div && this.center) {
|
|
151
|
+
var img = '', divTitle = '';
|
|
152
|
+
// NOTE: values must be specified in px units
|
|
153
|
+
var bp = this.backgroundPosition.split(' ');
|
|
154
|
+
var spriteH = parseInt(bp[0].replace(/^\s+|\s+$/g, ''), 10);
|
|
155
|
+
var spriteV = parseInt(bp[1].replace(/^\s+|\s+$/g, ''), 10);
|
|
156
|
+
var pos = this.getPosFromLatLng(this.center);
|
|
157
|
+
if (this.sums === null || typeof this.sums.title === 'undefined' || this.sums.title === '') {
|
|
158
|
+
divTitle = this.cluster.getClusterer().getTitle();
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
divTitle = this.sums.title;
|
|
162
|
+
}
|
|
163
|
+
this.div.style.cssText = this.createCss(pos);
|
|
164
|
+
img =
|
|
165
|
+
"<img alt='" +
|
|
166
|
+
divTitle +
|
|
167
|
+
"' src='" +
|
|
168
|
+
this.url +
|
|
169
|
+
"' style='position: absolute; top: " +
|
|
170
|
+
spriteV +
|
|
171
|
+
'px; left: ' +
|
|
172
|
+
spriteH +
|
|
173
|
+
'px; ';
|
|
174
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
175
|
+
//@ts-ignore
|
|
176
|
+
if (!this.cluster.getClusterer().enableRetinaIcons) {
|
|
177
|
+
img +=
|
|
178
|
+
'clip: rect(' +
|
|
179
|
+
-1 * spriteV +
|
|
180
|
+
'px, ' +
|
|
181
|
+
(-1 * spriteH + this.width) +
|
|
182
|
+
'px, ' +
|
|
183
|
+
(-1 * spriteV + this.height) +
|
|
184
|
+
'px, ' +
|
|
185
|
+
-1 * spriteH +
|
|
186
|
+
'px);';
|
|
187
|
+
}
|
|
188
|
+
img += "'>";
|
|
189
|
+
this.div.innerHTML =
|
|
190
|
+
img +
|
|
191
|
+
"<div style='" +
|
|
192
|
+
'position: absolute;' +
|
|
193
|
+
'top: ' +
|
|
194
|
+
this.anchorText[0] +
|
|
195
|
+
'px;' +
|
|
196
|
+
'left: ' +
|
|
197
|
+
this.anchorText[1] +
|
|
198
|
+
'px;' +
|
|
199
|
+
'color: ' +
|
|
200
|
+
this.textColor +
|
|
201
|
+
';' +
|
|
202
|
+
'font-size: ' +
|
|
203
|
+
this.textSize +
|
|
204
|
+
'px;' +
|
|
205
|
+
'font-family: ' +
|
|
206
|
+
this.fontFamily +
|
|
207
|
+
';' +
|
|
208
|
+
'font-weight: ' +
|
|
209
|
+
this.fontWeight +
|
|
210
|
+
';' +
|
|
211
|
+
'font-style: ' +
|
|
212
|
+
this.fontStyle +
|
|
213
|
+
';' +
|
|
214
|
+
'text-decoration: ' +
|
|
215
|
+
this.textDecoration +
|
|
216
|
+
';' +
|
|
217
|
+
'text-align: center;' +
|
|
218
|
+
'width: ' +
|
|
219
|
+
this.width +
|
|
220
|
+
'px;' +
|
|
221
|
+
'line-height:' +
|
|
222
|
+
this.height +
|
|
223
|
+
'px;' +
|
|
224
|
+
"'>" +
|
|
225
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
226
|
+
// @ts-ignore
|
|
227
|
+
this.sums.text +
|
|
228
|
+
'</div>';
|
|
229
|
+
this.div.title = divTitle;
|
|
230
|
+
this.div.style.display = '';
|
|
231
|
+
}
|
|
232
|
+
this.visible = true;
|
|
233
|
+
};
|
|
234
|
+
ClusterIcon.prototype.useStyle = function (sums) {
|
|
235
|
+
this.sums = sums;
|
|
236
|
+
var style = this.styles[Math.min(this.styles.length - 1, Math.max(0, sums.index - 1))];
|
|
237
|
+
this.url = style.url;
|
|
238
|
+
this.height = style.height;
|
|
239
|
+
this.width = style.width;
|
|
240
|
+
if (style.className)
|
|
241
|
+
this.className = this.className + " " + style.className;
|
|
242
|
+
this.anchorText = style.anchorText || [0, 0];
|
|
243
|
+
this.anchorIcon = style.anchorIcon || [this.height / 2, this.width / 2];
|
|
244
|
+
this.textColor = style.textColor || 'black';
|
|
245
|
+
this.textSize = style.textSize || 11;
|
|
246
|
+
this.textDecoration = style.textDecoration || 'none';
|
|
247
|
+
this.fontWeight = style.fontWeight || 'bold';
|
|
248
|
+
this.fontStyle = style.fontStyle || 'normal';
|
|
249
|
+
this.fontFamily = style.fontFamily || 'Arial,sans-serif';
|
|
250
|
+
this.backgroundPosition = style.backgroundPosition || '0 0';
|
|
251
|
+
};
|
|
252
|
+
ClusterIcon.prototype.setCenter = function (center) {
|
|
253
|
+
this.center = center;
|
|
254
|
+
};
|
|
255
|
+
ClusterIcon.prototype.createCss = function (pos) {
|
|
256
|
+
var style = [];
|
|
257
|
+
style.push('cursor: pointer;');
|
|
258
|
+
style.push('position: absolute; top: ' + pos.y + 'px; left: ' + pos.x + 'px;');
|
|
259
|
+
style.push('width: ' + this.width + 'px; height: ' + this.height + 'px;');
|
|
260
|
+
return style.join('');
|
|
261
|
+
};
|
|
262
|
+
ClusterIcon.prototype.getPosFromLatLng = function (latlng) {
|
|
263
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
264
|
+
// @ts-ignore
|
|
265
|
+
var pos = this.getProjection().fromLatLngToDivPixel(latlng);
|
|
266
|
+
pos.x -= this.anchorIcon[1];
|
|
267
|
+
pos.y -= this.anchorIcon[0];
|
|
268
|
+
// pos.x = pos.x
|
|
269
|
+
// pos.y = pos.y
|
|
270
|
+
return pos;
|
|
271
|
+
};
|
|
272
|
+
return ClusterIcon;
|
|
273
|
+
}());
|
|
274
|
+
|
|
275
|
+
var Cluster = /** @class */ (function () {
|
|
276
|
+
function Cluster(markerClusterer) {
|
|
277
|
+
this.markerClusterer = markerClusterer;
|
|
278
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
279
|
+
// @ts-ignore
|
|
280
|
+
this.map = this.markerClusterer.getMap();
|
|
281
|
+
this.gridSize = this.markerClusterer.getGridSize();
|
|
282
|
+
this.minClusterSize = this.markerClusterer.getMinimumClusterSize();
|
|
283
|
+
this.averageCenter = this.markerClusterer.getAverageCenter();
|
|
284
|
+
this.markers = [];
|
|
285
|
+
this.center = undefined;
|
|
286
|
+
this.bounds = null;
|
|
287
|
+
this.clusterIcon = new ClusterIcon(this, this.markerClusterer.getStyles());
|
|
288
|
+
}
|
|
289
|
+
Cluster.prototype.getSize = function () {
|
|
290
|
+
return this.markers.length;
|
|
291
|
+
};
|
|
292
|
+
Cluster.prototype.getMarkers = function () {
|
|
293
|
+
return this.markers;
|
|
294
|
+
};
|
|
295
|
+
Cluster.prototype.getCenter = function () {
|
|
296
|
+
return this.center;
|
|
297
|
+
};
|
|
298
|
+
Cluster.prototype.getMap = function () {
|
|
299
|
+
return this.map;
|
|
300
|
+
};
|
|
301
|
+
Cluster.prototype.getClusterer = function () {
|
|
302
|
+
return this.markerClusterer;
|
|
303
|
+
};
|
|
304
|
+
Cluster.prototype.getBounds = function () {
|
|
305
|
+
var bounds = new google.maps.LatLngBounds(this.center, this.center);
|
|
306
|
+
var markers = this.getMarkers();
|
|
307
|
+
for (var i = 0; i < markers.length; i++) {
|
|
308
|
+
var position = markers[i].getPosition();
|
|
309
|
+
if (position) {
|
|
310
|
+
bounds.extend(position);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return bounds;
|
|
314
|
+
};
|
|
315
|
+
Cluster.prototype.remove = function () {
|
|
316
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
317
|
+
// @ts-ignore
|
|
318
|
+
this.clusterIcon.setMap(null);
|
|
319
|
+
this.markers = [];
|
|
320
|
+
// @ts-ignore
|
|
321
|
+
delete this.markers;
|
|
322
|
+
};
|
|
323
|
+
Cluster.prototype.addMarker = function (marker) {
|
|
324
|
+
if (this.isMarkerAlreadyAdded(marker)) {
|
|
325
|
+
return false;
|
|
326
|
+
}
|
|
327
|
+
if (!this.center) {
|
|
328
|
+
var position = marker.getPosition();
|
|
329
|
+
if (position) {
|
|
330
|
+
this.center = position;
|
|
331
|
+
this.calculateBounds();
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
if (this.averageCenter) {
|
|
336
|
+
var position = marker.getPosition();
|
|
337
|
+
if (position) {
|
|
338
|
+
var length_1 = this.markers.length + 1;
|
|
339
|
+
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);
|
|
340
|
+
this.calculateBounds();
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
marker.isAdded = true;
|
|
345
|
+
this.markers.push(marker);
|
|
346
|
+
var mCount = this.markers.length;
|
|
347
|
+
var maxZoom = this.markerClusterer.getMaxZoom();
|
|
348
|
+
if (maxZoom !== null && this.map.getZoom() > maxZoom) {
|
|
349
|
+
// Zoomed in past max zoom, so show the marker.
|
|
350
|
+
if (marker.getMap() !== this.map) {
|
|
351
|
+
marker.setMap(this.map);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
else if (mCount < this.minClusterSize) {
|
|
355
|
+
// Min cluster size not reached so show the marker.
|
|
356
|
+
if (marker.getMap() !== this.map) {
|
|
357
|
+
marker.setMap(this.map);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
else if (mCount === this.minClusterSize) {
|
|
361
|
+
// Hide the markers that were showing.
|
|
362
|
+
for (var i = 0; i < mCount; i++) {
|
|
363
|
+
this.markers[i].setMap(null);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
marker.setMap(null);
|
|
368
|
+
}
|
|
369
|
+
return true;
|
|
370
|
+
};
|
|
371
|
+
Cluster.prototype.isMarkerInClusterBounds = function (marker) {
|
|
372
|
+
if (this.bounds !== null) {
|
|
373
|
+
var position = marker.getPosition();
|
|
374
|
+
if (position) {
|
|
375
|
+
return this.bounds.contains(position);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return false;
|
|
379
|
+
};
|
|
380
|
+
Cluster.prototype.calculateBounds = function () {
|
|
381
|
+
this.bounds = this.markerClusterer.getExtendedBounds(new google.maps.LatLngBounds(this.center, this.center));
|
|
382
|
+
};
|
|
383
|
+
Cluster.prototype.updateIcon = function () {
|
|
384
|
+
var mCount = this.markers.length;
|
|
385
|
+
var maxZoom = this.markerClusterer.getMaxZoom();
|
|
386
|
+
if (maxZoom !== null && this.map.getZoom() > maxZoom) {
|
|
387
|
+
this.clusterIcon.hide();
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
if (mCount < this.minClusterSize) {
|
|
391
|
+
// Min cluster size not yet reached.
|
|
392
|
+
this.clusterIcon.hide();
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
if (this.center) {
|
|
396
|
+
this.clusterIcon.setCenter(this.center);
|
|
397
|
+
}
|
|
398
|
+
this.clusterIcon.useStyle(this.markerClusterer.getCalculator()(this.markers, this.markerClusterer.getStyles().length));
|
|
399
|
+
this.clusterIcon.show();
|
|
400
|
+
};
|
|
401
|
+
Cluster.prototype.isMarkerAlreadyAdded = function (marker) {
|
|
402
|
+
if (this.markers.includes) {
|
|
403
|
+
return this.markers.includes(marker);
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
for (var i = 0; i < this.markers.length; i++) {
|
|
407
|
+
if (marker === this.markers[i]) {
|
|
408
|
+
return true;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
return false;
|
|
413
|
+
};
|
|
414
|
+
return Cluster;
|
|
415
|
+
}());
|
|
416
|
+
|
|
417
|
+
/* global google */
|
|
418
|
+
/**
|
|
419
|
+
* Supports up to 9007199254740991 (Number.MAX_SAFE_INTEGER) markers
|
|
420
|
+
* which is not a problem as max array length is 4294967296 (2**32)
|
|
421
|
+
*/
|
|
422
|
+
var CALCULATOR = function CALCULATOR(markers, numStyles) {
|
|
423
|
+
var count = markers.length;
|
|
424
|
+
var numberOfDigits = count.toString().length;
|
|
425
|
+
var index = Math.min(numberOfDigits, numStyles);
|
|
426
|
+
return {
|
|
427
|
+
text: count.toString(),
|
|
428
|
+
index: index,
|
|
429
|
+
title: '',
|
|
430
|
+
};
|
|
431
|
+
};
|
|
432
|
+
var BATCH_SIZE = 2000;
|
|
433
|
+
var BATCH_SIZE_IE = 500;
|
|
434
|
+
var IMAGE_PATH = 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m';
|
|
435
|
+
var IMAGE_EXTENSION = 'png';
|
|
436
|
+
var IMAGE_SIZES = [53, 56, 66, 78, 90];
|
|
437
|
+
var CLUSTERER_CLASS = 'cluster';
|
|
438
|
+
var Clusterer = /** @class */ (function () {
|
|
439
|
+
function Clusterer(map, optMarkers, optOptions) {
|
|
440
|
+
if (optMarkers === void 0) { optMarkers = []; }
|
|
441
|
+
if (optOptions === void 0) { optOptions = {}; }
|
|
442
|
+
this.extend(Clusterer, google.maps.OverlayView);
|
|
443
|
+
this.markers = [];
|
|
444
|
+
this.clusters = [];
|
|
445
|
+
this.listeners = [];
|
|
446
|
+
this.activeMap = null;
|
|
447
|
+
this.ready = false;
|
|
448
|
+
this.gridSize = optOptions.gridSize || 60;
|
|
449
|
+
this.minClusterSize = optOptions.minimumClusterSize || 2;
|
|
450
|
+
this.maxZoom = optOptions.maxZoom || null;
|
|
451
|
+
this.styles = optOptions.styles || [];
|
|
452
|
+
this.title = optOptions.title || '';
|
|
453
|
+
this.zoomOnClick = true;
|
|
454
|
+
if (optOptions.zoomOnClick !== undefined) {
|
|
455
|
+
this.zoomOnClick = optOptions.zoomOnClick;
|
|
456
|
+
}
|
|
457
|
+
this.averageCenter = false;
|
|
458
|
+
if (optOptions.averageCenter !== undefined) {
|
|
459
|
+
this.averageCenter = optOptions.averageCenter;
|
|
460
|
+
}
|
|
461
|
+
this.ignoreHidden = false;
|
|
462
|
+
if (optOptions.ignoreHidden !== undefined) {
|
|
463
|
+
this.ignoreHidden = optOptions.ignoreHidden;
|
|
464
|
+
}
|
|
465
|
+
this.enableRetinaIcons = false;
|
|
466
|
+
if (optOptions.enableRetinaIcons !== undefined) {
|
|
467
|
+
this.enableRetinaIcons = optOptions.enableRetinaIcons;
|
|
468
|
+
}
|
|
469
|
+
this.imagePath = optOptions.imagePath || IMAGE_PATH;
|
|
470
|
+
this.imageExtension = optOptions.imageExtension || IMAGE_EXTENSION;
|
|
471
|
+
this.imageSizes = optOptions.imageSizes || IMAGE_SIZES;
|
|
472
|
+
this.calculator = optOptions.calculator || CALCULATOR;
|
|
473
|
+
this.batchSize = optOptions.batchSize || BATCH_SIZE;
|
|
474
|
+
this.batchSizeIE = optOptions.batchSizeIE || BATCH_SIZE_IE;
|
|
475
|
+
this.clusterClass = optOptions.clusterClass || CLUSTERER_CLASS;
|
|
476
|
+
if (navigator.userAgent.toLowerCase().indexOf('msie') !== -1) {
|
|
477
|
+
// Try to avoid IE timeout when processing a huge number of markers:
|
|
478
|
+
this.batchSize = this.batchSizeIE;
|
|
479
|
+
}
|
|
480
|
+
this.timerRefStatic = null;
|
|
481
|
+
this.setupStyles();
|
|
482
|
+
this.addMarkers(optMarkers, true);
|
|
483
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
484
|
+
// @ts-ignore
|
|
485
|
+
this.setMap(map); // Note: this causes onAdd to be called
|
|
486
|
+
}
|
|
487
|
+
Clusterer.prototype.onAdd = function () {
|
|
488
|
+
var _this = this;
|
|
489
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
490
|
+
// @ts-ignore
|
|
491
|
+
this.activeMap = this.getMap();
|
|
492
|
+
this.ready = true;
|
|
493
|
+
this.repaint();
|
|
494
|
+
// Add the map event listeners
|
|
495
|
+
this.listeners = [
|
|
496
|
+
google.maps.event.addListener(
|
|
497
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
498
|
+
// @ts-ignore
|
|
499
|
+
this.getMap(), 'zoom_changed',
|
|
500
|
+
// eslint-disable-next-line @getify/proper-arrows/this, @getify/proper-arrows/name
|
|
501
|
+
function () {
|
|
502
|
+
_this.resetViewport(false);
|
|
503
|
+
// Workaround for this Google bug: when map is at level 0 and "-" of
|
|
504
|
+
// zoom slider is clicked, a "zoom_changed" event is fired even though
|
|
505
|
+
// the map doesn't zoom out any further. In this situation, no "idle"
|
|
506
|
+
// event is triggered so the cluster markers that have been removed
|
|
507
|
+
// do not get redrawn. Same goes for a zoom in at maxZoom.
|
|
508
|
+
if (
|
|
509
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
510
|
+
// @ts-ignore
|
|
511
|
+
_this.getMap().getZoom() === (_this.get('minZoom') || 0) ||
|
|
512
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
513
|
+
// @ts-ignore
|
|
514
|
+
_this.getMap().getZoom() === _this.get('maxZoom')) {
|
|
515
|
+
google.maps.event.trigger(_this, 'idle');
|
|
516
|
+
}
|
|
517
|
+
}),
|
|
518
|
+
google.maps.event.addListener(
|
|
519
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
520
|
+
// @ts-ignore
|
|
521
|
+
this.getMap(), 'idle',
|
|
522
|
+
// eslint-disable-next-line @getify/proper-arrows/this, @getify/proper-arrows/name
|
|
523
|
+
function () {
|
|
524
|
+
_this.redraw();
|
|
525
|
+
}),
|
|
526
|
+
];
|
|
527
|
+
};
|
|
528
|
+
// eslint-disable-next-line @getify/proper-arrows/this
|
|
529
|
+
Clusterer.prototype.onRemove = function () {
|
|
530
|
+
// Put all the managed markers back on the map:
|
|
531
|
+
for (var i = 0; i < this.markers.length; i++) {
|
|
532
|
+
if (this.markers[i].getMap() !== this.activeMap) {
|
|
533
|
+
this.markers[i].setMap(this.activeMap);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
// Remove all clusters:
|
|
537
|
+
for (var i = 0; i < this.clusters.length; i++) {
|
|
538
|
+
this.clusters[i].remove();
|
|
539
|
+
}
|
|
540
|
+
this.clusters = [];
|
|
541
|
+
// Remove map event listeners:
|
|
542
|
+
for (var i = 0; i < this.listeners.length; i++) {
|
|
543
|
+
google.maps.event.removeListener(this.listeners[i]);
|
|
544
|
+
}
|
|
545
|
+
this.listeners = [];
|
|
546
|
+
this.activeMap = null;
|
|
547
|
+
this.ready = false;
|
|
548
|
+
};
|
|
549
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
550
|
+
Clusterer.prototype.draw = function () { };
|
|
551
|
+
Clusterer.prototype.setupStyles = function () {
|
|
552
|
+
if (this.styles.length > 0) {
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
for (var i = 0; i < this.imageSizes.length; i++) {
|
|
556
|
+
this.styles.push({
|
|
557
|
+
url: this.imagePath + (i + 1) + '.' + this.imageExtension,
|
|
558
|
+
height: this.imageSizes[i],
|
|
559
|
+
width: this.imageSizes[i],
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
};
|
|
563
|
+
Clusterer.prototype.fitMapToMarkers = function () {
|
|
564
|
+
var markers = this.getMarkers();
|
|
565
|
+
var bounds = new google.maps.LatLngBounds();
|
|
566
|
+
for (var i = 0; i < markers.length; i++) {
|
|
567
|
+
var position = markers[i].getPosition();
|
|
568
|
+
if (position) {
|
|
569
|
+
bounds.extend(position);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
573
|
+
// @ts-ignore
|
|
574
|
+
this.getMap().fitBounds(bounds);
|
|
575
|
+
};
|
|
576
|
+
Clusterer.prototype.getGridSize = function () {
|
|
577
|
+
return this.gridSize;
|
|
578
|
+
};
|
|
579
|
+
Clusterer.prototype.setGridSize = function (gridSize) {
|
|
580
|
+
this.gridSize = gridSize;
|
|
581
|
+
};
|
|
582
|
+
Clusterer.prototype.getMinimumClusterSize = function () {
|
|
583
|
+
return this.minClusterSize;
|
|
584
|
+
};
|
|
585
|
+
Clusterer.prototype.setMinimumClusterSize = function (minimumClusterSize) {
|
|
586
|
+
this.minClusterSize = minimumClusterSize;
|
|
587
|
+
};
|
|
588
|
+
Clusterer.prototype.getMaxZoom = function () {
|
|
589
|
+
return this.maxZoom;
|
|
590
|
+
};
|
|
591
|
+
Clusterer.prototype.setMaxZoom = function (maxZoom) {
|
|
592
|
+
this.maxZoom = maxZoom;
|
|
593
|
+
};
|
|
594
|
+
Clusterer.prototype.getStyles = function () {
|
|
595
|
+
return this.styles;
|
|
596
|
+
};
|
|
597
|
+
Clusterer.prototype.setStyles = function (styles) {
|
|
598
|
+
this.styles = styles;
|
|
599
|
+
};
|
|
600
|
+
Clusterer.prototype.getTitle = function () {
|
|
601
|
+
return this.title;
|
|
602
|
+
};
|
|
603
|
+
Clusterer.prototype.setTitle = function (title) {
|
|
604
|
+
this.title = title;
|
|
605
|
+
};
|
|
606
|
+
Clusterer.prototype.getZoomOnClick = function () {
|
|
607
|
+
return this.zoomOnClick;
|
|
608
|
+
};
|
|
609
|
+
Clusterer.prototype.setZoomOnClick = function (zoomOnClick) {
|
|
610
|
+
this.zoomOnClick = zoomOnClick;
|
|
611
|
+
};
|
|
612
|
+
Clusterer.prototype.getAverageCenter = function () {
|
|
613
|
+
return this.averageCenter;
|
|
614
|
+
};
|
|
615
|
+
Clusterer.prototype.setAverageCenter = function (averageCenter) {
|
|
616
|
+
this.averageCenter = averageCenter;
|
|
617
|
+
};
|
|
618
|
+
Clusterer.prototype.getIgnoreHidden = function () {
|
|
619
|
+
return this.ignoreHidden;
|
|
620
|
+
};
|
|
621
|
+
Clusterer.prototype.setIgnoreHidden = function (ignoreHidden) {
|
|
622
|
+
this.ignoreHidden = ignoreHidden;
|
|
623
|
+
};
|
|
624
|
+
Clusterer.prototype.getEnableRetinaIcons = function () {
|
|
625
|
+
return this.enableRetinaIcons;
|
|
626
|
+
};
|
|
627
|
+
Clusterer.prototype.setEnableRetinaIcons = function (enableRetinaIcons) {
|
|
628
|
+
this.enableRetinaIcons = enableRetinaIcons;
|
|
629
|
+
};
|
|
630
|
+
Clusterer.prototype.getImageExtension = function () {
|
|
631
|
+
return this.imageExtension;
|
|
632
|
+
};
|
|
633
|
+
Clusterer.prototype.setImageExtension = function (imageExtension) {
|
|
634
|
+
this.imageExtension = imageExtension;
|
|
635
|
+
};
|
|
636
|
+
Clusterer.prototype.getImagePath = function () {
|
|
637
|
+
return this.imagePath;
|
|
638
|
+
};
|
|
639
|
+
Clusterer.prototype.setImagePath = function (imagePath) {
|
|
640
|
+
this.imagePath = imagePath;
|
|
641
|
+
};
|
|
642
|
+
Clusterer.prototype.getImageSizes = function () {
|
|
643
|
+
return this.imageSizes;
|
|
644
|
+
};
|
|
645
|
+
Clusterer.prototype.setImageSizes = function (imageSizes) {
|
|
646
|
+
this.imageSizes = imageSizes;
|
|
647
|
+
};
|
|
648
|
+
Clusterer.prototype.getCalculator = function () {
|
|
649
|
+
return this.calculator;
|
|
650
|
+
};
|
|
651
|
+
Clusterer.prototype.setCalculator = function (calculator) {
|
|
652
|
+
this.calculator = calculator;
|
|
653
|
+
};
|
|
654
|
+
Clusterer.prototype.getBatchSizeIE = function () {
|
|
655
|
+
return this.batchSizeIE;
|
|
656
|
+
};
|
|
657
|
+
Clusterer.prototype.setBatchSizeIE = function (batchSizeIE) {
|
|
658
|
+
this.batchSizeIE = batchSizeIE;
|
|
659
|
+
};
|
|
660
|
+
Clusterer.prototype.getClusterClass = function () {
|
|
661
|
+
return this.clusterClass;
|
|
662
|
+
};
|
|
663
|
+
Clusterer.prototype.setClusterClass = function (clusterClass) {
|
|
664
|
+
this.clusterClass = clusterClass;
|
|
665
|
+
};
|
|
666
|
+
Clusterer.prototype.getMarkers = function () {
|
|
667
|
+
return this.markers;
|
|
668
|
+
};
|
|
669
|
+
Clusterer.prototype.getTotalMarkers = function () {
|
|
670
|
+
return this.markers.length;
|
|
671
|
+
};
|
|
672
|
+
Clusterer.prototype.getClusters = function () {
|
|
673
|
+
return this.clusters;
|
|
674
|
+
};
|
|
675
|
+
Clusterer.prototype.getTotalClusters = function () {
|
|
676
|
+
return this.clusters.length;
|
|
677
|
+
};
|
|
678
|
+
Clusterer.prototype.addMarker = function (marker, optNoDraw) {
|
|
679
|
+
this.pushMarkerTo(marker);
|
|
680
|
+
if (!optNoDraw) {
|
|
681
|
+
this.redraw();
|
|
682
|
+
}
|
|
683
|
+
};
|
|
684
|
+
Clusterer.prototype.addMarkers = function (markers, optNoDraw) {
|
|
685
|
+
for (var key in markers) {
|
|
686
|
+
if (markers.hasOwnProperty(key)) {
|
|
687
|
+
this.pushMarkerTo(markers[key]);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
if (!optNoDraw) {
|
|
691
|
+
this.redraw();
|
|
692
|
+
}
|
|
693
|
+
};
|
|
694
|
+
Clusterer.prototype.pushMarkerTo = function (marker) {
|
|
695
|
+
var _this = this;
|
|
696
|
+
// If the marker is draggable add a listener so we can update the clusters on the dragend:
|
|
697
|
+
if (marker.getDraggable()) {
|
|
698
|
+
// eslint-disable-next-line @getify/proper-arrows/name, @getify/proper-arrows/this
|
|
699
|
+
google.maps.event.addListener(marker, 'dragend', function () {
|
|
700
|
+
if (_this.ready) {
|
|
701
|
+
marker.isAdded = false;
|
|
702
|
+
_this.repaint();
|
|
703
|
+
}
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
marker.isAdded = false;
|
|
707
|
+
this.markers.push(marker);
|
|
708
|
+
};
|
|
709
|
+
Clusterer.prototype.removeMarker_ = function (marker) {
|
|
710
|
+
var index = -1;
|
|
711
|
+
if (this.markers.indexOf) {
|
|
712
|
+
index = this.markers.indexOf(marker);
|
|
713
|
+
}
|
|
714
|
+
else {
|
|
715
|
+
for (var i = 0; i < this.markers.length; i++) {
|
|
716
|
+
if (marker === this.markers[i]) {
|
|
717
|
+
index = i;
|
|
718
|
+
break;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
if (index === -1) {
|
|
723
|
+
// Marker is not in our list of markers, so do nothing:
|
|
724
|
+
return false;
|
|
725
|
+
}
|
|
726
|
+
marker.setMap(null);
|
|
727
|
+
this.markers.splice(index, 1); // Remove the marker from the list of managed markers
|
|
728
|
+
return true;
|
|
729
|
+
};
|
|
730
|
+
Clusterer.prototype.removeMarker = function (marker, optNoDraw) {
|
|
731
|
+
var removed = this.removeMarker_(marker);
|
|
732
|
+
if (!optNoDraw && removed) {
|
|
733
|
+
this.repaint();
|
|
734
|
+
}
|
|
735
|
+
return removed;
|
|
736
|
+
};
|
|
737
|
+
Clusterer.prototype.removeMarkers = function (markers, optNoDraw) {
|
|
738
|
+
var removed = false;
|
|
739
|
+
for (var i = 0; i < markers.length; i++) {
|
|
740
|
+
removed = removed || this.removeMarker_(markers[i]);
|
|
741
|
+
}
|
|
742
|
+
if (!optNoDraw && removed) {
|
|
743
|
+
this.repaint();
|
|
744
|
+
}
|
|
745
|
+
return removed;
|
|
746
|
+
};
|
|
747
|
+
Clusterer.prototype.clearMarkers = function () {
|
|
748
|
+
this.resetViewport(true);
|
|
749
|
+
this.markers = [];
|
|
750
|
+
};
|
|
751
|
+
Clusterer.prototype.repaint = function () {
|
|
752
|
+
var oldClusters = this.clusters.slice();
|
|
753
|
+
this.clusters = [];
|
|
754
|
+
this.resetViewport(false);
|
|
755
|
+
this.redraw();
|
|
756
|
+
// Remove the old clusters.
|
|
757
|
+
// Do it in a timeout to prevent blinking effect.
|
|
758
|
+
setTimeout(function timeout() {
|
|
759
|
+
for (var i = 0; i < oldClusters.length; i++) {
|
|
760
|
+
oldClusters[i].remove();
|
|
761
|
+
}
|
|
762
|
+
}, 0);
|
|
763
|
+
};
|
|
764
|
+
Clusterer.prototype.getExtendedBounds = function (bounds) {
|
|
765
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
766
|
+
// @ts-ignore
|
|
767
|
+
var projection = this.getProjection();
|
|
768
|
+
// Convert the points to pixels and the extend out by the grid size.
|
|
769
|
+
var trPix = projection.fromLatLngToDivPixel(
|
|
770
|
+
// Turn the bounds into latlng.
|
|
771
|
+
new google.maps.LatLng(bounds.getNorthEast().lat(), bounds.getNorthEast().lng()));
|
|
772
|
+
trPix.x += this.gridSize;
|
|
773
|
+
trPix.y -= this.gridSize;
|
|
774
|
+
var blPix = projection.fromLatLngToDivPixel(
|
|
775
|
+
// Turn the bounds into latlng.
|
|
776
|
+
new google.maps.LatLng(bounds.getSouthWest().lat(), bounds.getSouthWest().lng()));
|
|
777
|
+
blPix.x -= this.gridSize;
|
|
778
|
+
blPix.y += this.gridSize;
|
|
779
|
+
// Extend the bounds to contain the new bounds.
|
|
780
|
+
bounds.extend(
|
|
781
|
+
// Convert the pixel points back to LatLng nw
|
|
782
|
+
projection.fromDivPixelToLatLng(trPix));
|
|
783
|
+
bounds.extend(
|
|
784
|
+
// Convert the pixel points back to LatLng sw
|
|
785
|
+
projection.fromDivPixelToLatLng(blPix));
|
|
786
|
+
return bounds;
|
|
787
|
+
};
|
|
788
|
+
Clusterer.prototype.redraw = function () {
|
|
789
|
+
// Redraws all the clusters.
|
|
790
|
+
this.createClusters(0);
|
|
791
|
+
};
|
|
792
|
+
Clusterer.prototype.resetViewport = function (optHide) {
|
|
793
|
+
// Remove all the clusters
|
|
794
|
+
for (var i = 0; i < this.clusters.length; i++) {
|
|
795
|
+
this.clusters[i].remove();
|
|
796
|
+
}
|
|
797
|
+
this.clusters = [];
|
|
798
|
+
// Reset the markers to not be added and to be removed from the map.
|
|
799
|
+
for (var i = 0; i < this.markers.length; i++) {
|
|
800
|
+
var marker = this.markers[i];
|
|
801
|
+
marker.isAdded = false;
|
|
802
|
+
if (optHide) {
|
|
803
|
+
marker.setMap(null);
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
};
|
|
807
|
+
Clusterer.prototype.distanceBetweenPoints = function (p1, p2) {
|
|
808
|
+
var R = 6371; // Radius of the Earth in km
|
|
809
|
+
var dLat = ((p2.lat() - p1.lat()) * Math.PI) / 180;
|
|
810
|
+
var dLon = ((p2.lng() - p1.lng()) * Math.PI) / 180;
|
|
811
|
+
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
|
|
812
|
+
Math.cos((p1.lat() * Math.PI) / 180) *
|
|
813
|
+
Math.cos((p2.lat() * Math.PI) / 180) *
|
|
814
|
+
Math.sin(dLon / 2) *
|
|
815
|
+
Math.sin(dLon / 2);
|
|
816
|
+
return R * (2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)));
|
|
817
|
+
};
|
|
818
|
+
Clusterer.prototype.isMarkerInBounds = function (marker, bounds) {
|
|
819
|
+
var position = marker.getPosition();
|
|
820
|
+
if (position) {
|
|
821
|
+
return bounds.contains(position);
|
|
822
|
+
}
|
|
823
|
+
return false;
|
|
824
|
+
};
|
|
825
|
+
Clusterer.prototype.addToClosestCluster = function (marker) {
|
|
826
|
+
var cluster;
|
|
827
|
+
var distance = 40000; // Some large number
|
|
828
|
+
var clusterToAddTo = null;
|
|
829
|
+
for (var i = 0; i < this.clusters.length; i++) {
|
|
830
|
+
cluster = this.clusters[i];
|
|
831
|
+
var center = cluster.getCenter();
|
|
832
|
+
var position = marker.getPosition();
|
|
833
|
+
if (center && position) {
|
|
834
|
+
var d = this.distanceBetweenPoints(center, position);
|
|
835
|
+
if (d < distance) {
|
|
836
|
+
distance = d;
|
|
837
|
+
clusterToAddTo = cluster;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
if (clusterToAddTo && clusterToAddTo.isMarkerInClusterBounds(marker)) {
|
|
842
|
+
clusterToAddTo.addMarker(marker);
|
|
843
|
+
}
|
|
844
|
+
else {
|
|
845
|
+
cluster = new Cluster(this);
|
|
846
|
+
cluster.addMarker(marker);
|
|
847
|
+
this.clusters.push(cluster);
|
|
848
|
+
}
|
|
849
|
+
};
|
|
850
|
+
Clusterer.prototype.createClusters = function (iFirst) {
|
|
851
|
+
var _this = this;
|
|
852
|
+
if (!this.ready) {
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
855
|
+
// Cancel previous batch processing if we're working on the first batch:
|
|
856
|
+
if (iFirst === 0) {
|
|
857
|
+
/**
|
|
858
|
+
* This event is fired when the <code>Clusterer</code> begins
|
|
859
|
+
* clustering markers.
|
|
860
|
+
* @name Clusterer#clusteringbegin
|
|
861
|
+
* @param {Clusterer} mc The Clusterer whose markers are being clustered.
|
|
862
|
+
* @event
|
|
863
|
+
*/
|
|
864
|
+
google.maps.event.trigger(this, 'clusteringbegin', this);
|
|
865
|
+
if (this.timerRefStatic !== null) {
|
|
866
|
+
window.clearTimeout(this.timerRefStatic);
|
|
867
|
+
// @ts-ignore
|
|
868
|
+
delete this.timerRefStatic;
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
// Get our current map view bounds.
|
|
872
|
+
// Create a new bounds object so we don't affect the map.
|
|
873
|
+
//
|
|
874
|
+
// See Comments 9 & 11 on Issue 3651 relating to this workaround for a Google Maps bug:
|
|
875
|
+
var mapBounds =
|
|
876
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
877
|
+
// @ts-ignore
|
|
878
|
+
this.getMap().getZoom() > 3
|
|
879
|
+
? new google.maps.LatLngBounds(
|
|
880
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
881
|
+
// @ts-ignore
|
|
882
|
+
this.getMap()
|
|
883
|
+
.getBounds()
|
|
884
|
+
.getSouthWest(),
|
|
885
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
886
|
+
// @ts-ignore
|
|
887
|
+
this.getMap()
|
|
888
|
+
.getBounds()
|
|
889
|
+
.getNorthEast())
|
|
890
|
+
: new google.maps.LatLngBounds(new google.maps.LatLng(85.02070771743472, -178.48388434375), new google.maps.LatLng(-85.08136444384544, 178.00048865625));
|
|
891
|
+
var bounds = this.getExtendedBounds(mapBounds);
|
|
892
|
+
var iLast = Math.min(iFirst + this.batchSize, this.markers.length);
|
|
893
|
+
for (var i = iFirst; i < iLast; i++) {
|
|
894
|
+
var marker = this.markers[i];
|
|
895
|
+
if (!marker.isAdded && this.isMarkerInBounds(marker, bounds)) {
|
|
896
|
+
if (!this.ignoreHidden || (this.ignoreHidden && marker.getVisible())) {
|
|
897
|
+
this.addToClosestCluster(marker);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
if (iLast < this.markers.length) {
|
|
902
|
+
this.timerRefStatic = window.setTimeout(
|
|
903
|
+
// eslint-disable-next-line @getify/proper-arrows/this, @getify/proper-arrows/name
|
|
904
|
+
function () {
|
|
905
|
+
_this.createClusters(iLast);
|
|
906
|
+
}, 0);
|
|
907
|
+
}
|
|
908
|
+
else {
|
|
909
|
+
this.timerRefStatic = null;
|
|
910
|
+
/**
|
|
911
|
+
* This event is fired when the <code>Clusterer</code> stops
|
|
912
|
+
* clustering markers.
|
|
913
|
+
* @name Clusterer#clusteringend
|
|
914
|
+
* @param {Clusterer} mc The Clusterer whose markers are being clustered.
|
|
915
|
+
* @event
|
|
916
|
+
*/
|
|
917
|
+
google.maps.event.trigger(this, 'clusteringend', this);
|
|
918
|
+
for (var i = 0; i < this.clusters.length; i++) {
|
|
919
|
+
this.clusters[i].updateIcon();
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
};
|
|
923
|
+
Clusterer.prototype.extend = function (obj1, obj2) {
|
|
924
|
+
return function applyExtend(object) {
|
|
925
|
+
// eslint-disable-next-line guard-for-in
|
|
926
|
+
for (var property in object.prototype) {
|
|
927
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
928
|
+
// @ts-ignore
|
|
929
|
+
this.prototype[property] = object.prototype[property];
|
|
930
|
+
}
|
|
931
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
|
|
932
|
+
// @ts-ignore
|
|
933
|
+
return this;
|
|
934
|
+
}.apply(obj1, [obj2]);
|
|
935
|
+
};
|
|
936
|
+
return Clusterer;
|
|
937
|
+
}());
|
|
938
|
+
|
|
939
|
+
exports.Cluster = Cluster;
|
|
940
|
+
exports.ClusterIcon = ClusterIcon;
|
|
941
|
+
exports.Clusterer = Clusterer;
|
|
942
|
+
//# sourceMappingURL=cjs.js.map
|