getHeight randomly returns undefined

Hi,

Following up on a previous post (http://cesiumjs.org/forum.html#!msg/cesium-dev/NvnW8_cNEQM/L6FCmkVABgAJ)

Here is a test case (sandcastle) that reproduces the problem. The camera flies over terrain and getHeight() is called, at each frame, at camera location.

Observe how, when the camera gets close to the ground, the number of undefined value increases quickly.

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

var cesiumTerrainProviderMeshes = new Cesium.CesiumTerrainProvider({
url : ‘//assets.agi.com/stk-terrain/world’,
requestWaterMask : true,
requestVertexNormals : true
});
viewer.terrainProvider = cesiumTerrainProviderMeshes;

var position = [6.8832, 45.9452, 1520];
var undefinedHeights = 0;
viewer.scene.preRender.addEventListener(function() {

position[0] += 0.00001;
position[1] += 0.00001;

viewer.camera.position = Cesium.Cartesian3.fromDegrees(position[0], position[1], position[2]);

var height = viewer.scene.globe.getHeight(new Cesium.Cartographic.fromDegrees(position[0], position[1], 0));

if (!height) {
    console.log(undefinedHeights++);
}

viewer.camera.setView({
    orientation: {
        heading: 0.5,
        pitch: 0,
        roll: 0
    }
});

});

``

Thanks,

Xavier.

Hello Xavier,

I think this should work:

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

var cesiumTerrainProviderMeshes = new Cesium.CesiumTerrainProvider({

url : ‘//assets.agi.com/stk-terrain/world’,

requestWaterMask : true,

requestVertexNormals : true

});

viewer.terrainProvider = cesiumTerrainProviderMeshes;

var position = [6.8832, 45.9452, 1520];

var undefinedHeights = 0;

viewer.scene.preRender.addEventListener(function() {

position[0] += 0.00001;

position[1] += 0.00001;

viewer.camera.position = Cesium.Cartesian3.fromDegrees(position[0], position[1], position[2]);

var pt = viewer.camera.position;

var ht = viewer.scene.globe.getHeight(Cesium.Cartographic.fromCartesian(pt));

if (!ht) {

console.log(undefinedHeights++);

}

else{console.log("Height is: " + ht);}

viewer.camera.setView({

orientation: {

heading: 0.5,

pitch: 0,

roll: 0

}

});

});

``

As soon as the page loads, since terrain is not loaded instantaneously, it enters in the “if” block, but as soon as the terrain is loaded, you get height value in variable “ht”.

Hope it helps.

Regards,

Parthesh.

Hi Parthesh,

Thanks for the hint. It does indeed improves things.

However, this is not an ideal solution as you have to provide an altitude in order to get… an altitude.

I believe the whole point of a method like getHeight would be to find out the terrain elevation from just some latitude, longitude coordinates.

What I implemented based on your input: I call getHeight with altitude=0, hope for a result, try again until I get one and re-use the last “good” result as a reference to call getHeight again the next time.

Also there are still some “undefined” value returned every now and then, even though much less.

As I try to run a physics engine on Cesium, it is vital to have a reliable elevation measurement.

Thanks for your help,

Xavier.

Actually I was only trying to give a hint, but if you want some elaboration kindly try following code in Cesium Sandcastle… You might get an idea of what I wanted to explain. First wait for the terrain to load and then click the button.

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

viewer.camera.setView({

destination : Cesium.Cartesian3.fromDegrees(6.8832, 45.9452, 10000)

});

var cesiumTerrainProviderMeshes = new Cesium.CesiumTerrainProvider({

url : ‘//assets.agi.com/stk-terrain/world’,

requestWaterMask : true,

requestVertexNormals : true

});

viewer.terrainProvider = cesiumTerrainProviderMeshes;

Sandcastle.addToolbarButton(‘Show Height’, function() {

var pt = Cesium.Cartographic.fromDegrees(6.8832, 45.9452);

console.log(pt);

var ht = viewer.scene.globe.getHeight(pt);

console.log(ht);

viewer.entities.add({

position : Cesium.Cartesian3.fromRadians(pt.longitude, pt.latitude,ht),

point : {

pixelSize : 15,

color : Cesium.Color.RED

}

});

});

``

Regards,

Parthesh.

correct link to original post: https://groups.google.com/d/msg/cesium-dev/NvnW8_cNEQM/L6FCmkVABgAJ

I’m sorry I read your question wrongly at the first time… My bad…

I think this is happening as the Levels of Details of the terrain are more that required due to which even you zoom in or out slightly the tiles will reload. I can think of one thing that you can do…

– Use your own terrain using Geoserver Terrain Provider.

– While using gdal retile to create imagepyramid, choose LOD to be 4-6.

– Follow the complete process form here. (https://github.com/kaktus40/Cesium-GeoserverTerrainProvider)

Using this method the reloading of tiles will happen between larger distances of zooming in or out.

Regards,

Parthesh.

Hi Parthesh,

No worries.

I submitted a but report about this issue.

Thanks,

Xavier.