What are Open Source (and/or modestly-priced) paths to offline quantized mesh 3D terrain self-hosting?

Hello. I am a (suitably proficient) javascript developer but with zero background in Cesium or mapping. I’ve been lurking for awhile on this excellent list trying hard not to bother it with very elementary questions, but I have this one now I’m going to try. Thanks in advance to anyone willing to indulge me.

I’m on a small, limited-budget team working on a self-funded, proof-of-concept-stage product using Cesium. The product needs 3D terrain data (often in relatively small regions of the globe) and we’ve been prototyping very happily online with Cesium’s online World Terran.

Ultimately the product will need to be deployed with zero internet access and we are hoping to self-host 3D quantized mesh terrain. (We are aware of AGI’s presumably excellent commercial solution and maybe will one day use it, but at this speculative stage it is way out of our budget.) To my novice way of thinking, there are three pieces to this step: 1) The actual terrain data 2) Conversion of data to Cesium-compatible quantized mesh 3) Server for converted terrain data

Is anyone on the list doing this (self-hosting 3D terrain data that they did not originate) in a way that they like? Which of these three components have Open Source solutions? (Am I even correct in thinking of it as those three pieces?)

Any advice (links) would be gratefully appreciated. Thanks for the excellent-so-far community!

This is certainly possible to achieve, we do something similar in one of our applications in terms of serving up our own local terrain sets derived from drone surveys.

There are essentially two components to what you are trying to achieve:

  1. Processing your source data into quantized mesh terrain tiles

  2. Serving up the tileset from a local server

To accomplish the first step, and assuming you have the source data, you can use a Docker instance of cesium-terrain-builder that has been modified to support creation of the quantized mesh format. Details for the docker image can be found here: https://hub.docker.com/r/tumgis/ctb-quantized-mesh. You will need to have your source data as a Digital Elevation Model (DEM) but this would be relatively straightforward to create depending on the source format of your height data (or you might already have it as a GeoTIFF DEM) - there is a project called GDAL (https://gdal.org/) with a whole bunch of tools to help with this part.

Once you have the tile set you need to serve them up to your Cesium application - to be frank this is also pretty straight-forward and can be achieved in a number of different ways:

  1. Create your own file server code using something like Node.js or other server-side language (ASP.Net Core for example which is what we use)

  2. Just setup a local web server to serve the tiles as static content (for example Nginx or another Docker container like https://hub.docker.com/r/danjellz/http-server)

To be quite frank the serving process is straightforward - the CesiumTerrainProvider requests a layer.json file which holds details of the terrain tile set (ctb-quantized-mesh will generate this for you) when the provider is added, then as it renders each scene it will request the terrain tiles it needs using an xyz format, again the file structure that ctb-quantized-mesh creates is in the correct format so simply exposing that directory structure through a local web server will give you what you need locally.

Hope that helps.

I’ve done exactly this task myself at my day job. I really wanted to get around to writing up a long blog post about it all, but never had time.

I wrote a small Python server that took standard TMS format queries (something like /z/x/y.tile), read the corresponding tile out of an MBTiles container database file, and returned it. I also did some work to handle multiple MBTiles files at different zoom levels around the world (such as a worldwide tileset up to zoom 8, and specific areas at zooms 9-13).

For terrain generation, I used the linked cesium-terrain-builder utility, and actually filed a PR to enabled outputting the contents to MBTiles format:

For our own use, I generated terrain data using the free ALOS30 worldwide terrain dataset:


Had to do some preprocessing to get it ready for use by CTB, but ultimately got some very usable data.

I sadly don’t have time to put that blog post together, but if you’ve got questions, please ask and I’ll be happy to try to provide more details.

Hi Colin I followed your steps and generated tileset using ctb and added the terrin folder to the htdocs folder of my xamp server, fired up sandcastle and used code
" var viewer = new Cesium.Viewer(‘cesiumContainer’, {
baseLayerPicker : false,
terrainProvider : new Cesium.CesiumTerrainProvider({
url : ‘http://localhost/terrain
}); "

But I am getting following error -
An error occurred in “CesiumTerrainProvider”: Failed to obtain terrain tile X: 0 Y: 0 Level: 0. Error message: “RangeError: Invalid typed array length: 8894653434”

Please help