8

Google 地图不提供拆分位于同一位置的多个标记的方法。这可能发生在多个居住地点(例如公寓楼或专业服务大楼)的人员或企业中。根据缩放级别,它也可能发生在购物中心等。

解决方法是“蜘蛛化”它们:单击第一个时,它会用一条线将它们分开到该位置。这是在 Google Earth 中完成的,George MacKerron 为 Google Maps 编写了一个包。(https://github.com/jawj/OverlappingMarkerSpiderfier

它可以与markerclusterer集成,虽然它不支持marker clusterer的批量创建marker。

我的问题是我正在处理的应用程序想要为不同类型的活动提供特定的图标。Spiderfier 将其中一个标记放在顶部。查看地图的人无法知道顶部标记下方可能有 10 个或更多其他标记。

理想情况下,有一种方法可以放置一个顶部标记,当有多个标记类似于 markercluster 中的不同图标时显示。这不是直接的 1 对 1,因为 Spiderfier 也可以在它们靠近但不完全相同的位置(默认为 20 像素)时工作,并且 markercluster 没有提供在完全相同的位置访问多个标记的规定。

理想的行为是有一个特殊的蜘蛛图标,当点击时会闯入蜘蛛化的单个图标。类似于markerclusterer,但没有缩放变化和处理相同的位置。理想情况下,特殊图标将指示现场有多少其他标记,再次像markerclusterer。特殊图标可以隐藏或成为蜘蛛组的一部分。

如果没有一些住宿,用户将无法知道该地点有多项活动。他们甚至可能假设他们想要的活动不在那个位置,因为显示了另一个活动标记。

这是一个有问题的 plunker:http ://plnkr.co/edit/vimZNq?p=info

  var markers = [];
  var bounds = new google.maps.LatLngBounds();
  for (var i = 0; i < 100; ++i) {
    var latLng = new google.maps.LatLng(Math.floor(Math.random() * 10) / 10 + 39,
      Math.floor(Math.random() * 10) / 10 - 100);
    var marker = new google.maps.Marker({
      position: latLng,
      title: "marker " + i + " pos: " + latLng,
      maxZoom: 8,
      map: map

    });
    marker.desc = marker.getTitle();
    bounds.extend(latLng);
    markers.push(marker);
    oms.addMarker(marker);
  }

  map.fitBounds(bounds);

  var markerCluster = new MarkerClusterer(map, markers);

谢谢你的帮助,

大卫

4

3 回答 3

5

这是我如何让它工作的。Wheremap是 Gmap 实例,并且oms是 Overlapping Marker Spiderfier 实例。我们还在初始缩放中使用了 Marker Clusterer,这让我们可以休息一下。

map.addListener('zoom_changed', function() {        

    map.addListenerOnce('idle', function() {

        // change spiderable markers to plus sign markers
        // we are lucky here in that initial map is completely clustered
        // for there is no init listener in oms :(
        // so we swap on the first zoom/idle
        // and subsequently any other zoom/idle

        var spidered = oms.markersNearAnyOtherMarker();

        for (var i = 0; i < spidered.length; i ++) {

            // this was set when we created the markers
            url = spidered[i].icon.url;

            // code to manipulate your spidered icon url
        };

    });

});


oms.addListener('unspiderfy', function(markers) {

    var spidered = markers;

    for (var i = 0; i < spidered.length; i ++) {

        url = spidered[i].icon.url;

        // change it back
    };
});


oms.addListener('click', function(marker) {

  // put the clicked-on marker on top
  // when oms un-spiders

  marker.zIndex=999;

  // set infowindow, panning etc.

});
于 2015-12-24T15:58:51.387 回答
1

我设法匹配以下版本:

  • MarkerClusterer 2.0.13
  • OverlappingMarkerSpiderfier 3.27

在每次创建新标记时,我将其存储initialIconUrl在标记对象中

 var marker = new google.maps.Marker({
    position: //some position
});

marker.setIcon(iconUrl);
marker.initialIconUrl = iconUrl;

声明 OverlappingMarkerSpiderfier 时,将 设置nearbyDistance为 0.001(或其他一些非常小的值)。

this.oms = new OverlappingMarkerSpiderfier(this.map, {
    markersWontMove: true,
    markersWontHide: true,
    nearbyDistance: 0.001 //This will only spiderfy the Markers if they have the exact same position
});

然后,我们需要在地图“空闲”事件上设置一个监听器,以手动格式化标记。我需要这个,因为当从集群标记转移到单独的标记时,我的 SPIDERFIABLE 标记在第一步无法正确显示。

var me = this;
google.maps.event.addListener(this.map, 'idle', function () {
    me.oms.formatMarkers();
});

监听 oms 'format' 事件并为可 SPIDERFIABLE 的标记设置 iconURL。如果 Marker 不可抓取,请将 Icon 重置为初始 Url。

var spiderfiableIconUrl = //Whatever you need

this.oms.addListener('format', function (marker, status) {
    var iconURL = status == OverlappingMarkerSpiderfier.markerStatus.SPIDERFIABLE
        ? spiderfiableIconUrl :
        marker.initialIconUrl;

    marker.setIcon(iconURL);
});

希望这可以帮助。

于 2017-04-05T12:29:20.860 回答
0

有些方法似乎很有趣,markersNearAnyOtherMarker但我无法让它发挥作用。一种有趣的方法可能是使用 spiderfy 和 unspiderfy 事件并在触发时更改标记

overlappingMarkers = new OverlappingMarkerSpiderfier(map, overlapOptions);
overlappingMarkers.addListener('spiderfy', function (markers) {
    markers.forEach(function (marker) {
        marker.setLabel('*');
        marker.setIcon(myNormalIcon);
    })
})
overlappingMarkers.addListener('unspiderfy', function (markers) {
    markers.forEach(function (marker) {
        marker.setLabel(''+markers.length);
        marker.setIcon(myOverlapIcon);
    })
})

不幸的是,在unspiderfy我们打开然后关闭重叠标记之前,该事件不会被触发。如果我找到这个解决方案的结论,我会更新这篇文章。

于 2015-11-25T16:58:09.380 回答