In an angular app I’ve inherited there’s a map of vehicle positions. What I’m to do is group them and make it possible to click and show which vehicles is in that group. When a group is clicked I need to change that icon, and that’s what I can’t seem to do.
When the vehicles are loaded this function is called to draw the markers:
async addPoints(points: ILatLng[]) {
this.clearMarkers();
const { Marker, PinElement } = (await google.maps.importLibrary("marker") as google.maps.MarkerLibrary);
const markers = points.map(point => this.addImageMarker(point, Marker));
const onClusterClick = (
(event, cluster) => {
// And then what
event.stop();
}
) as onClusterClickHandler;
this.markerCluster = new MarkerClusterer({
map: this.currentMap,
markers,
renderer: await this.createRenderer(),
onClusterClick
}) as MarkerClustererWithPublicClusters;
if (this.autoCenter)
this.setCenter();
}
And the renderer looks like this:
async createRenderer() {
const { Marker, AdvancedMarkerElement, PinElement } = (await google.maps.importLibrary("marker") as google.maps.MarkerLibrary);
return {
render: (cluster, stats) => {
const marker = new Marker({
label: { text: `${cluster.count}`, color, fontWeight: "bold", "className": "group-marker"},
icon: {
url: ClusterMarker.Default
scaledSize: new google.maps.Size(28, 49, "px", "px"),
},
position: cluster.position,
zIndex: Number(google.maps.Marker.MAX_ZINDEX) + cluster.count,
});
return marker;
}
} as Renderer;
}
I’ve tried a lot of things too. I’ve tried storing the selected cluster both in window, and in the component itself. And using a isClusterSelected
function defined in createRendere like:
async createRenderer() {
const { Marker, AdvancedMarkerElement, PinElement } = (await google.maps.importLibrary("marker") as google.maps.MarkerLibrary);
const isClusterSelected = (cluster: Cluster) => {
if (!(window as any & {cluster: Cluster}).cluster)
return false;
const selectedMarker = (window as any & {cluster: Cluster}).cluster.marker as ExtendedMarker;
const currentMarker = cluster.marker as ExtendedMarker;
if (!cluster.marker)
return false;
return selectedMarker.anchorPoint.x === currentMarker.anchorPoint.x && selectedMarker.anchorPoint.y === currentMarker.anchorPoint.y
};
return {
render: (cluster, stats) => {
const color = isClusterSelected(cluster) ? "#ff00ff" : "black";
console.log("Rendering", color); // Always prints "Rendering black"
const marker = new Marker({
label: { text: `${cluster.count}`, color, fontWeight: "bold", "className": "group-marker"},
icon: {
url: isClusterSelected(cluster) ? ClusterMarker.Clicked : ClusterMarker.Default,
scaledSize: new google.maps.Size(28, 49, "px", "px"),
},
position: cluster.position,
zIndex: Number(google.maps.Marker.MAX_ZINDEX) + cluster.count,
});
return marker;
}
} as Renderer;
}
There I’ve tried comparing both the clusters coordinates, and with ===
which doesn’t change anything. I’m not even sure how I get it to rerender the points except zooming in and out a bit. If I in onClusterClick
loop through all clusters in this.markerCluster
and set their icon to default, and set the icon in the cluster in onClusterClick
to the other icon. The property seen in the picture below
it doesn’t change anything. I know I can call setIcon
on the clusters marker in the onClusterClick function like so:
const onClusterClick = (
(event, cluster) => {
for (const markerCluster of this.markerCluster.clusters.filter(m => m.count > 1))
(markerCluster.marker as google.maps.Marker).setIcon(ClusterMarker.Default);
(cluster.marker as google.maps.Marker).setIcon(ClusterMarker.Clicked);
event.stop();
}
) as onClusterClickHandler;
But the icon will reset as zoom as I zoom. So I don’t really know what to do here?