【问题标题】:set marker cluster icon depending on markers inside it根据其中的标记设置标记群集图标
【发布时间】:2021-03-14 22:21:36
【问题描述】:

我已经用集群整理了一张地图。 idea 是集群的颜色应该取决于内部标记的颜色:如果有红色标记,则集群是红色的;没有红色,但是有一个黄色标记,簇是黄色的;没有红色和黄色标记,簇是蓝色的。

这仅在特定缩放级别下按预期工作。完全缩小它显示蓝色集群,但是那里有红色标记,所以我期待一个红色集群。当我开始放大并且地图显示多个集群时,大多数看起来都正确,但在某些情况下,这种违规行为会重复,它会将红色/黄色/蓝色标记分组到蓝色集群中,我希望是红色的。与黄色 + 蓝色标记相同,应形成黄色簇,而不是蓝色。

根据this setCalculator 函数为每个集群单独运行,因此我期待一致的行为,但我们得到了不同的结果。

    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>

更新:更改了标记图标,使其与集群图标更容易区分。

【问题讨论】:

  • 请提供一个minimal reproducible example 来证明您的问题。看起来与集群相同的随机标记,很难重现和调试问题。证明问题的单个案例会更有帮助。
  • 运行sn-p,你会看到蓝色的簇。我希望看到红色集群。我认为该问题已重现。
  • 更改了随机标记的图标,使其看起来与集群不同,并根据要求减少了标记的总数以更具可读性。
  • 使调试更容易。随机性仍然使它每次都表现不同,但至少可以看到(或)问题。

标签: javascript google-maps google-maps-api-3


【解决方案1】:

您的问题之一是您的计算器功能。如果集群中有任何红色标记,您希望它返回“红色”,如果有任何黄色标记但没有红色标记,则返回黄色,否则返回蓝色。编写代码来做到这一点:

// 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
}

缩小

放大

放大红色“17”簇

代码 sn-p:

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: 60,
        url: "https://raw.githubusercontent.com/googlearchive/js-marker-clusterer/gh-pages/images/m2.png",
        width: 60
      },
      {
        height: 70,
        url: "https://raw.githubusercontent.com/googlearchive/js-marker-clusterer/gh-pages/images/m3.png",
        width: 70
      }
    ]
  };
  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://unpkg.com/@google/markerclustererplus@4.0.1/dist/markerclustererplus.min.js"></script>


<div id="map"></div>

【讨论】:

  • 感谢您的解决方案。我想了解为什么我的嵌套 IF 语句在内部有一个红色标记时返回一个蓝色簇,并且您的 highestPriorityColor 标志返回正确的颜色。我应该问另一个问题还是你可以在评论中说?
  • 您的代码根据第一个标记返回结果。总是(除非它是一种奇怪的颜色并且不符合if 条件之一)。
  • 我虽然在这两种情况下都使用 FOR 循环遍历集群中的所有标记。我将不得不研究循环。暂时没有意义。感谢您的帮助。
  • 每个if 语句都从函数中返回,因此如果其中任何一个返回true,它将在评估第一个标记后返回。
猜你喜欢
  • 1970-01-01
  • 2015-02-07
  • 2012-02-24
  • 2018-03-17
  • 1970-01-01
  • 2012-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多