谷歌地图API V3 - 多个标记在同一位置

有点卡在这个。我正在通过JSON检索地理坐标列表,并将它们弹出到谷歌地图上。一切正常,除了在完全相同的位置上有两个或多个标记的实例。API 仅显示 1 个标记 - 顶部标记。我想这很公平,但想找到一种方法来以某种方式显示它们。

我搜索了谷歌并找到了一些解决方案,但它们似乎大多是针对API的V2,或者只是不是那么好。理想情况下,我想要一个解决方案,您可以在其中单击某种组标记,然后显示聚集在它们所在的位置周围的标记。

有人遇到这个问题或类似问题,并愿意分享一个解决方案吗?


答案 1

看看 OverlappingMarkerSpiderfier
有一个演示页面,但它们不显示完全相同位置的标记,只有一些非常接近的标记。

但是,在 http://www.ejw.de/ejw-vor-ort/ 上可以看到一个真实生活中的例子,其中的标记位于完全相同的位置(向下滚动地图,然后单击几个标记以查看蜘蛛效应)。

这似乎是您问题的完美解决方案。


答案 2

如果标记位于同一建筑物中,则抵消标记不是真正的解决方案。您可能要做的是修改标记群集.js如下所示:

  1. 在 MarkerClusterer 类中添加一个原型单击方法,如下所示 - 我们稍后将在 map initialize() 函数中重写此方法:

    MarkerClusterer.prototype.onClick = function() { 
        return true; 
    };
    
  2. 在 ClusterIcon 类中,在 clusterclick 触发器之后添加以下代码:

    // Trigger the clusterclick event.
    google.maps.event.trigger(markerClusterer, 'clusterclick', this.cluster_);
    
    var zoom = this.map_.getZoom();
    var maxZoom = markerClusterer.getMaxZoom();
    // if we have reached the maxZoom and there is more than 1 marker in this cluster
    // use our onClick method to popup a list of options
    if (zoom >= maxZoom && this.cluster_.markers_.length > 1) {
       return markerClusterer.onClickZoom(this);
    }
    
  3. 然后,在 initialize() 函数中初始化映射并声明 MarkerClusterer 对象:

    markerCluster = new MarkerClusterer(map, markers);
    // onClickZoom OVERRIDE
    markerCluster.onClickZoom = function() { return multiChoice(markerCluster); }
    

    其中 multiChoice() 是 YOUR(尚未编写)函数,用于弹出一个信息窗口,其中包含可供选择的选项列表。请注意,markerClusterer 对象将传递给函数,因为您将需要它来确定该群集中有多少个标记。例如:

    function multiChoice(mc) {
         var cluster = mc.clusters_;
         // if more than 1 point shares the same lat/long
         // the size of the cluster array will be 1 AND
         // the number of markers in the cluster will be > 1
         // REMEMBER: maxZoom was already reached and we can't zoom in anymore
         if (cluster.length == 1 && cluster[0].markers_.length > 1)
         {
              var markers = cluster[0].markers_;
              for (var i=0; i < markers.length; i++)
              {
                  // you'll probably want to generate your list of options here...
              }
    
              return false;
         }
    
         return true;
    }