diff --git a/src/algorithms/grid.ts b/src/algorithms/grid.ts index ced5a5c4..ccddb8a5 100644 --- a/src/algorithms/grid.ts +++ b/src/algorithms/grid.ts @@ -120,6 +120,12 @@ export class GridAlgorithm extends AbstractViewportAlgorithm { ): void { let maxDistance = this.maxDistance; // Some large number let cluster: Cluster | null = null; + const position = MarkerUtils.getPosition(marker); + + if (position === null) { + // Marker has no position, which makes it invisible and not part of the cluster + return; + } for (let i = 0; i < this.clusters.length; i++) { const candidate = this.clusters[i]; @@ -128,7 +134,7 @@ export class GridAlgorithm extends AbstractViewportAlgorithm { const distance = distanceBetweenPoints( candidate.bounds.getCenter().toJSON(), - MarkerUtils.getPosition(marker).toJSON() + position.toJSON() ); if (distance < maxDistance) { @@ -145,7 +151,7 @@ export class GridAlgorithm extends AbstractViewportAlgorithm { cluster.bounds, projection, this.gridSize - ).contains(MarkerUtils.getPosition(marker)) + ).contains(position) ) { cluster.push(marker); } else { diff --git a/src/algorithms/supercluster.ts b/src/algorithms/supercluster.ts index fb59aa73..9a27818a 100644 --- a/src/algorithms/supercluster.ts +++ b/src/algorithms/supercluster.ts @@ -64,6 +64,10 @@ export class SuperClusterAlgorithm extends AbstractAlgorithm { const points = this.markers.map((marker) => { const position = MarkerUtils.getPosition(marker); + if (!position) { + return null; + } + const coordinates = [position.lng(), position.lat()]; return { type: "Feature" as const, @@ -74,7 +78,7 @@ export class SuperClusterAlgorithm extends AbstractAlgorithm { properties: { marker }, }; }); - this.superCluster.load(points); + this.superCluster.load(points.filter((p) => p != null)); } if (!changed) { diff --git a/src/algorithms/superviewport.ts b/src/algorithms/superviewport.ts index df4f92c6..1aeda64c 100644 --- a/src/algorithms/superviewport.ts +++ b/src/algorithms/superviewport.ts @@ -79,6 +79,10 @@ export class SuperClusterViewportAlgorithm extends AbstractViewportAlgorithm { const points = this.markers.map((marker) => { const position = MarkerUtils.getPosition(marker); + if (!position) { + return null; + } + const coordinates = [position.lng(), position.lat()]; return { type: "Feature" as const, @@ -89,7 +93,7 @@ export class SuperClusterViewportAlgorithm extends AbstractViewportAlgorithm { properties: { marker }, }; }); - this.superCluster.load(points); + this.superCluster.load(points.filter((p) => p != null)); } if (changed) { diff --git a/src/algorithms/utils.ts b/src/algorithms/utils.ts index 5d20274b..bce76cea 100644 --- a/src/algorithms/utils.ts +++ b/src/algorithms/utils.ts @@ -41,9 +41,10 @@ export const filterMarkersToPaddedViewport = ( viewportPaddingPixels ); - return markers.filter((marker) => - extendedMapBounds.contains(MarkerUtils.getPosition(marker)) - ); + return markers.filter((marker) => { + const position = MarkerUtils.getPosition(marker); + return position ? extendedMapBounds.contains(position) : false; + }); }; /** diff --git a/src/cluster.ts b/src/cluster.ts index d7d51e43..c6d868b8 100644 --- a/src/cluster.ts +++ b/src/cluster.ts @@ -44,7 +44,10 @@ export class Cluster { const bounds = new google.maps.LatLngBounds(this._position, this._position); for (const marker of this.markers) { - bounds.extend(MarkerUtils.getPosition(marker)); + const position = MarkerUtils.getPosition(marker); + if (position) { + bounds.extend(position); + } } return bounds; } diff --git a/src/marker-utils.ts b/src/marker-utils.ts index 1a622c39..743f630d 100644 --- a/src/marker-utils.ts +++ b/src/marker-utils.ts @@ -50,7 +50,7 @@ export class MarkerUtils { } } - public static getPosition(marker: Marker): google.maps.LatLng { + public static getPosition(marker: Marker): google.maps.LatLng | null { // SuperClusterAlgorithm.calculate expects a LatLng instance so we fake it for Adv Markers if (this.isAdvancedMarker(marker)) { if (marker.position) { @@ -69,8 +69,7 @@ export class MarkerUtils { } } - // @ts-ignore - return new google.maps.LatLng(null); + return null; } return marker.getPosition()!; @@ -79,13 +78,14 @@ export class MarkerUtils { public static getVisible(marker: Marker) { if (this.isAdvancedMarker(marker)) { /** - * Always return true for Advanced Markers because the clusterer - * uses getVisible as a way to count legacy markers not as an actual - * indicator of visibility for some reason. Even when markers are hidden - * Marker.getVisible returns `true` and this is used to set the marker count - * on the cluster. See the behavior of Cluster.count + * As per google.maps.marker.AdvancedMarkerElement documentation: + * An AdvancedMarkerElement may be constructed without a position, + * but will not be displayed until its position is provided. + * + * The same goes for the map property. But in case of clustering this + * is always set to null as we don't want to show the marker on the map. */ - return true; + return marker.position !== null; } return marker.getVisible(); }