terrain elevation query


Just wondering whether there are any options available or being considered for programmatically querying terrain elevation served by http://cesium.agi.com/terrain ? Applications I’m thinking of include keeping a camera above the terrain, placing objects on terrain, drawing polylines on terrain (as an interim before more advanced techniques are implemented), pick on terrain etc.


  • Server query API for http://cesium.agi.com/terrain that returns highest detail result.
  • Client side query using approximation based on local terrain tiles.


Hi Chris,

That sort of thing is definitely planned, but not currently possible. Well, you could sort of do it today by fishing around in CentralBodySurface’s data structures to find the tiles that were rendered last frame and doing height queries against them. You’d probably need to do the queries on the GPU, though, because currently the heightmaps are thrown away once the vertex arrays are created, in order to save memory.

It’s also possible, of course, to download tiles separately from the rendering and do height queries against them. The (very subject to change) format of the terrain tiles is documented here:


Hi Kevin,

I started a quick investigation of a client side query function. I set it up to be called like this…

// user fills an array of Cesium.Cartographic() query locations

// the height value of the points will be modified in place

var terrainProvider = new Cesium.CesiumTerrainProvider(…);

var cartPts = … ;
var tileLevel = 8; // The desired tile level for queries

Cesium.when(terrainProvider.queryElevation(cartPts, tileLevel, scene.getContext()), elevationSuccessFunction);

I’m then setting up a set of query tiles, requesting them manually, and doing as per the terrain providers but without the final createResources(). I’m assuming the output of transformGeometry() would be standard across the terrain providers since there’s a centralized createTileEllipsoidGeometryFromBuffers(). I’m therefore taking a similar approach and centralizing what I’ve done in TerrainProvider.js in the hope that it would work with other terrain providers. I’m also hopeful that there would automatically be some level of caching via the context since I’m still using the standard Cesium tile request mechanisms.

The mechanics seem to be starting to work and I can litter billboards across a terrain. There’s still issues to be worked through such as tile fail/rejections, interpolation etc. Also, sequencing of tile requests then transformation etc is a bit different in my case since I’m working outside of a draw loop so I’ve just blocked it in with setTimeout() calls for now.

I realize the approach I’ve investigated will be brittle as the terrain branch continues to evolve. You mentioned that terrain query is a service you would like to provide in the future. I’d like to gauge your level of interest in me cleaning up what I have so far and contributing this to the terrain branch so that it can be reviewed, integrated and kept in sync with the work you are doing. If not, it would still be helpful for me if I could quiz you on details at some stage. A client side query seems appealing to me, particularly if it could work across the various terrain providers.


The attached image shows 20,000 point samples which results in 20 tiles requested at tile level 10. The speed seems reasonable. It calculates them and renders the billboards before the actual map has finished resolving. I think this is due to the map working up from tile level 0 whereas I’m going straight to the desired tile level for the point sampling.


Hi Chris,

This sounds very cool!

Are you doing your work in a publicly-visible repo? I’d like to take a look at your approach, with the understanding that it’s very much a work in progress. Whatever state it is currently in is fine - no need to spend a bunch of time cleaning it up at this stage. In the short term, I’ll probably be hesitant to pull it into the terrain branch because I really need to focus on stabilizing what’s already there so we can get it into master. But in the slightly longer term, I’m game. Lots of folks have asked for this feature, so it will be good to have a way to do it, even if we eventually change how it works.

I agree with your observation that the output of transformGeometry should be standard across terrain providers. This is a problem with the terrain providers in general right now, and something we need to clean up before merging terrain into master: there’s way too much duplication of tricky code in each of them.


Just to add to the discussion, we at Raytheon are using a bit different approach for draping features on terrain.

We're pulling out the heightmaps (integer arrays) before they're translated into vertices and copying them into a manager. Then whenever we need to render a feature (or polygon/polyline vertex) on the terrain, we make a getAltitude(location) call to get the altitude at the point. The manager then searches for the heightmap containing the point with the highest level of detail available and calculates the height at that point using the heightmap.

Because it is based on tiles that are already loaded, it doesn't require any additional tile loads, and is responsive enough to be done while drawing (so clicking and dragging to create a circle allows the circle to be draped as it's drawn). The downside, of course, is that polygons are drawn as meshes based only on edge vertices.

-- David

That sounds cool David. How well does it handle changing the viewpoint,
e.g. navigating a camera over the terrain? Are the queries cheap enough
and geometry light enough that you can regularly update poly vert positions
as the terrain LOD changes?


Hey Chris, sorry, I missed this and just now came back across it.

I believe we currently can make on the order of 60 queries per millisecond at high volume. The updates get triggered on the load of the terrain tiles and unless you have a bunch of circles in one area, things are pretty snappy (I think usually when we've had performance issues it hasn't been bottle-necked by the height queries). Basically, what you're going to see visually is that when terrain tiles load and the terrain morphs, the features on the terrain move up/down with the terrain.

I've even toyed around with throwing those queries into the geodetic scaling method when drawing meshes. (Because otherwise, that method has to be bypassed to drape polygons onto terrain). Probably our solution to that will involve a different approach for very large features (that actually need that geodetic scaling to wrap around the curvature of the earth) than for features that cover a relatively small area.

Hi guys, just wondering if you have any updates on draping things over terrain? It’s hard to tell what category that falls under on the Roadmap.

I’m trying to render some basic 3D extruded polygons on some terrain, and it’s difficult (as a novice) to figure out how to go about it. Google Earth, which we’re trying to migrate away from, can do it automatically with KML polygons; I think it just elevates a 2D polygon and draws sides down to the terrain surface. Currently we’re finding the minimum height of the terrain in the bounds of the polygon and elevating the polygon by that much, but it’s not very effective for polygons whose area is on the order of a hill.

Hi Oliver,

This is also something we are interested it, but we won’t be able to start on it until after this fall or later as we’re busy on other fundamental features like 3D models.

In the meantime, you can improve your workaround a bit by sampling the height of each point in the polygon and raising it slightly above terrain (make sure to render with the depth test on). To access the individual points, you’ll want to use the geometry system directly instead of the higher-level Polygon primitive. Checkout the draft tutorial and Sandcastle examples in the “Geometries” tab.




I have exactly the same problem as you. How you manage it?

Patrick, please could you tell me how it is possible to enable the depth buffer?