How to hanlde OnClick of map markers when using OverlappingMarkerSpiderfier?

539 Views Asked by At

I just discovers OverlappingMarkerSpiderfier for Leaflet, and think it could be extremely useful (please note that the Leaflet version offers fewer options than the Google maps version, but I am restricted to Leaflet).

It was the work of only a few minutes to add it an existing project, but I have one tiny problem :-(

When I click any marker from these

enter image description here

I see the markers briefly expand (spiderify), but then the OnClick() of the marker fires (moving me to a new state, showing a new page, without the map).

I guess that I could alter my code to not add an OnClick() handler of the marker, until it expands, then add it, so that only clicking an expanded (spiderified) marker will take the action that is currently taken when clicking on a marker.

My question is whether this is the approach that is generally taken. How do you do it?

Here's my AngularJs code that adds a marker to the map, in case it helps.

    // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
    /** Given some data about a single conpany, add an appropriate marrker (and tooltip) to the map */
    Self.AddCompanyMarkerToMap = function (companyData) 
    {
        const companyName = companyData.company_name;
        const latitude    = companyData.latitude;
        const longitude   = companyData.longitude;
        let   iconImage   = 'marker-icon-blue.png';

        if (companyData['currentWorkers'] > 0)
            iconImage = 'marker-icon-green.png';

        //console.log('Add marker to map for company : ' + companyName);

        Self.companyMarkers[companyName] = { lat: latitude, lng: longitude, message: companyName }

        const markerLatLng = L.latLng(latitude, longitude);
        const title = GetCompanyMapMarkerTitle(companyData);

        // see https://leafletjs.com/reference-1.4.0.html#popup
        ////marker.bindPopup("<b>Popup for</b><br>" + companyName);   // replaced by OnClick()

        //console.log('Marker added to map for "' + companyName + '"');

        // see https://leafletjs.com/reference-1.4.0.html#marker
        const marker = L.marker(markerLatLng,
            {
                draggable: false,

                // this is the tooltip hover stuff
                title: title,

                companyId: companyData['company_id'],

                // see https://leafletjs.com/reference-1.4.0.html#icon
                // this is a permanent label.
                icon: new L.DivIcon({
                    ////     className: cssClassname,
                    html: '<img class="my-div-image" src="../common/js/third_party/leaflet/images/' + iconImage + '" />'
                        + '<span style="color:darkblue">' + companyName + '</span>',
                    className: 'dummy',      // hide the square box See https://gis.stackexchange.com/questions/291901/leaflet-divicon-how-to-hide-the-default-square-shadow
                    iconSize: [41, 51],      // size of the icon
                    iconAnchor: [20, 51],    // point of the icon which will correspond to marker's location
                    popupAnchor: [0, -51]    // point from which the popup should open relative to the iconAnchor
                })
            }).addTo(Self.map).on('click', Self.CompanyMarkerClicked);

        Self.companyMarkers.push(marker);
        Self.overlappingMarkerSpiderfier.addMarker(marker);

        Self.UpdateMapBoundariesIfRequired(latitude, longitude);
    };      // AddMarkerToMap()
1

There are 1 best solutions below

1
On BEST ANSWER

You can add to the OMS Layer a click event:

oms.addListener('click', function(marker) {
  console.log(marker)
  marker.setIcon(greenIcon)
});

This is a little confusing but the click event is only called when the markers spiderfied and you click on a certain marker or it is a marker which is not in a spider "group"

In How to use

Instead of adding click listeners to your markers directly via marker.addEventListener or marker.on, add a global listener on the OverlappingMarkerSpiderfier instance instead. The listener will be passed the clicked marker as its first argument.

Here a vanilla js example

I think your code should look like:

Self.overlappingMarkerSpiderfier.addListener('click', function(marker) {
  console.log(marker)
  Self.CompanyMarkerClicked(marker); // if you pass the marker
});

Self.AddCompanyMarkerToMap = function (companyData) {
    // ...
    const marker = L.marker(markerLatLng, {
        draggable: false,
        // this is the tooltip hover stuff
        title: title,
        companyId: companyData['company_id'],
        icon: new L.DivIcon({
            ////     className: cssClassname,
            html: '<img class="my-div-image" src="../common/js/third_party/leaflet/images/' + iconImage + '" />'
                + '<span style="color:darkblue">' + companyName + '</span>',
            className: 'dummy',      // hide the square box See https://gis.stackexchange.com/questions/291901/leaflet-divicon-how-to-hide-the-default-square-shadow
            iconSize: [41, 51],      // size of the icon
            iconAnchor: [20, 51],    // point of the icon which will correspond to marker's location
            popupAnchor: [0, -51]    // point from which the popup should open relative to the iconAnchor
        })
    }).addTo(Self.map); // <----------- remove the click event

    Self.companyMarkers.push(marker);
    Self.overlappingMarkerSpiderfier.addMarker(marker);
};

I saw that you commented

// see https://leafletjs.com/reference-1.4.0.html#popup

This is the doc of the Leaflet version 1.4.0 the current version is 1.7.1 be careful that you using the correct one ;)

And probably you saw already the Library Leaflet.markercluster but maybe it has a few more features that you can need