z order between data source and imagery layer

1. A concise explanation of the problem you're experiencing.

My data source always displays on top of imagery layer, is there a way to hide data source under imagery layer?

2. A minimal code example. If you've found a bug, this helps us reproduce and repair it.

3. Context. Why do you need to do this? We might know a better way to accomplish your goal.
My map need to work offline so I use GeoJsonDataSource to display country borders. When adding a small imagery layer, I'd like to see the imagery cover the country borders underneath it.

4. The Cesium version you're using, your operating system and browser.
Cesium: 1.38, Windows 10, Firefox 62

There’s no way to place data source/entities underneath imagery layers, but there’s a couple of tricks you can do. The easiest I can think of is to simply hide the GeoJsonDataSource when you detect an internet connection/add the imagery.

If it’s a data type that clipping planes support, you could potentially clip the boundary of your object around the layer so it looks as if the layer is on top, this would be a bit more complicated though.

In this case, simply hiding might be the best option. Does that work for you?

Hiding the dataSource will work if imagery layer covers the whole globe. For smaller imagery layer, we still want to the datasource as for the base map.

I have a related question. We used Cesium's Natural Earth offline map which support up to 5 levels. Is there a way to detect when zooming in past the 5th layer (when images start to get blurry)? I want to show the datasource when this happens and hide it when zooming out.

The only other thing I can think of is if you can somehow convert your datasource to an actual imagery layer, that way you can easily order and manipulate it with other imagery layers. What kind of data is in your datasource now?

For your other question, I don’t think Cesium directly exposes the zoom level. The TileCoordinatesImageryProvider does actually display what level each tile is at, and you can see it in the Cesium Inspector example (https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/?src=Cesium%20Inspector.html) by clicking on “Terrain > Show tile coordinates”.

You might look at how that’s implemented to get an idea. Since this is determined based on camera distance to ellipsoid surface, you can compute that instead and use it as an estimate, see Hannah’s answer here:


If you do figure out a good way to expose the zoom level a contribution would be very much appreciated! I can imagine others would benefit from this as well. Let me know how it goes.

My datasource is a topojson converted from countries shapefile downloaded from naturalearthdata.com . I imagine convert to imagery layer will have issue with border get blurry when zooming in close.

I found a way to get the zoom level to show/hide my data source:
viewer.camera.moveEnd.addEventListener(function() {
    var tp = viewer.scene.globe._surface._tilesToRender;
    if(tp.length > 0){
        console.log("level:" + tp[0].level);
        if(tp[0].level > 5){
            viewer.dataSources.get(0).show = true
            viewer.dataSources.get(0).show = false

Thanks for posting your solution!

I did a quick search on the forum for “tilesToRender” and looks like there might be a simpler way to do this:


But again, since this uses private variables the API may change without warning between releases. It might be good for Cesium to officially support this, so I opened a GitHub issue for it: