kml ground overlay


this is my first post :slight_smile: here,
congrats for Cesium it is absolutely great!

Hi was training to learn how to visualize a "ground overlay" using cesium using as input a geotiff image [2]
i was using the google earth plugin before and for that purpose i was generating a kml ground overlay

for that purpose i was generating the tiles using gdal :

gdalbuildvrt filename_tmp.vrt filename.tif
gdalwarp -of VRT -t_srs EPSG:4326 filename_tmp.vrt filename_geo.vrt
gdal_translate -of vrt -expand rgba filename_geo.vrt filename.vrt -p geodetic -k filename.vrt

the generated kml is available here [3]

can you please help me to get started ?
what i'm looking for is a sample html code that load a Cesium globe adding the image [2] as overlay.

i'd love to see cesium running on the osgeolive :slight_smile:
next i will work on an overview and quick start, any help/contribution will be great

many thanks for your precious help!



i set up a running demo on localhost following the tutorial.
is my understanding that what i need is :


to load my georeferenced image.
is tha correct ?
do i need to provide the input in a specific map projection (perhaps epsg:4326)

i tried the following code but of course i'm missing something important,
thanks for your precious help!


<!DOCTYPE html>
<html lang="en">
    <title>Hello World!</title>
    <script type="text/javascript" src="Cesium/Cesium.js"></script>
      @import url(Cesium/Widgets/CesiumWidget/CesiumWidget.css);
      body {
        padding: 0;
        margin: 0;
        overflow: hidden;
  <div id="cesiumContainer"></div>
    var cesiumWidget = new Cesium.CesiumWidget('cesiumContainer');
    // attempt to load a geotif
    var imageryUrl = 'data/';
    var imageryProvider = new Cesium.SingleTileImageryProvider({
        url : imageryUrl + 'image.tif'});
  var layers = widget.centralBody.getImageryLayers();


You’re actually closer than you think to having this working. Tiling up your imagery by using is the first (and hardest) step, and you’ve already done that. With that done, you can hook up the generated tile pyramid to using using the TileMapServiceImageryProvider. Just provide the URL of the directory that contains the tilemapresource.xml file, and Cesium will figure out the rest.

One caveat is that you may not see the imagery until you zoom in close to it. To fix that, regenerate your tiles and specify the -z option to set the minimum zoom to 0. Set the maximum zoom to whatever came up with originally.

One more caveat is that WebGL cannot use images unless those images come from the exact same host and port that served the HTML file the browser is displaying, unless the server serving the image explicitly allows this. If you need to set up the server to explicitly allow it, see

You can’t load the TIF directly using SingleTileImageryProvider because most web browsers do not support loading TIF files. Even if they did, tiling it up with gdal2tiles will give you much better performance.


Thank you Kevin,
something is coming …

i changed the code to :

Hello World! @import url(Cesium/Widgets/CesiumWidget/CesiumWidget.css); body { padding: 0; margin: 0; overflow: hidden; }

where elev1cl5nn5 is the directory of my tiles (i stored it inside the same directory where the html code is)

… so is not an URL :frowning:

now in the js console i have :

GET http://localhost:8080/elev1cl5nn5/0/0/0.png 404 (Not Found) Cesium.js:331

An error occurred in “h”: Cesium.js:343

Failed to obtain image tile X: 0 Y: 0 Level: 0. Cesium.js:343

GET http://localhost:8080/elev1cl5nn5/1/1/1.png 404 (Not Found) Cesium.js:331

An error occurred in “h”: Cesium.js:343

Failed to obtain image tile X: 1 Y: 0 Level: 1. Cesium.js:343

An error occurred in “h”: Cesium.js:343

Failed to obtain image tile X: 624 Y: 269 Level: 10. Cesium.js:343

GET http://localhost:8080/elev1cl5nn5/9/312/377.png 404 (Not Found) Cesium.js:331

An error occurred in “h”: Cesium.js:343

Failed to obtain image tile X: 312 Y: 134 Level: 9.

this seems to be good (the code try to load the tiles)

but bad because the tiles are stored in a “non web available” directory.

i’m on osx right now, so i have to investigate where to put the directory in order to have it available in the browser (no /var/www/ like on linux)

is there a way to load that directory from a custom location ?

perhaps using absolute path and file:// instead of url ?

thank you very much for your help!


You can’t load from a “file://” URL because it will fail cross-origin checks. Since you appear to be using the Cesium-provided, Jetty-based web server on port 8080, the easiest way to get up and running is to copy your imagery directory somewhere underneath the directory (which is the Cesium root directory) that that web server is already serving.



sorry i didn’t understand where i should move the directory containing the tiles

the root directory is :


file listing :









the directory “elev1cl5nn5” is the one that contain the tiles and tilemapresource.xml

I’m running the server.js

var connect = require(‘connect’);




using node :

node server.js

i tried to move it under :


and then i changed in the html code :

url : 'Cesium/elev1cl5nn5/

but i got the same log,

where i should move the elev1cl5nn5 directory ?

i’m sure i’m missing something basic in web/js development, sorry about that

thank you,


That looks right to me. Try removing the trailing ‘/’ from the end of the URL.

Actually, nevermind. It should work with our without a trailing slash. Do you have both and extracted into the same /Users/epi/Desktop/Cesium-b17? You don’t need to, I’m just asking because I’m trying to understand your directory structure.

i unpacked the tarbal :

all the contents is in :


it looks like :

i didn’t download

Ok, I see what’s going on now. For the directory setup in that screenshot, your URL should be ‘/elev1cl5nn5’. But the other problem is that you’re missing tile levels 0-10. You can fix that by re-running and specifying an initial level of 0, as I mentioned before. Or you can ignore it (and the accompanying errors in the log) and the imagery should still appear when you zoom in close enough for the levels you do have to be used (which is pretty close for levels 11 and 12).


Those Core/Scene/Renderer folders aren’t normally part of the zip package, which is what confused Kevin, but they snuck in with the last release because whomever published it has stray .orig files left over by git in his branch. We’ve remedied the situation so it doesn’t happen next release. Sorry for the confusion.


fixing the url adding ‘/’ and rerunning gdaltotiiles with --zoom=0-10

i do not have any error log and the image is visualized correctly

i’ve a question about the image rendering and its resolution,

in the screenshot below i have the tile (the biggest : level 12) i have side by side

the tile opened in a image viewer and in the browser in Cesium :

there is a loss in resolution in the web view, is there any setting i need to enable to have the image rendered in full resolution ?

thanks a lot!


Great, glad to hear you got it working.

To get the full resolution, you need to include all 12 levels instead of telling to stop at 10. Use --zoom-0-12.