How to remove individual KML DataSources ?

Please I need help . I tried a simple example to load 2 KML DataSources. When I try to remove a single KML DataSource, the DataSource’s features still visible in the viewer. Is there any way to Hide/Show one DataSource’s features without removing the second?
Here is my code :

var Layer1 = Cesium.KmlDataSource.load(’…/…/SampleData/Bus_Stop.kml’);

var Layer2= Cesium.KmlDataSource.load(’…/…/SampleData/Car_Parking.kml’);

//////Add layers///

Sandcastle.addToolbarButton('add Layer1 ', function() {

viewer.dataSources.add(Layer1 );

});

Sandcastle.addToolbarButton('add Layer2 ', function() {

viewer.dataSources.add(Layer2 );

});

//////// Remove layers//

Sandcastle.addToolbarButton(‘remove Layer1’, function() {

viewer.dataSources.remove(Layer1);

});

Sandcastle.addToolbarButton(‘remove Layer2’, function() {

viewer.dataSources.remove(Layer2);

});

Layer1 and Layer 2 are not instances of KmlDataSource, they are Promises to the data source instance once it’s down loading. If you are not familiat with Promises, I recommend reading this article: http://www.html5rocks.com/en/tutorials/es6/promises/ Cesium specifically uses the when promise library that is mentioned in the article.

I rewrote your sample code in two ways, first to do what you want using promises, and second to avoid promises and simply create instances of KmlDataSource. In such a simple example, promises don’t get you much (other than letting you know when the data is ready to go). But when you need to wait for the data to be loaded before taking action, promises are really useful.

//This version uses promises

var viewer = new Cesium.Viewer(‘cesiumContainer’);

var promise1 = Cesium.KmlDataSource.load(’…/…/SampleData/kml/facilities/facilities.kml’);

var promise2 = Cesium.KmlDataSource.load(’…/…/SampleData/kml/gdpPerCapita2008.kmz’);

Cesium.when(promise1, function(dataSource1){

Sandcastle.addToolbarButton(‘Add DataSource 1’, function() {

viewer.dataSources.add(dataSource1);

});

Sandcastle.addToolbarButton(‘Remove DataSource 1’, function() {

viewer.dataSources.remove(dataSource1);

});

});

Cesium.when(promise2, function(dataSource2){

Sandcastle.addToolbarButton(‘Add DataSource 2’, function() {

viewer.dataSources.add(dataSource2);

});

Sandcastle.addToolbarButton(‘Remove DataSource 2’, function() {

viewer.dataSources.remove(dataSource2);

});

});

//And this version uses new KmlDataSource(). Load still returns a promise in this case, but we just ignore it.

var viewer = new Cesium.Viewer(‘cesiumContainer’);

var dataSource1 = new Cesium.KmlDataSource();

dataSource1.load(’…/…/SampleData/kml/facilities/facilities.kml’);

var dataSource2 = new Cesium.KmlDataSource();

dataSource2.load(’…/…/SampleData/kml/gdpPerCapita2008.kmz’);

Sandcastle.addToolbarButton(‘Add DataSource 1’, function() {

viewer.dataSources.add(dataSource1);

});

Sandcastle.addToolbarButton(‘Remove DataSource 1’, function() {

viewer.dataSources.remove(dataSource1);

});

Sandcastle.addToolbarButton(‘Add DataSource 2’, function() {

viewer.dataSources.add(dataSource2);

});

Sandcastle.addToolbarButton(‘Remove DataSource 2’, function() {

viewer.dataSources.remove(dataSource2);

});

Hi Matthew,

Thank you very much for your help,I can understand now. It works fine for me and I can keep going in my project.

I just wanna ask one more thing, can cesium support KML Network Link?

Best regards

Cesium has basic support for NetworkLink already, but we don’t support auto-refreshing or network link updates and regions. We plan on supporting them in the future. The server that is hosting the NetworkLink needs to either be the same origin as the app or support cross-origin resource sharing. If neither of these is true, you can still use them, but you have to go through a proxy. You might want to check out this post, where I go into some details: https://groups.google.com/d/msg/cesium-dev/xz2xwKogybY/jt8h174rknwJ

I have uploaded kml files in cesium ion. Now I am displaying the list of kml asstes in my application using below code.

var kmlfiles = Cesium.IonResource.fromAssetId(assetID)
                .then(function (resource) {
                  return Cesium.KmlDataSource.load(resource, {
                    camera: viewer.scene.camera,
                    canvas: viewer.scene.canvas
                  });
                })
                .then(function (dataSource) {
                  return viewer.dataSources.add(dataSource);
                });
              viewer.zoomTo(kmlfiles );

I want to show/hide kml file on checkbox click. Problem is that I have collection of kml datasources in kmlfiles object and i didn't get the filename or assetid in kmlfiles object, So that i will remove particular kml datasource. Any solution?

Thanks

kmlList.png

Did you ever find a solution to this Rohit? I'd be interested in doing something similar if you got it working.

Is your situation that you have multiple datasources of KML files and you want to toggle each one on/off, or that you’re trying to toggle features within one KML data source on/off?

My situation is that I have multiple datasources that I would like to toggle on and off, using a checkbox or radio button group. (I only need 1 at a time) I've tried using viewer.dataSources.add/remove but that never seems to remove the datasouce and crashes on the second click event, and the datasource.show = true/false doesn't seem to turn the KML icons on/off either.

Removing the dataSources should work, like in this Sandcastle example:

https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/?src=GeoJSON%20and%20TopoJSON.html

If it’s crashing, that is potentially a bug. A community member just stumbled onto something similar here that I’ve documented here:

https://github.com/AnalyticalGraphicsInc/cesium/issues/7758

Are you able to share a sample of your data that causes this crash along with a Sandcastle example I can run? That’ll help us determine if it’s a bug and fix it.

Omar,

If I used the viewer.resources.removeAll() then it seems to work OK without crashing. When I was trying to remove things individually is when I was running into problems. Fortunately, I only need to have one datasource at a time, so removeAll should work for me, thank you.

this works great.
now plz tell me how to add or 3d tileset by this method.

now plz tell me how to add and remove 3d tileset by this method.

Hello, I’m interested in adding and removing czml data sources using a checklist like shown above, or even if I have to adding a bunch of buttons that add each cesium ion file to the viewer. But this discussion only talks about the remove all function. I want to be able to switch between say 10 different czml files and check which ones are being displayed in the viewer or not. Unfortunately the sandcastle toolbar and button load data functions don’t work with cesium/cesium ion. I’ve been looking for a solution for this for days, I haven’t found anything that explains how to do something like this using data from cesium ion or cesium code, everything seems to just say do it manually with html/js etc but then there are no examples of exactly how to do that with cesium ion. I feel like the expectation is that I should just be able to learn how to do it but i’m having a hard time finding leads to get everything working and am hoping someone will be able to help.

see:

var promise = Cesium.IonResource.fromAssetId(xxxxx)
.then(function (resource) {
return Cesium.CzmlDataSource.load(resource);
})
//.then(function (dataSource) {
//return viewer.dataSources.add(dataSource);
//})
.otherwise(function (error) {
console.log(error);
});

I put this together from all the examples I could find, but when I switch to the dataSource function it crashes the page saying TypeError: Cannot read property ‘length’ of undefined. Also, even if it did work, idk how I would get it to do this for multiple files from cesium ion, and this is a button not a checklist.

I attempted to use a solution using Jquery earlier but was unsuccessful in that as well, but it was my first time every trying to use Jquery at anything.

@mhernandez624

Thank you for the detailed post. You are correct, this thread primarily addresses the remove-all function. Could you please send over a sandcastle demo of what you have so far? I do not quite understand how the following code has been incorporated into your project.

var promise = Cesium.IonResource.fromAssetId(xxxxx)
.then(function (resource) {
return Cesium.CzmlDataSource.load(resource);
})
//.then(function (dataSource) {
//return viewer.dataSources.add(dataSource);
//})
.otherwise(function (error) {
console.log(error);
});

Let me know if you have any questions or concerns!

-Sam