How to add and remove marker clusters on a leaflet map?












3















I am using leaflet market cluster and I am setting markers as circle markers.




Leaflet version: leaflet@1.3.1



Leaflet cluster version: markercluster@1.3.0




NOTE




$.fn.almDone... and $.fn.almEmpty... are just some functions I use for
my ajax callbacks




I am drawing some markers on the map if we have results, and clear the markers we've drawn if on a second callback we have zero results. Or simply tell the user we've got zero results and therefore zero markers.



We have 2 arrays with values where I get the coordinates:



var longitude = ;
var latitude = ;
var count = ;


We set the var to stopAjax true when we start:



var stopAjax = true;


On click we start the search and we set stopAjax to false



$(".alm-filters--button").on("click", function(){
stopAjax = false;
});


And that is the basic logic, now we define two functions:



// This is run when we finish the call and we have results
// So on the callback we run the function to draw the markers

$.fn.almDone = function(alm){
drawMarkers();
};

// Let's draw the markers

function drawMarkers() {

// This is the logic to read latitude and longitude arrays
// and push to a new array the two values as pair of coords
// eg. 4.66, 4,5555

var i;
for (i = 0; i < longitude.length; ++i) {
pair=[ parseFloat( latitude[i] ) , parseFloat( longitude[i] ) ]
count.push( pair );
$("#searchNations").removeAttr("disabled");
$(this).attr("disabled", "disabled");
var myYears = $('#years').val();
$("#ajax-load-more ul").attr("data-meta-value", myYears);
};

// We check if we said to run ajax
// and if so draw the markers
// for myself I had also to retrieve those coords
// and place them in individual inputs for the form

if(stopAjax == false) {
L.MarkerCluster.include({
spiderfy: function(e) {
var childMarkers = this.getAllChildMarkers();
this._group._unspiderfy();
this._group._spiderfied = this;

// Fill the markersList.

markersList.innerHTML = childMarkers
.map((marker, index) => `<li>Marker ${index + 1}: ${marker.getLatLng()}</li>`)
.join('');

// If there are any childMarkers
// draw the cluster and run a form

if(childMarkers.length > 0) {
// Match the lat and lng numbers from the string returned by getLatLng()
const [lat, lng] = `${ childMarkers[0].getLatLng() }`.match(/(-?d+.d*)/gi);

// Construct the required string value from the extracted numbers
const requiredString = `${ lat }, ${ lng }`;

// Use requiredString to populate the value attribute of the input field in OP

// grab the coords in individual inputs
// that's just for my specific case

$("#longiTude").attr("value",lat);
$("#latiTude").attr("value", lng);

// run a form to see results

submitSearchForm();
}
},
unspiderfy: function() {
this._group._spiderfied = null;
}
});

// this bit is for single marker
// we want to add a click to run the form
// also for the single marker and grab the coords
// and place them in inputs for the form

var mcg = L.markerClusterGroup().addTo(map);

circles = new L.MarkerClusterGroup();
for (var i = 0; i < count.length; i++) {
var a = count[i];
var circle = new L.CircleMarker([a[0], a[1]]);
circles.addLayer(circle);
circle.on('click', function (e) {
var curPos = e.target.getLatLng();
$("#longiTude").val(curPos.lat);
$("#latiTude").val(curPos.lng);
submitSearchForm();
});
}

// we add the markers to the map
map.addLayer(circles);

// we empty the arrays for the future calls

count = ;
longitude = ;

// we set again stopAjax var to true to reset
stopAjax = true;
}
}


Then the zero results function



//This is run when we have zero results

$.fn.almEmpty = function(alm) {
stopAjax = true;
clearMarkers();
};

// We empty the arrays and we
// clear the previously drawn markers

function clearMarkers(stopAjax) {
if(stopAjax == true) {
count = ;
longitude = ;
map.removeLayer(circles);
}
// if zero results, we launch a modal to advise user
$('#zeroResults').modal('show');
}


The above works if We first have results and then we do another search and we have zero results, but in case we've made a search at first and we've got zero results, then we will have an error:




Uncaught ReferenceError: circles is not defined



And that's correct because since we get into the empty function we try to clear the markers which we haven't ever defined as we never got into the draw markers function where we define circles.



I am getting very confused on how to draw the markers and make the var circles available in both cases.




p.s. Happy for anyone to improve the logic regardless of the question issue











share|improve this question





























    3















    I am using leaflet market cluster and I am setting markers as circle markers.




    Leaflet version: leaflet@1.3.1



    Leaflet cluster version: markercluster@1.3.0




    NOTE




    $.fn.almDone... and $.fn.almEmpty... are just some functions I use for
    my ajax callbacks




    I am drawing some markers on the map if we have results, and clear the markers we've drawn if on a second callback we have zero results. Or simply tell the user we've got zero results and therefore zero markers.



    We have 2 arrays with values where I get the coordinates:



    var longitude = ;
    var latitude = ;
    var count = ;


    We set the var to stopAjax true when we start:



    var stopAjax = true;


    On click we start the search and we set stopAjax to false



    $(".alm-filters--button").on("click", function(){
    stopAjax = false;
    });


    And that is the basic logic, now we define two functions:



    // This is run when we finish the call and we have results
    // So on the callback we run the function to draw the markers

    $.fn.almDone = function(alm){
    drawMarkers();
    };

    // Let's draw the markers

    function drawMarkers() {

    // This is the logic to read latitude and longitude arrays
    // and push to a new array the two values as pair of coords
    // eg. 4.66, 4,5555

    var i;
    for (i = 0; i < longitude.length; ++i) {
    pair=[ parseFloat( latitude[i] ) , parseFloat( longitude[i] ) ]
    count.push( pair );
    $("#searchNations").removeAttr("disabled");
    $(this).attr("disabled", "disabled");
    var myYears = $('#years').val();
    $("#ajax-load-more ul").attr("data-meta-value", myYears);
    };

    // We check if we said to run ajax
    // and if so draw the markers
    // for myself I had also to retrieve those coords
    // and place them in individual inputs for the form

    if(stopAjax == false) {
    L.MarkerCluster.include({
    spiderfy: function(e) {
    var childMarkers = this.getAllChildMarkers();
    this._group._unspiderfy();
    this._group._spiderfied = this;

    // Fill the markersList.

    markersList.innerHTML = childMarkers
    .map((marker, index) => `<li>Marker ${index + 1}: ${marker.getLatLng()}</li>`)
    .join('');

    // If there are any childMarkers
    // draw the cluster and run a form

    if(childMarkers.length > 0) {
    // Match the lat and lng numbers from the string returned by getLatLng()
    const [lat, lng] = `${ childMarkers[0].getLatLng() }`.match(/(-?d+.d*)/gi);

    // Construct the required string value from the extracted numbers
    const requiredString = `${ lat }, ${ lng }`;

    // Use requiredString to populate the value attribute of the input field in OP

    // grab the coords in individual inputs
    // that's just for my specific case

    $("#longiTude").attr("value",lat);
    $("#latiTude").attr("value", lng);

    // run a form to see results

    submitSearchForm();
    }
    },
    unspiderfy: function() {
    this._group._spiderfied = null;
    }
    });

    // this bit is for single marker
    // we want to add a click to run the form
    // also for the single marker and grab the coords
    // and place them in inputs for the form

    var mcg = L.markerClusterGroup().addTo(map);

    circles = new L.MarkerClusterGroup();
    for (var i = 0; i < count.length; i++) {
    var a = count[i];
    var circle = new L.CircleMarker([a[0], a[1]]);
    circles.addLayer(circle);
    circle.on('click', function (e) {
    var curPos = e.target.getLatLng();
    $("#longiTude").val(curPos.lat);
    $("#latiTude").val(curPos.lng);
    submitSearchForm();
    });
    }

    // we add the markers to the map
    map.addLayer(circles);

    // we empty the arrays for the future calls

    count = ;
    longitude = ;

    // we set again stopAjax var to true to reset
    stopAjax = true;
    }
    }


    Then the zero results function



    //This is run when we have zero results

    $.fn.almEmpty = function(alm) {
    stopAjax = true;
    clearMarkers();
    };

    // We empty the arrays and we
    // clear the previously drawn markers

    function clearMarkers(stopAjax) {
    if(stopAjax == true) {
    count = ;
    longitude = ;
    map.removeLayer(circles);
    }
    // if zero results, we launch a modal to advise user
    $('#zeroResults').modal('show');
    }


    The above works if We first have results and then we do another search and we have zero results, but in case we've made a search at first and we've got zero results, then we will have an error:




    Uncaught ReferenceError: circles is not defined



    And that's correct because since we get into the empty function we try to clear the markers which we haven't ever defined as we never got into the draw markers function where we define circles.



    I am getting very confused on how to draw the markers and make the var circles available in both cases.




    p.s. Happy for anyone to improve the logic regardless of the question issue











    share|improve this question



























      3












      3








      3








      I am using leaflet market cluster and I am setting markers as circle markers.




      Leaflet version: leaflet@1.3.1



      Leaflet cluster version: markercluster@1.3.0




      NOTE




      $.fn.almDone... and $.fn.almEmpty... are just some functions I use for
      my ajax callbacks




      I am drawing some markers on the map if we have results, and clear the markers we've drawn if on a second callback we have zero results. Or simply tell the user we've got zero results and therefore zero markers.



      We have 2 arrays with values where I get the coordinates:



      var longitude = ;
      var latitude = ;
      var count = ;


      We set the var to stopAjax true when we start:



      var stopAjax = true;


      On click we start the search and we set stopAjax to false



      $(".alm-filters--button").on("click", function(){
      stopAjax = false;
      });


      And that is the basic logic, now we define two functions:



      // This is run when we finish the call and we have results
      // So on the callback we run the function to draw the markers

      $.fn.almDone = function(alm){
      drawMarkers();
      };

      // Let's draw the markers

      function drawMarkers() {

      // This is the logic to read latitude and longitude arrays
      // and push to a new array the two values as pair of coords
      // eg. 4.66, 4,5555

      var i;
      for (i = 0; i < longitude.length; ++i) {
      pair=[ parseFloat( latitude[i] ) , parseFloat( longitude[i] ) ]
      count.push( pair );
      $("#searchNations").removeAttr("disabled");
      $(this).attr("disabled", "disabled");
      var myYears = $('#years').val();
      $("#ajax-load-more ul").attr("data-meta-value", myYears);
      };

      // We check if we said to run ajax
      // and if so draw the markers
      // for myself I had also to retrieve those coords
      // and place them in individual inputs for the form

      if(stopAjax == false) {
      L.MarkerCluster.include({
      spiderfy: function(e) {
      var childMarkers = this.getAllChildMarkers();
      this._group._unspiderfy();
      this._group._spiderfied = this;

      // Fill the markersList.

      markersList.innerHTML = childMarkers
      .map((marker, index) => `<li>Marker ${index + 1}: ${marker.getLatLng()}</li>`)
      .join('');

      // If there are any childMarkers
      // draw the cluster and run a form

      if(childMarkers.length > 0) {
      // Match the lat and lng numbers from the string returned by getLatLng()
      const [lat, lng] = `${ childMarkers[0].getLatLng() }`.match(/(-?d+.d*)/gi);

      // Construct the required string value from the extracted numbers
      const requiredString = `${ lat }, ${ lng }`;

      // Use requiredString to populate the value attribute of the input field in OP

      // grab the coords in individual inputs
      // that's just for my specific case

      $("#longiTude").attr("value",lat);
      $("#latiTude").attr("value", lng);

      // run a form to see results

      submitSearchForm();
      }
      },
      unspiderfy: function() {
      this._group._spiderfied = null;
      }
      });

      // this bit is for single marker
      // we want to add a click to run the form
      // also for the single marker and grab the coords
      // and place them in inputs for the form

      var mcg = L.markerClusterGroup().addTo(map);

      circles = new L.MarkerClusterGroup();
      for (var i = 0; i < count.length; i++) {
      var a = count[i];
      var circle = new L.CircleMarker([a[0], a[1]]);
      circles.addLayer(circle);
      circle.on('click', function (e) {
      var curPos = e.target.getLatLng();
      $("#longiTude").val(curPos.lat);
      $("#latiTude").val(curPos.lng);
      submitSearchForm();
      });
      }

      // we add the markers to the map
      map.addLayer(circles);

      // we empty the arrays for the future calls

      count = ;
      longitude = ;

      // we set again stopAjax var to true to reset
      stopAjax = true;
      }
      }


      Then the zero results function



      //This is run when we have zero results

      $.fn.almEmpty = function(alm) {
      stopAjax = true;
      clearMarkers();
      };

      // We empty the arrays and we
      // clear the previously drawn markers

      function clearMarkers(stopAjax) {
      if(stopAjax == true) {
      count = ;
      longitude = ;
      map.removeLayer(circles);
      }
      // if zero results, we launch a modal to advise user
      $('#zeroResults').modal('show');
      }


      The above works if We first have results and then we do another search and we have zero results, but in case we've made a search at first and we've got zero results, then we will have an error:




      Uncaught ReferenceError: circles is not defined



      And that's correct because since we get into the empty function we try to clear the markers which we haven't ever defined as we never got into the draw markers function where we define circles.



      I am getting very confused on how to draw the markers and make the var circles available in both cases.




      p.s. Happy for anyone to improve the logic regardless of the question issue











      share|improve this question
















      I am using leaflet market cluster and I am setting markers as circle markers.




      Leaflet version: leaflet@1.3.1



      Leaflet cluster version: markercluster@1.3.0




      NOTE




      $.fn.almDone... and $.fn.almEmpty... are just some functions I use for
      my ajax callbacks




      I am drawing some markers on the map if we have results, and clear the markers we've drawn if on a second callback we have zero results. Or simply tell the user we've got zero results and therefore zero markers.



      We have 2 arrays with values where I get the coordinates:



      var longitude = ;
      var latitude = ;
      var count = ;


      We set the var to stopAjax true when we start:



      var stopAjax = true;


      On click we start the search and we set stopAjax to false



      $(".alm-filters--button").on("click", function(){
      stopAjax = false;
      });


      And that is the basic logic, now we define two functions:



      // This is run when we finish the call and we have results
      // So on the callback we run the function to draw the markers

      $.fn.almDone = function(alm){
      drawMarkers();
      };

      // Let's draw the markers

      function drawMarkers() {

      // This is the logic to read latitude and longitude arrays
      // and push to a new array the two values as pair of coords
      // eg. 4.66, 4,5555

      var i;
      for (i = 0; i < longitude.length; ++i) {
      pair=[ parseFloat( latitude[i] ) , parseFloat( longitude[i] ) ]
      count.push( pair );
      $("#searchNations").removeAttr("disabled");
      $(this).attr("disabled", "disabled");
      var myYears = $('#years').val();
      $("#ajax-load-more ul").attr("data-meta-value", myYears);
      };

      // We check if we said to run ajax
      // and if so draw the markers
      // for myself I had also to retrieve those coords
      // and place them in individual inputs for the form

      if(stopAjax == false) {
      L.MarkerCluster.include({
      spiderfy: function(e) {
      var childMarkers = this.getAllChildMarkers();
      this._group._unspiderfy();
      this._group._spiderfied = this;

      // Fill the markersList.

      markersList.innerHTML = childMarkers
      .map((marker, index) => `<li>Marker ${index + 1}: ${marker.getLatLng()}</li>`)
      .join('');

      // If there are any childMarkers
      // draw the cluster and run a form

      if(childMarkers.length > 0) {
      // Match the lat and lng numbers from the string returned by getLatLng()
      const [lat, lng] = `${ childMarkers[0].getLatLng() }`.match(/(-?d+.d*)/gi);

      // Construct the required string value from the extracted numbers
      const requiredString = `${ lat }, ${ lng }`;

      // Use requiredString to populate the value attribute of the input field in OP

      // grab the coords in individual inputs
      // that's just for my specific case

      $("#longiTude").attr("value",lat);
      $("#latiTude").attr("value", lng);

      // run a form to see results

      submitSearchForm();
      }
      },
      unspiderfy: function() {
      this._group._spiderfied = null;
      }
      });

      // this bit is for single marker
      // we want to add a click to run the form
      // also for the single marker and grab the coords
      // and place them in inputs for the form

      var mcg = L.markerClusterGroup().addTo(map);

      circles = new L.MarkerClusterGroup();
      for (var i = 0; i < count.length; i++) {
      var a = count[i];
      var circle = new L.CircleMarker([a[0], a[1]]);
      circles.addLayer(circle);
      circle.on('click', function (e) {
      var curPos = e.target.getLatLng();
      $("#longiTude").val(curPos.lat);
      $("#latiTude").val(curPos.lng);
      submitSearchForm();
      });
      }

      // we add the markers to the map
      map.addLayer(circles);

      // we empty the arrays for the future calls

      count = ;
      longitude = ;

      // we set again stopAjax var to true to reset
      stopAjax = true;
      }
      }


      Then the zero results function



      //This is run when we have zero results

      $.fn.almEmpty = function(alm) {
      stopAjax = true;
      clearMarkers();
      };

      // We empty the arrays and we
      // clear the previously drawn markers

      function clearMarkers(stopAjax) {
      if(stopAjax == true) {
      count = ;
      longitude = ;
      map.removeLayer(circles);
      }
      // if zero results, we launch a modal to advise user
      $('#zeroResults').modal('show');
      }


      The above works if We first have results and then we do another search and we have zero results, but in case we've made a search at first and we've got zero results, then we will have an error:




      Uncaught ReferenceError: circles is not defined



      And that's correct because since we get into the empty function we try to clear the markers which we haven't ever defined as we never got into the draw markers function where we define circles.



      I am getting very confused on how to draw the markers and make the var circles available in both cases.




      p.s. Happy for anyone to improve the logic regardless of the question issue








      javascript leaflet leaflet.markercluster






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 25 '18 at 15:42







      rob.m

















      asked Nov 25 '18 at 7:03









      rob.mrob.m

      3,719113983




      3,719113983
























          1 Answer
          1






          active

          oldest

          votes


















          1














          I would consider putting circles as a variable outside the scope of either function via var circles = undefined;. Note that the problem isn't that circles is undefined but that it is not defined, i.e not recognised as a variable.



          Then set it as you do in drawMarkers.



          On clearMarkers before the call to removeLayer check if (circles) to check that it is defined.
          Then set it to undefined again after calling removeLayer.






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53465385%2fhow-to-add-and-remove-marker-clusters-on-a-leaflet-map%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            I would consider putting circles as a variable outside the scope of either function via var circles = undefined;. Note that the problem isn't that circles is undefined but that it is not defined, i.e not recognised as a variable.



            Then set it as you do in drawMarkers.



            On clearMarkers before the call to removeLayer check if (circles) to check that it is defined.
            Then set it to undefined again after calling removeLayer.






            share|improve this answer




























              1














              I would consider putting circles as a variable outside the scope of either function via var circles = undefined;. Note that the problem isn't that circles is undefined but that it is not defined, i.e not recognised as a variable.



              Then set it as you do in drawMarkers.



              On clearMarkers before the call to removeLayer check if (circles) to check that it is defined.
              Then set it to undefined again after calling removeLayer.






              share|improve this answer


























                1












                1








                1







                I would consider putting circles as a variable outside the scope of either function via var circles = undefined;. Note that the problem isn't that circles is undefined but that it is not defined, i.e not recognised as a variable.



                Then set it as you do in drawMarkers.



                On clearMarkers before the call to removeLayer check if (circles) to check that it is defined.
                Then set it to undefined again after calling removeLayer.






                share|improve this answer













                I would consider putting circles as a variable outside the scope of either function via var circles = undefined;. Note that the problem isn't that circles is undefined but that it is not defined, i.e not recognised as a variable.



                Then set it as you do in drawMarkers.



                On clearMarkers before the call to removeLayer check if (circles) to check that it is defined.
                Then set it to undefined again after calling removeLayer.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 25 '18 at 7:20









                ShushanShushan

                1,1171814




                1,1171814






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53465385%2fhow-to-add-and-remove-marker-clusters-on-a-leaflet-map%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

                    Calculate evaluation metrics using cross_val_predict sklearn

                    Insert data from modal to MySQL (multiple modal on website)