Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use leaflet slider along with markercluster in Javascript?

i am making a map that uses a slider to show or hide markers, and i want to add clustering functionality, each one alone works perfectly, but i want the slider to show the markers, and in case of markers very close to use a cluster. the problem is that both, the individual and the marker clusters are showing, i want the shown markers to cluster not clusters being there all the time

 <script type="text/javascript">
		var sliderControl = null;
                    //creating layers
                    var cities = new L.LayerGroup();
                    var mbAttr = 'Map data &copy; <a href="http://openstreetmap.org">OpenstreetMap</a> contributors, ' +
                    '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
                    'Imagery © <a href="http://mapbox.com">Mapbox</a>',
                    mbUrl = 'https://{s}.tiles.mapbox.com/v3/{id}/{z}/{x}/{y}.png';
                    var grayscale = L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {id: 'remote-sensing.n8k508ak', attribution: mbAttr, accessToken: 'pk.eyJ1IjoicmVtb3RlLXNlbnNpbmciLCJhIjoiYWNiYzg0ZWU2Mjk3ZTU5NjE4MmQyZWEzZTY2ZWNlYjIifQ.U7mp4MXdcjaIwW_syAqriQ'})
                    , streets = L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {id: 'remote-sensing.84f6c85a', attribution: mbAttr, accessToken: 'pk.eyJ1IjoicmVtb3RlLXNlbnNpbmciLCJhIjoiYWNiYzg0ZWU2Mjk3ZTU5NjE4MmQyZWEzZTY2ZWNlYjIifQ.U7mp4MXdcjaIwW_syAqriQ'});
                    //create and add the layers to the map
                    var map = L.map('map', {
                    center: [33.9, 35.877],
                            zoom: 10,
                            layers: [ streets, cities]
                    });
					
		
                    //get length of the entries array
                    var len = "{{events|length}}";
                    var date = 1;
                    var time = 2;
                    var lat = 4;
                    var lon = 5;
                    //get events from database
                    var stri = "{% for event in events %} {{event.timestamp|date:"Y-m-d H"}}  {{event.lat}} {{event.lon}} <br>  {% endfor %}";
                    var entry =  stri.split(" ");
                    //create the clustermarker object
                    var markers = new L.markerClusterGroup();
                    //create markers and add to cluster
					var mymark;
                    for (var t = 0; t < len; t++) {
					mymark = new L.marker([entry[lat], entry[lon]], {time: "\"" + entry[date] + entry[time] + "+01\""});
                    mymark.bindPopup("<b>Accident</b><br>this is marker number " + (t + 1) + " with coordinates :[" + entry[lat] + "," + entry[lon] + "]").openPopup();
                    markers.addLayer(mymark);
                    date += 8;
                    time += 8;
                    lat += 8;
                    lon += 8;
            }
	mymark = new L.marker([33.8,35.5]);
	markers.addLayer(mymark);                                       
	mymark = new L.marker([33.8,35.5]);
	markers.addLayer(mymark);  
	mymark = new L.marker([33.8,35.5]);
	markers.addLayer(mymark);  
	mymark = new L.marker([33.8,35.5]);
	markers.addLayer(mymark);  
	mymark = new L.marker([33.8,35.5]);
	markers.addLayer(mymark);  
	mymark = new L.marker([33.8,35.5]);
	markers.addLayer(mymark);  
	mymark = new L.marker([33.8,35.5]);
	markers.addLayer(mymark);  
	mymark = new L.marker([33.8,35.5]);
	markers.addLayer(mymark);  
	mymark = new L.marker([33.8,35.5]);
	markers.addLayer(mymark);  	
            //add cluster to map
          // map.addLayer(markers);
                    //baseLayers for the map
                    var baseLayers = {
                    "Grayscale": grayscale,
                            "streets": streets
                    };
					layerGroup = L.layerGroup(markers);
	// $.getJSON("data.geojson", function(data) {

    //  var testlayer = L.geoJson(data);
      var sliderControl = L.control.sliderControl({  position: "topright",   layer: markers,  range: false , follow: 3});
												// ({position: "topright", layer: testlayer, follow: 3});
map.addControl(sliderControl);
sliderControl.startSlider();//});
        </script>

sorry for some comments, some are just actual code made as comments for debuggung

like image 836
jaafar Nasrallah Avatar asked Oct 31 '22 18:10

jaafar Nasrallah


1 Answers

Edit March 2016:

You can now simply use the plugin Leaflet.MarkerCluster.LayerSupport to achieve this, without having to change Leaflet Slider plugin code.

See the demo LayerSupport with LeafletSlider plugin.

In your case, you would do:

var markers = L.layerGroup();

// Add all your markers into `markers` Layer Group.

// Check into MCG Layer Support!
// Add to map first before checking in.
L.markerClusterGroup.layerSupport().addTo(map).checkIn(markers);

var sliderControl = L.control.sliderControl({
  position: "topright",
  layer: markers,
  range: false,
  follow: 3
});

map.addControl(sliderControl);
sliderControl.startSlider();

Disclosure: I am the author of that plugin.


Original answer:

Refrain from adding (removing) individual markers directly to (from) the map, when they are handled by a MarkerClusterGroup which is on the map at the same time.

MCG expects to be the only group managing the markers, and if you want to show / hide some of the markers, you have to use markers.addLayer(myMarker); (or removeLayer), where markers is your MCG.

The Leaflet Time-Slider (sliderControl) plugin is therefore incompatible as-is with MCG: it directly adds (removes) markers to (from) the map. It does not know anything about your MCG.

Nevertheless, you should be able to make it compatible with MCG by replacing any map.addLayer by markers.addLayer (same for removeLayer) in the plugin code. Do not forget to add your MCG to the map.

like image 88
ghybs Avatar answered Nov 14 '22 19:11

ghybs