Leaflet / Leaflet.markercluster

Marker Clustering plugin for Leaflet
MIT License
3.94k stars 996 forks source link

Marker popup doesn't opens when It's inside group #180

Closed kiselev-dv closed 10 years ago

kiselev-dv commented 11 years ago

Hi here is my case.

  1. Create 2 markers m1, m2 with same coordinates and bind popup to each other.
  2. Create two links, with m1.openPopup(); and m2.openPopup();
  3. Add them to marker cluster, they are olways in one group.

Popups will not shown on map, until group will be spiderfied, because marker not shown and this._map for marker are undefined.

So I use hack:

if(m1._map === undefined ) {
       m1.__parent.spiderfy();
} 

How to make it as default behaviour, to spiderfy marker group, for marker which openPopup() was called?

tbergeron commented 11 years ago

Hi,

I'm suffering from the same issue actually. But I use Mapbox (which uses leaflet).

When I trigger openPopup is simply non-existing.

I wonder if your hack would apply for me using Mapbox. How do you use it? Where do you call .spidefy from?

I'll try to investigate. Still I'm looking forward for this.

kiselev-dv commented 11 years ago

Marker instance have field __parent (I found it using firebug), that point to marker group. Marker group have spiderfy() function.

There more simple way: just set _map property for marker, but in this case marker doesn't appears on map, just popup only anchored where marker should be.

danzel commented 11 years ago

Hrm, yeah this is an interesting use case. You'd need to do something like:

L.Marker.prototype.openPopupBackup = L.Marker.prototype.openPopup;
L.Marker.prototype.openPopup = function() {
if (!this._map && this.__parent) {
this.__parent.spiderfy();
}
this.openPopupBackup();
}

Then calling openPopup on a marker should work. Give that a try :)

Might need a delay after calling spiderfy, haven't tested.

kiselev-dv commented 11 years ago

I use spiderfied callback. Here is my test page. Sorry, for links to local files. I dont know, is it worth to push it in upstream.

<html>
<head>
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.5/leaflet.css" />
    <link rel="stylesheet" href="file:///home/dkiselev/desktop/MarkerCluster.css" />
    <link rel="stylesheet" href="file:///home/dkiselev/desktop/MarkerCluster.Default.css" />

    <script src="http://cdn.leafletjs.com/leaflet-0.5/leaflet.js"></script>     
    <script src="file:///home/dkiselev/desktop/leaflet.markercluster.js" ></script>

    <script>
    L.Marker.prototype.openPopupBackup = L.Marker.prototype.openPopup;
    L.Marker.prototype.openPopup = function() {
        if (!this._map && this.__parent) {
            this.__parent._group.on('spiderfied', this.doneSpiderfy, this);
            this.__parent.spiderfy();
        }
        else {
            this.openPopupBackup();
        }
    }
    L.Marker.prototype.doneSpiderfy = function() {
        this.__parent._group.off('spiderfied', this.doneSpiderfy, this);
        this.openPopupBackup();
    }

    </script>

    <script>
    function init(){
        var map = L.map('map').setView([51.505, -0.09], 13);

        // add an OpenStreetMap tile layer
        L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
            attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        }).addTo(map);

        map.markerClusters = new L.MarkerClusterGroup({ showCoverageOnHover: false });
        map.addLayer(map.markerClusters);

        // add a marker in the given location, attach some popup content to it and open the popup
        m1 = L.marker([51.5, -0.09]).addTo(map.markerClusters)
            .bindPopup('m1 marker popup');

        m2 = L.marker([51.5, -0.09]).addTo(map.markerClusters)
            .bindPopup('m2 marker popup');      
    }
    </script>
</head>

<body onload="init();">
    <div><a onclick="m1.openPopup();">Marker 1</a><a onclick="m2.openPopup();">Marker 2</a></div>
    <div id="map" style="width:100%; height:800px;"></div>
</body>
</html>
tbergeron commented 11 years ago

This actually works well! The only issue I'm having is that when I click on something in my sidebar, it pops other popups of that clusterer node before showing the good one. That's a minor issue though. Any idea? You can check out what happens here: http://vinpin.com/map Thanks!

kiselev-dv commented 11 years ago

I tried http://vinpin.com/map but it's seems normally for me. I don't understand what's the problem.

danzel commented 10 years ago

Using zoomToShowLayer is the recommended way to do this. https://github.com/Leaflet/Leaflet.markercluster#other-methods

two3d commented 1 year ago

To open the hidden popup, simply modify the openPopup function of leaflet.js:

openPopup:function(t,i){if(!this._map&&this.__parent){this.__parent.spiderfy()}return this._popup&&this._map&&(i=this._popup._prepareOpen(this,t,i),this._map.openPopup(this._popup,i)),this}

I simply added this:

if(!this._map&&this.__parent){this.__parent.spiderfy()}