Save a reference to your object layer(s) and then remove them before re-adding to avoid duplicates. It looks like you were already on the right track, but your current objectsLayer
has a scope inside getEpc()
.. you need to define this at a higher level, and you need to maintain a separate layer for each checkbox.
Note that Leaflet already supports this concept out-of-box by using the Layers control. You can create overlays, add them to the layers control, and use checkboxes to automatically toggle the layers, which will add and remove them for you.
However, if you want to do it on your own, you need to do a few things:
First, modify getEPC()
to return a reference to the new layer:
function getEpc(items, icon) {
var objectsLayer = L.geoJson(items, {
pointToLayer: function(items, latlng) {
var result;
if (icon !== undefined) {
result = L.marker(latlng, {
icon: icon
});
} else {
result = L.marker(latlng);
}
return result;
}
});
leafletData.getMap().then(function(map) {
objectsLayer.addTo(map);
});
// return layer reference so we can manage it
return objectsLayer;
}
Then, you need to manage the layers as you add and remove them.
Note: it will get very tedious to do this for each checkbox.. you may want to use a watchGroup
or watchCollection
instead. But to keep the example simple, I tried to use your code without making major modifications:
// global cache for overlays.
// you may want to put this somewhere better, but keeping example simple..
var overlays = {};
$scope.$watch('locations.somecheck1', function(somecheck1) {
if ($scope.locations.somecheck1 === true) {
findItem.find(function(err, items) {
lastLocationItems = items[0].items;
items = lastLocationItems.map((item) => GeoService.toGeoJSON(item, { idKey: '_id', geometryKey: 'lastLocation'}));
var objectsLayer = getEpc(items, ssccIcon); // get new layer
// save layer reference so it can be removed later
overlays["somecheck1"] = objectsLayer;
});
} else if(overlays["somecheck1"]) {
leafletData.getMap().then(function(map) {
map.removeLayer(overlays["somecheck1"]); // remove cached layer
});
}
}, true);
$scope.$watch('locations.somecheck2', function(somecheck1) {
if ($scope.locations.somecheck2 === true) {
findItem.find(function(err, items) {
lastLocationItems = items[0].items;
items = lastLocationItems.map((item) => GeoService.toGeoJSON(item, { idKey: '_id', geometryKey: 'lastLocation'}));
var objectsLayer = getEpc(items, ssccIcon); // get new layer
// save layer reference so it can be removed later
overlays["somecheck2"] = objectsLayer;
});
} else if(overlays["somecheck2"]) {
leafletData.getMap().then(function(map) {
map.removeLayer(overlays["somecheck2"]);
});
}
}, true);
// etc, for each checkbox (but prefer to refactor into smaller, reusable methods)
Best Answer
All controls in Leaflet should inherit the
removeFrom
method, so to remove your existinglayerscontrol
, you can use: