Overlapping Marker Spiderfier Marker Icon When The

2020-06-03 06:57发布

Google Maps doesn't provide a way to break apart multiple markers that are at the same location. This can occur with a people or businesses at a multiple residency location such as an apartment building or professional services building. Depending at zoom level it can also occur at shopping malls, etc.

The way around that is to "spiderfy" them: when clicking on the first it breaks them out with a line to the location. This is done in Google Earth and George MacKerron wrote a package to do that for Google Maps. (https://github.com/jawj/OverlappingMarkerSpiderfier)

It can be integrated with markerclusterer, although it doesn't support marker clusterer's batch creation of markers.

My issue is that the application I'm working on wants to have specific icons for different types of activities. Spiderfier puts one of the markers on top. A person looking at the map has no way of knowing that there can be 10 or more other markers underneath the top marker.

Ideally, there would be a way to put a top marker that displays when there are multiple markers similar to the different icon in markercluster. It isn't a direct 1-to-1 since spiderfier also works when they are close but not exactly at the same location (default is 20 pixels) and markercluster has no provision for accessing multiple markers at the exact same location.

The ideal behavior would be have a special icon for spiders that broke into the spiderfied individual icons when clicked. Similar to markerclusterer, but without the zoom change and handling the same location. The special icon ideally would indicate how many other markers are at the spot, again like markerclusterer. The special icon could be hidden or become part of the spiderfied group.

Without some accommodation users would have no way of knowing multiple activities are at the location. They may even assume that the activity they want is not at that location because another activities marker is shown.

This is a plunker that has the problem: 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);

Thanks for your help,

David

3条回答
叛逆
2楼-- · 2020-06-03 07:09

I managed to match the following Versions:

  • MarkerClusterer 2.0.13
  • OverlappingMarkerSpiderfier 3.27

On every creation of a new Marker, i store the initialIconUrl in the Marker Object

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

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

When declaring the OverlappingMarkerSpiderfier, set the nearbyDistance to 0.001 (or some other very small value).

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
});

Then, we need a listener on the maps 'idle' Event, to format the Markers manually. I needed this because my SPIDERFIABLE Marker wouldn't show correctly on the first step, when transferring from the Clustered Marker to the seperate Markers.

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

Listen to the oms 'format' Event and set the iconURL for Markers that are SPIDERFIABLE. If the Marker is not spiderfiable, reset the Icon to the initial 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);
});

Hope this helps.

查看更多
太酷不给撩
3楼-- · 2020-06-03 07:32

Here's how I got it to work. Where map is a Gmap instance and oms is an Overlapping Marker Spiderfier instance. We're also using Marker Clusterer on the initial zoom which buys us a break.

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.

});
查看更多
姐就是有狂的资本
4楼-- · 2020-06-03 07:32

Some methods seems to be interesting like markersNearAnyOtherMarker but I cannot get it work. An interesting way could be to use spiderfy and unspiderfy events and change marker when it's fired

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);
    })
})

Unfortunatly, the unspiderfy event isn't fired until we open then close the overlap marker. If I find a conclusion to this solution I will update this post.

查看更多
登录 后发表回答