STK High-res terrain and height

261 views
Skip to first unread message

Jerrold Siegel

unread,
Jul 17, 2015, 9:45:55 AM7/17/15
to cesiu...@googlegroups.com
I have been moving Google Earth buildings to Cesium fairly successfully. The one issue  is getting the correct height. For example for

position: Cesium.Cartesian3.fromDegrees(-90.2020842502553,38.63132390529897,118.5)


I calculate the longitude and latitude but end up approximating the height and getting 118.5 , the ground level at that point by more or less trial and error.
Can somebody point me to a reference, or is there code that gives me the ground level at a particular long/lat?
Thanks

Hannah Pinkos

unread,
Jul 17, 2015, 10:43:10 AM7/17/15
to cesiu...@googlegroups.com
Hello Jerrold,

Look at the code for Sample Everest Terrain.  Cesium has a function called sampleTerrain that takes in an array of Cartographic lon/lat positions and a terrain provider, then sends the array of Cartographic positions with the correct height to a callback function.
This should save you from having to guess the correct heights for a bunch of positions.

We also have this demo that shows how to get the terrain height from a mouse position: http://analyticalgraphicsinc.github.io/cesium-google-earth-examples/examples/groundAlt.html

Best Regards,

-Hannah

Jerrold Siegel

unread,
Jul 17, 2015, 2:46:21 PM7/17/15
to cesiu...@googlegroups.com

Hi Hannah, 
I had played with it before but got nowhere. I am clearly missing something because I see that it works.
 I just tried again beginning with
position = new Cesium.Cartographic(longitude, latitude) 

and either got height=0 or NaN. depending on what I invoked. 
Thanks,
Jerry

Hannah Pinkos

unread,
Jul 17, 2015, 3:58:53 PM7/17/15
to cesiu...@googlegroups.com
Hi Jerry,

Here's some sample code for how to get the height for a single position:

var viewer = new Cesium.Viewer('cesiumContainer', {timeline : false, animation : false});

var cesiumTerrainProviderMeshes = new Cesium.CesiumTerrainProvider({
    requestWaterMask : true,
    requestVertexNormals : true
});
viewer.terrainProvider = cesiumTerrainProviderMeshes;


function placePin(cartographics) {
    console.log(cartographics[0]);
    var pinBuilder = new Cesium.PinBuilder();

    var pin = viewer.entities.add({
        position : viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographics[0]),
        billboard : {
            image : pinBuilder.fromColor(Cesium.Color.ROYALBLUE, 48).toDataURL(),
            verticalOrigin : Cesium.VerticalOrigin.BOTTOM
        }
    });

    viewer.zoomTo(pin);
}

var position = Cesium.Cartographic.fromDegrees(-90.2020842502553,38.63132390529897);
Cesium.when(Cesium.sampleTerrain(viewer.terrainProvider, 14, [position]), placePin);


Remember that Cartographic uses radians by default, so if you want to use degrees you need to use the function Cesium.Cartographic.fromDegrees(). 
I'm happy to answer any more questions if something comes up.

-Hannah

Jerrold Siegel

unread,
Jul 17, 2015, 4:50:33 PM7/17/15
to cesiu...@googlegroups.com

Hi Hannah,   
  
That did it!

Thanks again,
Jerry
 

Jerrold Siegel

unread,
Jul 18, 2015, 11:17:57 AM7/18/15
to cesiu...@googlegroups.com
Hannah,

I do need a bit more help. The problem is synchronizing various computation. I have to compute, say, 20 heights, make sure all the computations are completed and then use the heights to build and place 20 buildings and do various other tasks. I tried to use "promise" which didn't work. Here is a simple minded version of the issue is:
--------------------------------------------------------------------------------------------------------------------

var viewer = new Cesium.Viewer('cesiumContainer');
var viewer = new Cesium.Viewer('cesiumContainer');
var this_height;
var the_flag=false;
var count=1;
 
var cesiumTerrainProviderMeshes = new Cesium.CesiumTerrainProvider({
    requestWaterMask : true,
    requestVertexNormals : true
});
viewer.terrainProvider = cesiumTerrainProviderMeshes;

function checkFlag() {
    if(the_flag == false) {
       window.setTimeout(checkFlag, 100); 
    } else {
        if(count==1){
      alert(this_height+" inside");
      count=0;
        }
        };
}

function get_height(cartographics) {
    var thisstring=cartographics[0].toString().split(",");
    this_height=thisstring[2].trim().split(")")[0];
    the_flag=true;
}                                                                              
var position = Cesium.Cartographic.fromDegrees(-90.20200114367877,38.63073438333625);
Cesium.when(Cesium.sampleTerrain(viewer.terrainProvider, 14, [position]), get_height);
checkFlag();
alert(this_height+" outside");
-----------------------------------------------------------------------------------------------------------------------------------------
The "inside" computation of this_height is correct but the "outside" alert occurs first and  is undefined.

How can I be sure that the "outside" code does not run before sampleTerrain is completed. I know I could get an array of heights but placing all the code I need in checkFlag() is really not viable.
Thanks,
Jerry

Hannah Pinkos

unread,
Jul 20, 2015, 10:42:13 AM7/20/15
to cesiu...@googlegroups.com
Hi Jerry,

I'm not sure exactly what you need to do, but because the sampleTerrain function runs asynchronously I would put any code that depends on the heights inside the get_height callback function.  This way the application can still run and doesn't have to wait for all of the heights to be computed.  Things that do need to the height, such as your buildings, will pop in once the height is computed.  If you don't have too many positions, this should happen almost instantly.

I'm not sure how much I can help with your asynch issues, but this is the library that we use to handle promises: https://github.com/cujojs/when
Maybe there's something in their API that might be helpful for you.

Sorry for not having more helpful suggestions.  Maybe someone else will have a better idea.

Best,

Hannah

Jerrold Siegel

unread,
Jul 20, 2015, 3:27:39 PM7/20/15
to cesiu...@googlegroups.com

Hi Hanna, 

If you would allow me a bit of an exaggeration, everything depends on the computation of the height. I am trying to figure out how to postpone the rendering until after the heights have been computed. Sort of a wait() - notify() for Threads...knowing that I am not dealing with Threads.  Anyway, thank you for pointing me to the library, it will be my next stop.

Jerry
Reply all
Reply to author
Forward
0 new messages