问题
I've put together a map with clusters. The idea was that cluster's color should depend on the color of markers inside: if there is a red marker, cluster is red; no red, but there is a yellow marker, cluster is yellow; no red and yellow markers, cluster is blue.
This only works as expected at specific zoom levels. Fully zoomed out it shows blue cluster, however there are red markers in there, so I expect a red cluster. When I start to zoom in and the map shows multiple clusters, most look right, but in some instances this offending behavior repeats, it will group red/yellow/blue markers into blue cluster, I expect red. Same with Yellow + Blue markers should form a yellow cluster, not blue.
According to this setCalculator function runs for each cluster individually, therefore I was expecting consistent behavior, but instead we have mixed results.
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(51, 4),
zoom:6,
mapTypeControlOptions:"roadmap"
});
var markers = [];
// make random red, yellow, blue markers
for (var i = 0; i < 20; i++) {
var latLng = new google.maps.LatLng(51.11 - Math.random(), 4.11 - Math.random());
var marker = new google.maps.Marker({
position: latLng,
icon: 'http://maps.google.com/mapfiles/ms/micons/green.png',
label: i,
map: map
});
markers.push(marker);
}
for (var i = 0; i < 20; i++) {
var latLng = new google.maps.LatLng(51.11 - Math.random(),4.11 - Math.random());
var marker = new google.maps.Marker({
position: latLng,
icon: 'http://maps.google.com/mapfiles/ms/micons/yellow.png',
label: i,
map: map
});
markers.push(marker);
}
for (var i = 0; i < 20; i++) {
var latLng = new google.maps.LatLng(51.11 - Math.random(),4.11 - Math.random());
var marker = new google.maps.Marker({
position: latLng,
icon: 'http://maps.google.com/mapfiles/ms/micons/red.png',
label: i,
map: map
});
markers.push(marker);
}
// match cluster icon to markers
var calc = function(markers, numStyles) {
for (var i = 0; i < markers.length; i++) {
if (markers[i].getIcon().indexOf("red.png") > -1) {
return {text: markers.length, index: 3}; // index of red
}else if (markers[i].getIcon().indexOf("yellow.png") > -1) {
return {text: markers.length, index: 2}; // index of yellow
}else if (markers[i].getIcon().indexOf("green.png") > -1) {
return {text: markers.length, index: 1};// index of blue
}
}
}
// define cluster icons
var mcOptions = {gridSize: 50, maxZoom: 15, styles: [{
height: 50,
url: "https://raw.githubusercontent.com/googlearchive/js-marker-clusterer/gh-pages/images/m1.png",
width: 50
},
{
height: 50,
url: "https://raw.githubusercontent.com/googlearchive/js-marker-clusterer/gh-pages/images/m2.png",
width: 50
},
{
height: 50,
url: "https://raw.githubusercontent.com/googlearchive/js-marker-clusterer/gh-pages/images/m3.png",
width: 50
}]
};
var markerCluster = new MarkerClusterer(map, markers, mcOptions);
markerCluster.setCalculator(calc);
}
#map {
height: 80%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
<script defer src="https://maps.googleapis.com/maps/api/js?v=3.42&key=AIzaSyA4PP1O36qWCzer8K3VFyjf0uxRs4WVNFo&callback=initMap"></script>
<script src="https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/markerclusterer.js"></script>
<div id="map"></div>
UPDATE: changed marker icons to be more distinguishable from cluster icons.
回答1:
One of your issues is your calculator function. You want it to return "red" if there are any red markers in the cluster, yellow if there are any yellow markers but no red ones, and blue otherwise. Write the code to do that:
// match cluster icon to markers
var calc = function(markers, numStyles) {
// default to blue
var highestPriorityColor = 1;
for (var i = 0; i < markers.length; i++) {
if (markers[i].getIcon().indexOf("red.png") > -1) {
// if any markers are red, will be red, can return result
return {text: markers.length, index: 3}; // index of red
} else if (markers[i].getIcon().indexOf("yellow.png") > -1) {
// if any markers are yellow, update it to yellow if it is blue
if (highestPriorityColor < 2)
highestPriorityColor = 2; // index of yellow
} /* else if (markers[i].getIcon().indexOf("green.png") > -1) {
// ignore green markers (leave it whatever color it is, defaults to blue)
} */
}
// return result once complete processing all the markers
return {text: markers.length, index: highestPriorityColor}; // index of chosen cluster
}
zoomed out
zoom in
zoom in on red "17" cluster
code snippet:
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(51, 4),
zoom: 6,
mapTypeControlOptions: "roadmap"
});
var markers = [];
// make random red, yellow, blue markers
for (var i = 0; i < 50; i++) {
var latLng = new google.maps.LatLng(51.11 - Math.random(), 4.11 - Math.random());
var marker = new google.maps.Marker({
position: latLng,
icon: 'http://maps.google.com/mapfiles/ms/micons/green.png',
label: "" + i,
map: map
});
markers.push(marker);
}
for (var i = 0; i < 20; i++) {
var latLng = new google.maps.LatLng(51.11 - Math.random(), 4.11 - Math.random());
var marker = new google.maps.Marker({
position: latLng,
icon: 'http://maps.google.com/mapfiles/ms/micons/yellow.png',
label: "" + i,
map: map
});
markers.push(marker);
}
for (var i = 0; i < 5; i++) {
var latLng = new google.maps.LatLng(51.11 - Math.random(), 4.11 - Math.random());
var marker = new google.maps.Marker({
position: latLng,
icon: 'http://maps.google.com/mapfiles/ms/micons/red.png',
label: "" + i,
map: map
});
markers.push(marker);
}
// match cluster icon to markers
var calc = function(markers, numStyles) {
// default to blue
var highestPriorityColor = 1;
for (var i = 0; i < markers.length; i++) {
if (markers[i].getIcon().indexOf("red.png") > -1) {
// if any markers are red, will be red, can return result
return {
text: markers.length,
index: 3
}; // index of red
} else if (markers[i].getIcon().indexOf("yellow.png") > -1) {
// if any markers are yellow, update it to yellow if it is blue
if (highestPriorityColor < 2)
highestPriorityColor = 2; // index of yellow
}
/* else if (markers[i].getIcon().indexOf("green.png") > -1) {
// ignore green markers (leave it whatever color it is, defaults to blue)
} */
}
// return result once complete processing all the markers
return {
text: markers.length,
index: highestPriorityColor
}; // index of chosen cluster
}
// define cluster icons
var mcOptions = {
gridSize: 50,
maxZoom: 15,
styles: [{
height: 50,
url: "https://raw.githubusercontent.com/googlearchive/js-marker-clusterer/gh-pages/images/m1.png",
width: 50
},
{
height: 50,
url: "https://raw.githubusercontent.com/googlearchive/js-marker-clusterer/gh-pages/images/m2.png",
width: 50
},
{
height: 50,
url: "https://raw.githubusercontent.com/googlearchive/js-marker-clusterer/gh-pages/images/m3.png",
width: 50
}
]
};
var markerCluster = new MarkerClusterer(map, markers, mcOptions);
markerCluster.setCalculator(calc);
}
#map {
height: 80%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
<script defer src="https://maps.googleapis.com/maps/api/js?v=3.42&key=AIzaSyA4PP1O36qWCzer8K3VFyjf0uxRs4WVNFo&callback=initMap"></script>
<script src="https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/markerclusterer.js"></script>
<div id="map"></div>
来源:https://stackoverflow.com/questions/65116880/set-marker-cluster-icon-depending-on-markers-inside-it