I am using markerclustererplus with Google Maps. I have multiple markers and I have set it so that only one InfoWindow displays at a time. If the user clicks on a marker, an InfoWindow appears. If the user zooms out and the marker is absorbed into a cluster, the InfoWindow is closed.
I use the 'map_changed' listener to the markers to check if the marker has been "absorbed" into a cluster. If so, the InfoWindow is closed and I want to call another function one time only. The problem is that in my current code, the function gets called for multiple markers.
How can I either add the 'map_changed' listener to the currently-selected marker only? If this is not possible, how can I prevent the function being called multiple times? Do I need to temporarily remove the 'map_changed' listener to non-selected markers?
The function I want to call is named "closeMarker()". Please see the JSfiddle.
JS:
var map;
function loadMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: -41.75,
lng: 172.75
},
zoom: 4
});
addMarkers();
}
var WeatherStations = [{
"stn": 719460,
"wban": 99999,
"StationName": "FORT SIMPSON",
"FIPS": "CA",
"Latitude": 61.759998322,
"Longitude": -121.2369995,
"Elevation_m": 169,
"NOAAReadings": 14952
}, {
"stn": 935970,
"wban": 99999,
"StationName": "CAPE CAMPBELL AWS",
"FIPS": "NZ",
"Latitude": -41.71699905,
"Longitude": 174.26699829,
"Elevation_m": 32,
"NOAAReadings": 12174
},
{
"stn": 934360,
"wban": 99999,
"StationName": "WELLINGTON INTL",
"FIPS": "NZ",
"Latitude": -41.32699966,
"Longitude": 174.80499268,
"Elevation_m": 12,
"NOAAReadings": 9914
}, {
"stn": 937090,
"wban": 99999,
"StationName": "HAAST AWS",
"FIPS": "NZ",
"Latitude": -43.86700058,
"Longitude": 169,
"Elevation_m": 5,
"NOAAReadings": 14371
},
{
"stn": 935270,
"wban": 99999,
"StationName": "FAREWELL SPIT AWS",
"FIPS": "NZ",
"Latitude": -40.54999924,
"Longitude": 173,
"Elevation_m": 3,
"NOAAReadings": 11575
}, {
"stn": 935460,
"wban": 99999,
"StationName": "NELSON AERODROME AWS",
"FIPS": "NZ",
"Latitude": -41.29999924,
"Longitude": 173.19999695,
"Elevation_m": 6,
"NOAAReadings": 10557
},
{
"stn": 937800,
"wban": 99999,
"StationName": "CHRISTCHURCH INTL",
"FIPS": "NZ",
"Latitude": -43.48899841,
"Longitude": 172.53199768,
"Elevation_m": 38,
"NOAAReadings": 14933
}, {
"stn": 938050,
"wban": 99999,
"StationName": "PUYSEGUR POINT AWS",
"FIPS": "NZ",
"Latitude": -46.15000153,
"Longitude": 166.6000061,
"Elevation_m": 44,
"NOAAReadings": 10493
},
{
"stn": 939940,
"wban": 99999,
"StationName": "RAOUL ISLAND AWS",
"FIPS": "NZ",
"Latitude": -29.25,
"Longitude": -177.9329987,
"Elevation_m": 50,
"NOAAReadings": 11001
}
];
var styles = [
[{
url: "https://i.imgur.com/4dzjY47.png",
height: 47,
width: 48,
anchorText: [14, 0],
textColor: '#fff',
textSize: 11
}, {
url: 'https://i.imgur.com/My5Cgpd.png',
height: 47,
width: 48,
anchorText: [14, 0],
textColor: '#fff',
textSize: 11
}, {
url: 'https://i.imgur.com/t7SvOax.png',
height: 47,
width: 48,
anchorText: [14, 0],
textColor: '#fff',
textSize: 11
}]
];
var prev_infowindow = false; // to close previously-opened infowindows
var dataSourceType = 0; // 0 = grid; 1 = weatherstation
var gStn;
var gWban;
var gMarkerLat;
var gMarkerLng;
var gMarkerName;
var iw;
var iwClosed = false;
var curMark;
var infowindow;
function addMarkers() {
infowindow = new google.maps.InfoWindow();
var markers = [];
for (var i = 0; i < WeatherStations.length; i++) {
var latLng = new google.maps.LatLng(WeatherStations[i].Latitude, WeatherStations[i].Longitude)
var marker = new google.maps.Marker({
position: latLng,
map: map,
visible: true,
zIndex: 10,
});
var content = "<div id='" + WeatherStations[i].stn + " '> <div class='scrollfix'><b>" + WeatherStations[i].StationName + "</b>";
google.maps.event.addListener(marker, 'click', (function(marker, content, infowindow) {
return function() {
curMark = this;
// Close already-opened InfoWindow
if (prev_infowindow) {
prev_infowindow.close();
}
prev_infowindow = infowindow;
infowindow.setContent(content);
infowindow.setOptions({
pixelOffset: new google.maps.Size(0, -42)
})
infowindow.setPosition(marker.getPosition())
infowindow.open(map, /* marker */ );
};
})(marker, content, infowindow));
google.maps.event.addListener(marker, 'map_changed', function() {
var clusters = markerClusterer.getClusters(); // use the get clusters method which returns an array of objects
for (let i = 0, l = clusters.length; i < l; i++) {
const markers = clusters[i].getMarkers();
for (const m of markers) {
if (m === curMark && markers.length > 1) {
try {
if (infowindow !== null) {
infowindow.close();
infowindow = null;
}
if (prev_infowindow) {
prev_infowindow.close();
}
closeMarker();
} catch (ee) {}
}
}
}
});
markers.push(marker);
}
var zoom = null;
var size = null;
var style = 0;
markerClusterer = new MarkerClusterer(map, markers, {
maxZoom: zoom,
gridSize: size,
styles: styles[style]
});
}
function clearClusters() {
markerClusterer.clearMarkers();
}
function closeMarker()
{
console.log('x');
}
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Google Maps Marker Example</title>
<script src="https://maps.googleapis.com/maps/api/js" async defer></script>
<script src="https://unpkg.com/@googlemaps/markerclustererplus/dist/index.min.js"></script>
<script type="text/javascript" src="mark.js"></script>
<script>
</script>
<style>
#map {
width: 500px;
height: 500px;
border: thin solid black;
}
</style>
</head>
<body onload="loadMap();">
<h1>Google Maps Marker Example</h1>
<div id="map"></div>
</body>
</html>
One option to address the issue would be to set the variable curMark
to null
when you close it's InfoWindow
and move the call to closeMark
to the code that closes the InfoWindow
and sets the curMark
variable to null
.
Also, not sure why you are setting infowindow
to null
there, but if you do that, it will only call closeMarker
one time.
Updated map_changed
listener:
google.maps.event.addListener(marker, 'map_changed', function() {
var clusters = markerClusterer.getClusters(); // use the get clusters method which returns an array of objects
for (let i = 0, l = clusters.length; i < l; i++) {
const markers = clusters[i].getMarkers();
for (const m of markers) {
if (m === curMark && markers.length > 1) {
try {
if (infowindow !== null) {
infowindow.close();
closeMarker();
curMark=null;
}
if (prev_infowindow) {
prev_infowindow.close();
}
} catch (ee) {}
}
}
}
});
code snippet:
var map;
function loadMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: -41.75,
lng: 172.75
},
zoom: 4
});
addMarkers();
}
var WeatherStations = [{
"stn": 719460,
"wban": 99999,
"StationName": "FORT SIMPSON",
"FIPS": "CA",
"Latitude": 61.759998322,
"Longitude": -121.2369995,
"Elevation_m": 169,
"NOAAReadings": 14952
}, {
"stn": 935970,
"wban": 99999,
"StationName": "CAPE CAMPBELL AWS",
"FIPS": "NZ",
"Latitude": -41.71699905,
"Longitude": 174.26699829,
"Elevation_m": 32,
"NOAAReadings": 12174
},
{
"stn": 934360,
"wban": 99999,
"StationName": "WELLINGTON INTL",
"FIPS": "NZ",
"Latitude": -41.32699966,
"Longitude": 174.80499268,
"Elevation_m": 12,
"NOAAReadings": 9914
}, {
"stn": 937090,
"wban": 99999,
"StationName": "HAAST AWS",
"FIPS": "NZ",
"Latitude": -43.86700058,
"Longitude": 169,
"Elevation_m": 5,
"NOAAReadings": 14371
},
{
"stn": 935270,
"wban": 99999,
"StationName": "FAREWELL SPIT AWS",
"FIPS": "NZ",
"Latitude": -40.54999924,
"Longitude": 173,
"Elevation_m": 3,
"NOAAReadings": 11575
}, {
"stn": 935460,
"wban": 99999,
"StationName": "NELSON AERODROME AWS",
"FIPS": "NZ",
"Latitude": -41.29999924,
"Longitude": 173.19999695,
"Elevation_m": 6,
"NOAAReadings": 10557
},
{
"stn": 937800,
"wban": 99999,
"StationName": "CHRISTCHURCH INTL",
"FIPS": "NZ",
"Latitude": -43.48899841,
"Longitude": 172.53199768,
"Elevation_m": 38,
"NOAAReadings": 14933
}, {
"stn": 938050,
"wban": 99999,
"StationName": "PUYSEGUR POINT AWS",
"FIPS": "NZ",
"Latitude": -46.15000153,
"Longitude": 166.6000061,
"Elevation_m": 44,
"NOAAReadings": 10493
},
{
"stn": 939940,
"wban": 99999,
"StationName": "RAOUL ISLAND AWS",
"FIPS": "NZ",
"Latitude": -29.25,
"Longitude": -177.9329987,
"Elevation_m": 50,
"NOAAReadings": 11001
}
];
var styles = [
[{
url: "https://i.imgur.com/4dzjY47.png",
height: 47,
width: 48,
anchorText: [14, 0],
textColor: '#fff',
textSize: 11
}, {
url: 'https://i.imgur.com/My5Cgpd.png',
height: 47,
width: 48,
anchorText: [14, 0],
textColor: '#fff',
textSize: 11
}, {
url: 'https://i.imgur.com/t7SvOax.png',
height: 47,
width: 48,
anchorText: [14, 0],
textColor: '#fff',
textSize: 11
}]
];
var prev_infowindow = false; // to close previously-opened infowindows
var dataSourceType = 0; // 0 = grid; 1 = weatherstation
var gStn;
var gWban;
var gMarkerLat;
var gMarkerLng;
var gMarkerName;
var iw;
var iwClosed = false;
var curMark;
var infowindow;
function addMarkers() {
infowindow = new google.maps.InfoWindow();
var markers = [];
for (var i = 0; i < WeatherStations.length; i++) {
var latLng = new google.maps.LatLng(WeatherStations[i].Latitude, WeatherStations[i].Longitude)
var marker = new google.maps.Marker({
position: latLng,
map: map,
visible: true,
zIndex: 10,
});
var content = "<div id='" + WeatherStations[i].stn + " '> <div class='scrollfix'><b>" + WeatherStations[i].StationName + "</b>";
google.maps.event.addListener(marker, 'click', (function(marker, content, infowindow) {
return function() {
curMark = this;
// Close already-opened InfoWindow
if (prev_infowindow) {
prev_infowindow.close();
}
prev_infowindow = infowindow;
infowindow.setContent(content);
infowindow.setOptions({
pixelOffset: new google.maps.Size(0, -42)
})
infowindow.setPosition(marker.getPosition())
infowindow.open(map);
};
})(marker, content, infowindow));
google.maps.event.addListener(marker, 'map_changed', function() {
var clusters = markerClusterer.getClusters(); // use the get clusters method which returns an array of objects
for (let i = 0, l = clusters.length; i < l; i++) {
const markers = clusters[i].getMarkers();
for (const m of markers) {
if (m === curMark && markers.length > 1) {
try {
if (infowindow !== null) {
infowindow.close();
closeMarker();
curMark=null;
}
if (prev_infowindow) {
prev_infowindow.close();
}
} catch (ee) {}
}
}
}
});
markers.push(marker);
}
var zoom = null;
var size = null;
var style = 0;
markerClusterer = new MarkerClusterer(map, markers, {
maxZoom: zoom,
gridSize: size,
styles: styles[style]
});
}
function clearClusters() {
markerClusterer.clearMarkers();
}
function closeMarker() {
console.log('x');
}
<!DOCTYPE html>
<html>
<head>
<title>Google Maps Marker Example</title>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk" async defer></script>
<script src="https://unpkg.com/@googlemaps/markerclustererplus/dist/index.min.js"></script>
<style>
#map {
width: 500px;
height: 500px;
border: thin solid black;
}
</style>
</head>
<body onload="loadMap();">
<h1>Google Maps Marker Example</h1>
<div id="map"></div>
</body>
</html>