set marker cluster icon depending on markers inside it

狂风中的少年 提交于 2020-12-15 04:56:33

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!