Capturing click events on clusters with markerclus

2019-07-07 06:32发布

问题:

I'm playing with the angular-leaflet-directive, and getting the marker names from a mouse click is straight forward. I just listen for the leafletDirectiveMarker.click event and then access args.markerName.

angular-leaflet-directive also works with markercluster, so I can cluster markers that have the same coordinates or ones that are close by. However, I would like to do the following, but it is not clear from the documentation on how to do it:

  • Make user double-click on cluster to zoom in. Currently doing a single click on a cluster will zoom in on the markers. see example.

  • How to listen for click event on cluster and get all marker names in the cluster. The documentation for clustermarker has a cluster event:

    markers.on('clusterclick', function (a) {
    console.log('cluster ' + a.layer.getAllChildMarkers().length);
    });
    

    But I'm not sure what event I should be listening to using angular-leaflet-directive.

回答1:

As far as your first question goes, you'll have to hook the doubleclick and pass it the fire('click') command after overriding the usual click event. Probably more trouble than its really worth, especially on mobile - and not something I can easily solve.

Regarding your second question, I have just solved it.

$scope.openMarker is a reference to an ng-click event in my jade template that is attached to an ng-repeat which pulls images and their id's from the database.

         $scope.openMarker = function(id) {
            var _this = [];
            _this.id = id;
            leafletData.getMarkers()
                .then(function(markers) {
                    $scope.london = {
                        lat: $scope.markers[_this.id].lat,
                        lng: $scope.markers[_this.id].lng,
                        zoom: 19
                    };                  
                    var _markers = [];
                    _markers.currentMarker = markers[_this.id];
                    _markers.currentParent = _markers.currentMarker.__parent._group;
                    _markers.visibleParent = _markers.currentParent.getVisibleParent(markers[id]);
                    _markers.markers = markers;
                    return _markers;
                }).then(function(_markers){
                    if (_markers.visibleParent !== null) {
                        _markers.visibleParent.fire('clusterclick');
                    } else {
                        _markers.currentMarker.fire('click');
                    }
                    return _markers;
                }).then(function(_markers){
                     _markers.currentParent.zoomToShowLayer(_markers.markers[ _this.id ], function() {
                        $scope.hamburg = {
                            lat: $scope.markers[_this.id].lat,
                            lng: $scope.markers[_this.id].lng,
                            zoom: 19
                        };
                        if (_markers.currentMarker !== null) {
                            _markers.currentMarker.fire('click');
                        } else {
                            _markers.visibleParent.fire('clusterclick');
                            _markers.currentMarker.fire('click');
                        }
                    });

                });

        };

You can read more about how I came to this solution here at github.



回答2:

Much like many people, I too had a long search with no results. While experimenting with another method, I came across this:

$timeout(function(){
    leafletData.getLayers().then(function(layers) {
        $scope.markerClusterGrp = layers.overlays.locations;
        var clusters            = $scope.markerClusterGrp.getLayers();
        $scope.markerClusterGrp.on('clustermouseover', function (a) {
            var clusterObjects  = a.layer.getAllChildMarkers();
            console.log(clusterObjects);
        });
        $scope.markerClusterGrp.on('clusterclick', function (a) {
            var clusterObjects = a.layer.getAllChildMarkers();
            console.log(clusterObjects);
        });
    });

},1000);

It works the same, the difference is that it requires a timeout in order to wait for the layer to render with all markers (my understanding, correct me if wrong :-) ).

I hope this helps anyone searching for an angular solution. Just remember to include $timeout in your controller dependencies.