@react-google-maps/marker-clusterer 2.10.0 → 2.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs.js +262 -223
- package/dist/cjs.js.map +1 -1
- package/dist/cjs.min.js +1 -1
- package/dist/cjs.min.js.map +1 -1
- package/dist/esm.js +262 -223
- package/dist/esm.js.map +1 -1
- package/dist/esm.min.js +1 -1
- package/dist/esm.min.js.map +1 -1
- package/dist/index.d.ts +16 -6
- package/dist/umd.js +262 -223
- package/dist/umd.js.map +1 -1
- package/dist/umd.min.js +1 -1
- package/dist/umd.min.js.map +1 -1
- package/package.json +7 -7
- package/src/Cluster.tsx +4 -8
- package/src/ClusterIcon.tsx +183 -114
- package/src/Clusterer.tsx +92 -82
package/src/Clusterer.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* global google */
|
|
2
2
|
/* eslint-disable filenames/match-regex */
|
|
3
3
|
import { Cluster } from './Cluster'
|
|
4
|
+
import { ClusterIcon } from './ClusterIcon'
|
|
4
5
|
|
|
5
6
|
import {
|
|
6
7
|
MarkerExtended,
|
|
@@ -44,7 +45,7 @@ const IMAGE_SIZES = [53, 56, 66, 78, 90]
|
|
|
44
45
|
|
|
45
46
|
const CLUSTERER_CLASS = 'cluster'
|
|
46
47
|
|
|
47
|
-
export class Clusterer {
|
|
48
|
+
export class Clusterer extends google.maps.OverlayView {
|
|
48
49
|
markers: MarkerExtended[]
|
|
49
50
|
clusters: Cluster[]
|
|
50
51
|
listeners: google.maps.MapsEventListener[]
|
|
@@ -73,6 +74,8 @@ export class Clusterer {
|
|
|
73
74
|
optMarkers: MarkerExtended[] = [],
|
|
74
75
|
optOptions: ClustererOptions = {}
|
|
75
76
|
) {
|
|
77
|
+
super()
|
|
78
|
+
|
|
76
79
|
this.extend(Clusterer, google.maps.OverlayView)
|
|
77
80
|
|
|
78
81
|
this.markers = []
|
|
@@ -134,56 +137,55 @@ export class Clusterer {
|
|
|
134
137
|
this.setupStyles()
|
|
135
138
|
|
|
136
139
|
this.addMarkers(optMarkers, true)
|
|
137
|
-
|
|
138
|
-
// @ts-ignore
|
|
140
|
+
|
|
139
141
|
this.setMap(map) // Note: this causes onAdd to be called
|
|
140
142
|
}
|
|
141
143
|
|
|
144
|
+
onZoomChanged() {
|
|
145
|
+
this.resetViewport(false)
|
|
146
|
+
|
|
147
|
+
// Workaround for this Google bug: when map is at level 0 and "-" of
|
|
148
|
+
// zoom slider is clicked, a "zoom_changed" event is fired even though
|
|
149
|
+
// the map doesn't zoom out any further. In this situation, no "idle"
|
|
150
|
+
// event is triggered so the cluster markers that have been removed
|
|
151
|
+
// do not get redrawn. Same goes for a zoom in at maxZoom.
|
|
152
|
+
if (
|
|
153
|
+
this.getMap()?.getZoom() === (this.get('minZoom') || 0) ||
|
|
154
|
+
|
|
155
|
+
this.getMap()?.getZoom() === this.get('maxZoom')
|
|
156
|
+
) {
|
|
157
|
+
google.maps.event.trigger(this, 'idle')
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
onIdle() {
|
|
162
|
+
this.redraw()
|
|
163
|
+
}
|
|
164
|
+
|
|
142
165
|
onAdd() {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
this.activeMap =
|
|
166
|
+
const map = this.getMap()
|
|
167
|
+
|
|
168
|
+
this.activeMap = map
|
|
146
169
|
|
|
147
170
|
this.ready = true
|
|
148
171
|
|
|
149
172
|
this.repaint()
|
|
150
173
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
167
|
-
// @ts-ignore
|
|
168
|
-
this.getMap().getZoom() === (this.get('minZoom') || 0) ||
|
|
169
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
170
|
-
// @ts-ignore
|
|
171
|
-
this.getMap().getZoom() === this.get('maxZoom')
|
|
172
|
-
) {
|
|
173
|
-
google.maps.event.trigger(this, 'idle')
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
),
|
|
177
|
-
google.maps.event.addListener(
|
|
178
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
179
|
-
// @ts-ignore
|
|
180
|
-
this.getMap(),
|
|
181
|
-
'idle',
|
|
182
|
-
() => {
|
|
183
|
-
this.redraw()
|
|
184
|
-
}
|
|
185
|
-
),
|
|
186
|
-
]
|
|
174
|
+
if (map !== null) {
|
|
175
|
+
// Add the map event listeners
|
|
176
|
+
this.listeners = [
|
|
177
|
+
google.maps.event.addListener(
|
|
178
|
+
map,
|
|
179
|
+
'zoom_changed',
|
|
180
|
+
this.onZoomChanged
|
|
181
|
+
),
|
|
182
|
+
google.maps.event.addListener(
|
|
183
|
+
map,
|
|
184
|
+
'idle',
|
|
185
|
+
this.onIdle
|
|
186
|
+
),
|
|
187
|
+
]
|
|
188
|
+
}
|
|
187
189
|
}
|
|
188
190
|
|
|
189
191
|
onRemove() {
|
|
@@ -237,14 +239,18 @@ export class Clusterer {
|
|
|
237
239
|
|
|
238
240
|
for (let i = 0; i < markers.length; i++) {
|
|
239
241
|
const position = markers[i].getPosition()
|
|
242
|
+
|
|
240
243
|
if (position) {
|
|
241
244
|
bounds.extend(position)
|
|
242
245
|
}
|
|
243
246
|
}
|
|
244
247
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
+
const map = this.getMap()
|
|
249
|
+
|
|
250
|
+
if (map !== null && 'fitBounds' in map) {
|
|
251
|
+
map.fitBounds(bounds)
|
|
252
|
+
}
|
|
253
|
+
|
|
248
254
|
}
|
|
249
255
|
|
|
250
256
|
getGridSize(): number {
|
|
@@ -496,36 +502,51 @@ export class Clusterer {
|
|
|
496
502
|
}
|
|
497
503
|
|
|
498
504
|
getExtendedBounds(bounds: google.maps.LatLngBounds): google.maps.LatLngBounds {
|
|
499
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
500
|
-
// @ts-ignore
|
|
501
505
|
const projection = this.getProjection()
|
|
506
|
+
|
|
502
507
|
// Convert the points to pixels and the extend out by the grid size.
|
|
503
508
|
const trPix = projection.fromLatLngToDivPixel(
|
|
504
509
|
// Turn the bounds into latlng.
|
|
505
510
|
new google.maps.LatLng(bounds.getNorthEast().lat(), bounds.getNorthEast().lng())
|
|
506
511
|
)
|
|
507
512
|
|
|
508
|
-
trPix
|
|
509
|
-
|
|
513
|
+
if (trPix !== null) {
|
|
514
|
+
trPix.x += this.gridSize
|
|
515
|
+
trPix.y -= this.gridSize
|
|
516
|
+
}
|
|
510
517
|
|
|
511
518
|
const blPix = projection.fromLatLngToDivPixel(
|
|
512
519
|
// Turn the bounds into latlng.
|
|
513
520
|
new google.maps.LatLng(bounds.getSouthWest().lat(), bounds.getSouthWest().lng())
|
|
514
521
|
)
|
|
515
522
|
|
|
516
|
-
blPix
|
|
517
|
-
|
|
523
|
+
if (blPix !== null) {
|
|
524
|
+
blPix.x -= this.gridSize
|
|
525
|
+
blPix.y += this.gridSize
|
|
526
|
+
}
|
|
527
|
+
|
|
518
528
|
|
|
519
529
|
// Extend the bounds to contain the new bounds.
|
|
520
|
-
|
|
530
|
+
if (trPix !== null) {
|
|
521
531
|
// Convert the pixel points back to LatLng nw
|
|
522
|
-
projection.fromDivPixelToLatLng(trPix)
|
|
523
|
-
|
|
532
|
+
const point1 = projection.fromDivPixelToLatLng(trPix)
|
|
533
|
+
|
|
534
|
+
if (point1 !== null) {
|
|
535
|
+
bounds.extend(point1)
|
|
536
|
+
}
|
|
537
|
+
}
|
|
524
538
|
|
|
525
|
-
|
|
539
|
+
if (blPix !== null) {
|
|
526
540
|
// Convert the pixel points back to LatLng sw
|
|
527
|
-
projection.fromDivPixelToLatLng(blPix)
|
|
528
|
-
|
|
541
|
+
const point2 = projection.fromDivPixelToLatLng(blPix)
|
|
542
|
+
|
|
543
|
+
if (point2 !== null) {
|
|
544
|
+
bounds.extend(
|
|
545
|
+
point2
|
|
546
|
+
)
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
529
550
|
|
|
530
551
|
return bounds
|
|
531
552
|
}
|
|
@@ -642,39 +663,33 @@ export class Clusterer {
|
|
|
642
663
|
}
|
|
643
664
|
}
|
|
644
665
|
|
|
666
|
+
const map = this.getMap()
|
|
667
|
+
|
|
668
|
+
const bounds = map !== null && 'getBounds' in map ? map.getBounds() : null
|
|
669
|
+
|
|
670
|
+
const zoom = map?.getZoom() || 0
|
|
645
671
|
// Get our current map view bounds.
|
|
646
672
|
// Create a new bounds object so we don't affect the map.
|
|
647
673
|
//
|
|
648
674
|
// See Comments 9 & 11 on Issue 3651 relating to this workaround for a Google Maps bug:
|
|
649
|
-
const mapBounds =
|
|
650
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
651
|
-
// @ts-ignore
|
|
652
|
-
this.getMap().getZoom() > 3
|
|
675
|
+
const mapBounds = zoom > 3
|
|
653
676
|
? new google.maps.LatLngBounds(
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
this.getMap()
|
|
657
|
-
.getBounds()
|
|
658
|
-
.getSouthWest(),
|
|
659
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
660
|
-
// @ts-ignore
|
|
661
|
-
this.getMap()
|
|
662
|
-
.getBounds()
|
|
663
|
-
.getNorthEast()
|
|
677
|
+
bounds?.getSouthWest(),
|
|
678
|
+
bounds?.getNorthEast()
|
|
664
679
|
)
|
|
665
680
|
: new google.maps.LatLngBounds(
|
|
666
681
|
new google.maps.LatLng(85.02070771743472, -178.48388434375),
|
|
667
682
|
new google.maps.LatLng(-85.08136444384544, 178.00048865625)
|
|
668
683
|
)
|
|
669
684
|
|
|
670
|
-
const
|
|
685
|
+
const extendedMapBounds = this.getExtendedBounds(mapBounds)
|
|
671
686
|
|
|
672
687
|
const iLast = Math.min(iFirst + this.batchSize, this.markers.length)
|
|
673
688
|
|
|
674
689
|
for (let i = iFirst; i < iLast; i++) {
|
|
675
690
|
const marker = this.markers[i]
|
|
676
691
|
|
|
677
|
-
if (!marker.isAdded && this.isMarkerInBounds(marker,
|
|
692
|
+
if (!marker.isAdded && this.isMarkerInBounds(marker, extendedMapBounds) && (!this.ignoreHidden || (this.ignoreHidden && marker.getVisible()))) {
|
|
678
693
|
this.addToClosestCluster(marker)
|
|
679
694
|
}
|
|
680
695
|
}
|
|
@@ -704,18 +719,13 @@ export class Clusterer {
|
|
|
704
719
|
}
|
|
705
720
|
}
|
|
706
721
|
|
|
707
|
-
extend(obj1:
|
|
708
|
-
return function applyExtend(object:
|
|
709
|
-
// eslint-disable-next-line guard-for-in
|
|
722
|
+
extend<A extends typeof ClusterIcon | typeof Clusterer>(obj1: A, obj2: typeof google.maps.OverlayView) {
|
|
723
|
+
return function applyExtend(this: A, object: typeof google.maps.OverlayView) {
|
|
710
724
|
for (const property in object.prototype) {
|
|
711
|
-
|
|
712
|
-
// @ts-ignore
|
|
713
|
-
this.prototype[property] = object.prototype[property]
|
|
725
|
+
this.prototype.set(property, object.prototype.get(property))
|
|
714
726
|
}
|
|
715
727
|
|
|
716
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
717
|
-
// @ts-ignore
|
|
718
728
|
return this
|
|
719
|
-
}.apply(obj1, [obj2])
|
|
729
|
+
}.apply<A, [typeof google.maps.OverlayView], any>(obj1, [obj2])
|
|
720
730
|
}
|
|
721
731
|
}
|