KML does not load when using a drop-down list

I am new to Cesium so excuse this question which may have a very simple solution. I am trying to create a drop-down layer list as in this Sandcastle example. I changed the first entry to “Ports”, adding a kml file I created. However, the code does not work when I add this data source, so I am not sure what I am doing wrong as I only changed the data source path and the text to show on the drop-down list. Please let me know if you have any suggestions on what I am doing wrong here.
Sandcastle link

1 Like

@JC_2021

This is a great question! Thank you for bringing it to the community. In your sandcastle demo, I see that you added the following code.

{
  text: "Ports",
  onselect: function () {
    viewer.camera.flyHome(0);
    viewer.dataSources.add(
      Cesium.KmlDataSource.load(
        "C:/Cesium/Ports_exp.kml",
        options
      )
    );
  },
},

We are getting the error Request has failed. I suspect that CesiumJS is unable to find your file. I would double-check to ensure that you are adding the correct directory for your file.

A more robust alternative would be to upload your data to Cesium ion. Once your data is uploaded, select “Open a complete code example”

Upon opening the complete code example, you should see the following variable named promise.

var promise = Cesium.IonResource.fromAssetId(########)
  .then(function (resource) {
    return Cesium.KmlDataSource.load(resource, {
      camera: viewer.scene.camera,
      canvas: viewer.scene.canvas,
    });
  })
  .then(function (dataSource) {
    return viewer.dataSources.add(dataSource);
  })
  .then(function (dataSource) {
    return viewer.zoomTo(dataSource);
  })
  .otherwise(function (error) {
    console.log(error);
  });

In the CesiumJS documentation, we see that KmlDataSource.load() takes a promise.

https://cesium.com/learn/cesiumjs/ref-doc/KmlDataSource.html?classFilter=kmldata

In your sandcastle demo, you are using an invalid file path as a parameter. Try using the promise variable instead. Let me know if this works for you! I was able to get this working on my machine with the sample KML data that I uploaded. Here is a sandcastle demo that showcases what I put together.

You can use this demo as a reference. Let me know if you have any other questions or concerns! I am looking forward to seeing your project grow :smiley:

-Sam

1 Like

If you’re able to host your data online as Sam suggested, definitely do that!

If you need to load it locally, you should be aware that browsers implement strict limitations on pages that run from the local filesystem (file:// URLs). I don’t think any browsers have supported dynamically loading data from a URL like “C:/Cesium/Ports_exp.kml” for a long, long time.

I’m guessing you found Cesium because you want to write a web application that uses it. Whatever you’re using to serve your application during local development – NodeJS with express, Python SimpleHTTPServer, etc – can also be configured to serve your sample data. If your application is hosted on https://localhost:8080/index.html, you could have it serve https://localhost:8080/data/ports.kml and configure Cesium to use that URL.

3 Likes

Thank you Sam, I will give this a try

@JC_2021

Great, please keep me in the loop!

A huge thanks to @James_B for providing some additional input :rocket: :grinning:

-Sam