Overlap marker Spiderfier marker icon when there are several markers in one place

Google Maps doesn’t provide the ability to split multiple markers located in the same place. This can happen to people or businesses in several places of residence, for example, in a residential building or professional services building. Depending on the zoom level, it can also occur in shopping centers, etc.

How to do this, "spiderfy" them: when you click on the first one, it breaks them with a line into the location. This is done on Google Earth, and George McCarron wrote a package for Google Maps. ( https://github.com/jawj/OverlappingMarkerSpiderfier )

It can be integrated with markerclusterer, although it does not support the creation of clustered marker markers.

My problem is that the application I'm working on wants to have specific icons for different activities. Spiderfier places one of the markers on top. The person looking at the map does not know that there can be 10 or more other markers under the top marker.

Ideally, there would be a way to place the top marker, which is displayed when there are several markers similar to another icon in the markercluster. This is not 1-to-1 direct, since spiderfier also works when they are close, but not exactly in the same place (20 pixels by default), and markercluster does not provide access to multiple markers in the same place.

The ideal behavior would be to have a special icon for spiders, which during the click attacked individual icons. Like markerclusterer, but without zooming in and handling the same location. A special icon would ideally indicate how many other markers are in place, again like a markerclusterer. A special icon can be hidden or become part of a spiderfied group.

Without any placement, users might not know that several actions are in this place. They may even suggest that the desired activity is not in this place because another activity marker is shown.

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

Thank you for your help,

David

+6
source share
3 answers

This is how I earned it. Where map is an instance of Gmap and oms is an instance of Overlapping Marker Spiderfier. We also use 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. }); 
+3
source

Some methods seem interesting, for example markersNearAnyOtherMarker , but I cannot get it to work. An interesting way would be to use the spiderfy and unspiderfy events and change the marker when it starts

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

Unfortunately, the unspiderfy event unspiderfy not unspiderfy until we open it and then close the overlap marker. If I find a conclusion for this solution, I will update this post.

0
source

I was able to match the following versions:

  • MarkerClusterer 2.0.13
  • OverlappingMarkerSpiderfier 3.27

Each time I create a new marker, I save initialIconUrl in the Marker object

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

When declaring OverlappingMarkerSpiderfier, set 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 for the Event event to format the markers manually. I need this because my SPIDERFIABLE Marker will not display correctly in the first step when moving from a cluster token to individual tokens.

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

Listen to the oms 'Event' format and set theURUR icon for markers that are SPIDERFIABLE. If the token is not password protected, 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.

0
source

Source: https://habr.com/ru/post/977942/


All Articles