getHeight randomly returns undefined

255 views
Skip to first unread message

Xavier Tassin

unread,
Jan 8, 2016, 8:38:14 AM1/8/16
to cesium-dev
Hi, 


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.

Parthesh Bulbule

unread,
Jan 10, 2016, 12:43:03 AM1/10/16
to cesium-dev
Hello Xavier,

   I think this should work:

   
var viewer = new Cesium.Viewer('cesiumContainer');


var cesiumTerrainProviderMeshes = new Cesium.CesiumTerrainProvider({
    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.

Xavier Tassin

unread,
Jan 10, 2016, 7:54:35 AM1/10/16
to cesium-dev
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.

Parthesh B.

unread,
Jan 11, 2016, 1:36:51 AM1/11/16
to cesium-dev
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({
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.

Xavier Tassin

unread,
Jan 12, 2016, 5:21:24 AM1/12/16
to cesium-dev


On Friday, January 8, 2016 at 2:38:14 PM UTC+1, Xavier Tassin wrote:

Parthesh B.

unread,
Jan 12, 2016, 11:29:39 PM1/12/16
to cesium-dev
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.

Xavier Tassin

unread,
Jan 18, 2016, 4:56:17 AM1/18/16
to cesium-dev
Hi Parthesh,

No worries.

I submitted a but report about this issue.

Thanks,

Xavier.
Reply all
Reply to author
Forward
0 new messages