sampleTerrain returns 404 for STK-Terrain level 11

Hey there. I have found that the STK-Terrain returns "undefined" for height (and writes a JS error to the console for the 404 from sampleTerrain) for certain coordinates that are valid. I have code below that shows the problem. As it is below, it will show undefined for height in the console and show a JS error. If you change the last line to tile depth of 9 instead of 11, it works properly.

//if you don't change the default Terrain Provider to the STK-Terrain below ([1]), then it will not happen, but you always get 0 for height because the default terrain has no heights
var terrainProviders = Cesium.createDefaultTerrainProviderViewModels();

var viewer = new Cesium.Viewer('cesiumContainer',{
terrainProviderViewModels:terrainProviders,
                         selectedTerrainProviderViewModel: terrainProviders[1],});

var terrainSamplePositions;
terrainSamplePositions = ;
var longitude = -2.1945539525212125;
var latitude = 0.8642748429733929;
var longitudeBad = -3.0145815911295206;
var latitudeBad = 1.024137168972982;
var position = new Cesium.Cartographic(longitude, latitude);
var positionBad = new Cesium.Cartographic(longitudeBad, latitudeBad);

terrainSamplePositions.push(position);
terrainSamplePositions.push(positionBad);

function sampleTerrainSuccess(updated) {
    var ellipsoid = Cesium.Ellipsoid.WGS84;
    var height = null;
    viewer.entities.suspendEvents();
    viewer.entities.removeAll();
  
    for (var i = 0; i < updated.length; ++i) {
  
        var position = updated[i];
        var cartoPos = new Cesium.Cartographic(position.longitude, position.latitude);
  
        console.warn('height = ' + position.height);
  
  viewer.entities.add({
            name : position.height.toFixed(1),
            position : ellipsoid.cartographicToCartesian(position),
            billboard : {
                verticalOrigin : Cesium.VerticalOrigin.BOTTOM,
               image : '../images/facility.gif'
            }
        });
    }
    viewer.entities.resumeEvents();
}

//Cesium.when(Cesium.sampleTerrain(viewer.terrainProvider, 9, terrainSamplePositions), sampleTerrainSuccess);
Cesium.when(Cesium.sampleTerrain(viewer.terrainProvider, 11, terrainSamplePositions), sampleTerrainSuccess);

Hi there. The tileset hosted by the STK Terrain Server is multiresolutional, meaning that in certain parts of the world we can have highly detailed terrain, while over open ocean we may only go down to level 9. In this case, the terrain server is returning 404 because it does not have this tile. Before calling sampleTerrain, you can check to see if the terrain tile containing this position is available at level 11. Here is some sample code that conveys the general idea for how your code can work through this.

var tileXY;

terrainProvider.tilingScheme.positionToTileXY(cartographicPos, 11, tileXY);

var tileExistsOnServer = terrainProvider.getTileDataAvailable(tileXY.x tileXY.y, 11);

So what happens if the tile doesn’t exist? Try the parent tile:

tileXY.x = Math.floor(tileXY.x / 2);

tileXY.y = Math.floor(tileXY.y / 2);

var tileExistsOnServer = terrainProvider.getTileDataAvailable(tileXY.x tileXY.y, 10);

You can repeat this until tileExistsOnServer is true.

Alex

You Rock! Thank you! This is a great explanation and a work-around. My biggest issue was that I couldn’t “catch” the 404, so this check will help a lot.

Thanks again!

Joy