CesiumTerrainProvider V VRTheWorldTerrainProvider Heights


I am plotting a polyline on the map which uses co-ordinates taken from an external mapping service. When I create the polyline with my coordinates and heights with the VRTheWorldTerrainProvider, the polyline matches the height of the elevation almost perfectly.

When I switch to the CesiumTerrainProvider the polyline height is way off.

I checked a few points using the sampleTerrain when using the CesiumTerrainProvider and they were quite a bit different i.e. 65m (that my external API calculated) v 106 that the sampleTerrain provided.

Am I doing something wrong? I would ideally like to use the CesiumTerrainProvider with the co-ordinates I already have. They currently work with the VRTheWorldTerrainProvider but that seems slower to render.



Hi Aaron,

What you’re seeing is the difference between the mean sea level (MSL) reference surface and the WGS84 ellipsoid surface. In Cesium, all heights are relative to the WGS84 ellipsoid, and CesiumTerrainProvider is returning the correct heights. VRTheWorldTerrainProvider incorrectly returns heights relative to MSL instead of WGS84. This is a really common error; from what I understand it’s even considered “standard” to make this error in some industries, such as Modeling and Simulation, which is why it hasn’t been correct in VRTheWorldTerrainProvider. Your external mapping service may be making the same error, or perhaps you’re just interpreting the heights it provides incorrectly.

You can transform heights between MSL and WGS84 using the EGM96 model:


There’s a link on that page to an online EGM96 calculator you can use to verify that this is the difference you’re seeing.


Hi Kevin

Thanks for the swift reply.

I ran 2 co-ordinates through the calculator and they didn’t represent a height that either my map service provided or the sampleTerrain provided. Sorry for being slow!

Am I reading from above correctly that I can take the MSL heights I have already got and convert them to those related to the WGS84 ellipsoid surface.


The online calculator I mentioned computes the difference between WGS84 and MSL at the provided coordinates. So, to convert an MSL-referenced height to a WGS84-referenced height, add that value to the MSL height. There’s code on that page - unfortunately not in JavaScript - that you can use to transform the heights programmatically. Cesium will probably have built-in support for this transformation at some point, for what it’s worth.


Thank you very much for your help. That makes sense now. When I added the returned value the polyline fit just fine.

So now I need to write some code to automate this… :slight_smile:

Is the code you refer to in the fortran file?



Yes, that’s it. Really you’ll want to interpolate the 15 minute geoid height file, which can be found here:

This Stackoverflow question on the topic has a link to some Java code (from NASA World Wind) that may be easier to deal with than the Fortran code.



Doesn’t MSL change over time? Without a reference ellipsoid how can one measure changing sea levels and continental drift?

“…the IRM is not fixed to any point on Earth.”

Data should always be height from the reference ellipsoid as it’s called reference for a reason. If they give height from MSL then the obvious question is ‘then what is the height of MSL?’ Relative to the reference ellipsoid of course, and the xyz of any position relative to the surface of the ellipsoid can calculated just by knowing its 3 axis lengths. You can’t figure your position relative to Earth just from height above MSL (unless you also know MSL height from reference), so why not just give data relative to the reference ellipsoid in the first place.

If someone wants their:

height above MSL = their_height_above_ellipsoid - MSL_height_above ellipsoid

height above terrain = their_height_above_ellipsoid - terrain_height_above ellipsoid

I agree with you that providing terrain data relative to a reference ellipsoid is much more sensible than providing it relative to MSL. But sadly lots of terrain data (the majority of it actually) is provided relative to MSL or other MSL-like reference surfaces. Sure, MSL may change over time, but a given MSL model (like EGM96) is fixed relative to an ellipsoidal model, so it’s reasonable to use it as a reference surface.


Found this regarding KML. I believe Google Earth API is the same except Lat/Lon order.


Section 6.2 Coordinate Reference System (pg14)

"The KML encoding of every kml:Location and coordinate tuple uses geodetic longitude,

geodetic latitude, and altitude (in that order) as defined in Annex A by the GML Coordinate

Reference System (CRS) with identifier LonLat84_5773. Note that altitude is measured

from the vertical datum, which is the WGS84 EGM96 Geoid. The altitude measurement

(orthometric H) is illustrated in Figure 1."

"Figure 1: Altitude H is Measured from the Vertical Datum (Geoid) and is Compared to

the Ellipsoid Height h and the Geoid Undulation N."

So you’re given heights from undulation surfaces (both MSL and terrain are uneven.) OK, so lets say you know the tuples of 3 points. When looking from one point what is the 3D angle between the other 2 points? What is the 3D distance between any 2 points?

To calculate any of this you need to first convert heights to the common reference ellipsoid for all 3 points (then to Cartesian.) Google Earth API won’t give you any of these (camera,ground, or MSL) relative to reference ellipsoid, so you can’t calculate them. You’d have to reference an outside source for this information.

With Cesium you have access to Earth-Fixed xyz coordinates for position and orientation vectors. Plus the ability to create any ray to test distance to ellipsoid or terrain. (and soon MSL.) Height is just a special case of a straight down ray. Google Earth did have hitTest but I believe only with Terrain and ray.origin is always the camera.origin.

For any one needing to understanding the difference Ellipsoid vs. Orthometric Elevations and the role of the Geoid in defining the difference between the two, the following video is a great resource in explaining it.

For any one migrating from Google Earth, the elevations provided in Earth or by the Google Maps Elevation API are Orthometric elevations, sea level is at an elevation of 0 meters

note the elevation example in cesium


go to any coastal area ( I’m in Vancouver, BC Canada ) , where the ocean meets the land, the cesium example shows about -19.96 meters as an elevation.

Enter the coordinates in the e EGM96 model link that Kevin mentioned in the post above:


you will see this value returned, explaining the discrepancy

Going over the the east coast of North America, say Miami there will be a similar result, but with the Geoid Height of -28.00 meters.

I will disagree with Kevin on the point of:

“providing terrain data relative to a reference ellipsoid is much more sensible than providing it relative to MSL”

As mentioned in the video, elevations in ellipsoid space will have water flowing uphill and standing bodies of water (lakes) which should define surface of constant elevation, will have variations in elevation along the shoreline.

That’s a really good video, thanks!

I think the guy in the video does a better job than I did of making my point about ellipsoid heights being more sensible. He suggests that heights be stored relative to the ellipsoid and just transformed to the geoid-du-jour when necessary. That sounds perfectly reasonable to me. I understand that geoid heights are useful in some applications. However, when terrain data is distributed relative to the geoid, it requires applications like Cesium to back out the MSL adjustment, and other applications that need a more accurate geoid to first back out the one the data provider applied, and then apply a better one. Not very sensible. :slight_smile:

“transformed to the geoid-du-jour when necessary”

I can agree with that.

I think the primary difference is in that the storage and distribution form of elevation data for a global perspective is a very different beast than the working data set that most people utilize in engineering and design.

Terrain and survey data is typically prepared in a fashion to be consumed and analysed as orthometric information, at a local scale (watershed or city) and is in the context that most can relate to (downhill is the way that water flow).

In the past, the subtleties of Geoids wasn’t needed as elevation was measured with line of sight, levels and from established benchmarks. But now with data collected on a local to continental scale with satellites, gps, lidar et all the complications over time with geoids and other data sets make spatial data the beast it is.

A tangent that comes to mind, the ground elevation in some area of Chile changed by as much as 3 meters after the 2010 M8.8 earthquake. http://en.wikipedia.org/wiki/2010_Chile_earthquake

Good illustration showing slight variations in gravity direction due uneven Earth densities.

However on average, does gravity direction actually diverge from pointing to the center of the Earth when away from the Poles and Equator? On average, does the gravity direction match the surface normal of the reference ellipsoid? (if reference sphere then surface normal would always be toward the center of the Earth)

Geoid seems to be what sea level would be if land wasn’t there. Of course if land wasn’t there, the local gravity be different! Also this depends on how much water the Oceans have, which can vary.

What would be ultimate is having a 3D density map of the Earth from which you can determine gravity vector from any 3D position (I believe reflection seismology only yields rough results.) But all we have is gravity’s vector at each point of the surface (and above I suppose.)

Perhaps in addition to the ‘what sea level would be if land wasn’t there’ model we could have ‘gravity’s magnitude and direction at each point of the surface’ model. With this model you can know what direction water will flow by comparing gravity vector to terrain normal.

What would be cool is simulating flowing a certain volume of water at a certain point and seeing what kind of lake shape would result (assuming of course it doesn’t flow off into some river and off to the Ocean.

The illustration example in the pdf is easier to follow as both Geoid and terrain are above the ellipsoid. Also the pdf file didn’t mention that both h and N were normal to the ellipse, while H is in the direction of local gravity. (although if you look carefully at the illustration it is drawn that way.) Since the the directions don’t necessarily match up H ~= h-N rather than H = h-N.