3D Terrains with Mapbox GL JS v.2 for Terradactile

aerial view of city buildings during night time

In October, we released Terradactile (blog post here), an app hatched during hackathon designed to find, process, and download AWS Terrain tiles. The original application allowed the user to select an area of interest, process the contained elevation data into cloud optimized derived products including a seamless elevation and derived hillshade surface, and view/download the outputs. Since then, Terradactile has continued to evolve.

The original release was built upon Mapbox GL JS v1, and featured the familiar top-down 2D map view. When Mapbox GL JS v2 was released in December, we were quickly able to modify Terradactile to make use of the new features. The major new features introduced by the new version of the API include: 3D terrain, increased camera movement and control, and sky/sun customization. Additionally, map and tile loading performance have both been greatly improved, with no modification required to previous version code.

Aside from updating the Mapbox library import, we made three new changes to Terradactile:

  1. 3D terrain: once the new version of the Mapbox GL JS library is imported into the application, terrain is very easy to incorporate. First, add a new raster-dem data source to the map object, similar to how you would add any other source. Then, invoke the new map.setTerrain method to attach the terrain source to the map. We also added a slider that allows the user to control the amount of terrain exaggeration displayed in the map (the exaggeration parameter is modified in the setTerrain method).

2. Refine the map design: the original design of Terradactile was simply a flat map, inside which the user’s view was confined. The new camera movement capabilities allow the user to tilt the camera farther skyward, meaning they may now look beyond the horizon. This is an important consideration if your application allows the camera to be positioned at a high altitude – it may be a jarring experience if the user sees multiple copies of the world stretching into the infinite distance, which is the default map behaviour. As in previous versions of Mapbox GL JS, setting renderWorldCopies to false in the map object disables multiple copies of the world map. We also added an extruded wall around the map (constructed from a geojson geometry), just to define the boundary of the app.

terradactile walls

3. Add a sun and sky: finally, we added a sky object, configured to show a sun and atmospheric halo effect. Sky is easy to add to your map; simply use map.addLayer() with sky type, and configure the other desired parameters to control atmosphere, gradient, and sun characteristics. In Terradactile’s case, the sky is a very simple black, like space, while the sun and atmosphere are configured to fit into our app’s blue colour palette. It looks artificial, but let’s face it, so does the rest of the app (i.e. we don’t truly believe the Earth is accurately represented as a flat rectangle).

terradactile sun

Overall, we found the transition between Mapbox GL JS v1 and v2 to be refreshingly simple. While not explicitly requiring any code changes whatsoever, most apps will benefit from performance enhancements, and the additional functionalities, especially those concerning 3D, are well worth us considering the newest version of Mapbox GL JS for any of our Mapbox-focused apps, going forward.

Do you have an idea for a Mapbox app? We’re happy to discuss it with you, and as a certified Mapbox service provider, we are well positioned to make it happen. Let’s talk.