0

I am new to CartoDB/Leaflet. Here's my fiddle... http://jsfiddle.net/zippyferguson/fLkqgf4q/1/

If you click the play button, I want it to load data to the map year by year from 1966 to 2015 from a CartoDB query. But, with each iteration, the map is cleared of data, and then the next year data appears. I am looking to load the next year data and remove the previous year data underneath in the previous layer, without the clearing of everything on the map. If you comment out this line in the fiddle, you will kind of see what I am looking for.

removeAllLayersExcept(layer);

...this function is an attempt to remove all layers on the map except the one just loaded.

But, with removeAllLayersExcept(layer) commented out, that just keeps putting more layers on the map. I don't understand why it clears the whole map each iteration.

0

You correctly remove previous layer(s) only once the data for the new layer is received, but not its tiles (images). That is why your map appears empty for a short time.

You could first attach your removeAllLayersExcept callback to the "load" event of your new Tile Layer.

Fired when the tile layer loaded all visible tiles.

Then you would also leave a short timeout before actually removing other layer(s), because the new tiles will appear with a little delay and transition, even if they are correctly loaded already.

cartodb.createLayer(map, layerSource)
  .addTo(map)
  .done(function(layer) {
    //removeAllLayersExcept(layer);
    layer.once("load", function () { // Remove only once the new tile layer has downloaded all tiles in view port.
      removeAllLayersExcept(layer);
    });
    setTimeout(updateMap, 1000);
  })
  .error(function(err) {
    console.log("error: " + err);
  });

function removeAllLayersExcept(new_layer) {
  console.log('new_layer._leaflet_id:' + new_layer._leaflet_id);
  var layer_index = 0;
  map.eachLayer(function(layer) {
    if (layer_index > 0 && layer._leaflet_id != new_layer._leaflet_id) {
      console.log('layer removed:' + layer._leaflet_id);
      //map.removeLayer(layer);
      setTimeout(function () { // give a little time before removing previous tile layer because new one will appear with some transition.
        map.removeLayer(layer);
      }, 500);
    }
    layer_index++;
  });
}

Demo: http://jsfiddle.net/fLkqgf4q/5/

Note: you may also need to harden your removeAllLayersExcept function to cover the case where a more recent Tile Layer is loaded before a previous one (due to some back connectivity or whatever). Otherwise the previous layer will make the new one being removed from map. But then you also need to handle the case when the user manually drags the cursor backwards.

  • Thank you! The "load" event is what I was looking for. I assumed that is what what was happening with the done event. Very good. – zippyferguson Dec 7 '15 at 15:36
0

For a shorter version since I also needed this and found another version:

map.eachLayer(function(layer) {
    if( layer instanceof L.GeoJSON )
       map.removeLayer(layer);
});
  • it would be perfect if we could target a specific layer. – OZGUR SARIKAMIS Apr 5 '18 at 12:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.