How to build a 3D map with MapLibre v2 GL JS

In this tutorial, you’ll learn how to build a 3D map using MapLibre GL JS v2. We will show you how to make a simple map application allowing you to zoom and pan MapTiler maps in 3D using MapLibre. By the end, you will have a map that looks like this in a fully interactive web interface. 
Hint: You can do the same, just easier with MapTiler SDK!

map-3d-winter.png

Getting started

Minimal requirements for completing this tutorial.

  • Some experience with JavaScript, CSS, and HTML. You don’t need a lot of experience using JavaScript, CSS, and HTML for this tutorial, but you should be familiar with basic concepts and workflow.
  • MapTiler API key. Your MapTiler account access key is on your MapTiler Cloud account page or Get API key for FREE.
  • MapLibre GL JS. Javascript library for building web maps. In this tutorial, we will see how to install it.

Simple Map

In this step, we will learn how to create a Simple Map with MapLibre GL JS.

Create a file called index.html and write the following lines:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>3D Map</title>
</head>

<body>

</body>

</html>

Add a <div> tag into your page. This div will be the container to display the map. Write the following line into the body of the page.

<body>  
  <div id="map"></div>  
</body>

Initialize the map

Include the MapLibre JavaScript and CSS files in the <head> of your HTML file. Add these lines in the <head>

<title>3D Map</title>  
<script src='https://cdn.maptiler.com/maplibre-gl-js/v2.2.0-pre.2/maplibre-gl.js'></script>  
<link href='https://cdn.maptiler.com/maplibre-gl-js/v2.2.0-pre.2/maplibre-gl.css' rel='stylesheet' />  
</head>

To create a fullscreen map, add the following style in the <head> of your page.

<link href='https://cdn.maptiler.com/maplibre-gl-js/v2.2.0-pre.2/maplibre-gl.css' rel='stylesheet' />  
<style>  
body { margin: 0; padding: 0; }  
#map { position: absolute; top: 0; bottom: 0; width: 100%; }  
</style>  
</head>

Inside the <body>, write the following code to visualize and add the map to our HTML page.

<body>
  <div id="map"></div>
  <script type="module">
    const API_KEY = 'YOUR_MAPTILER_API_KEY';
    const map = new maplibregl.Map({
      container: 'map',
      style: `https://api.maptiler.com/maps/winter-v2/style.json?key=${API_KEY}`,
      center: [11.40416, 47.26475],
      zoom: 12,
    });  
  </script>
</body>
Here you will need to replace YOUR_MAPTILER_API_KEY with your MapTiler API key.

Open the index.html file in your browser, and you will see a full-screen map, like the one shown in the map below.

full-screen-map.png

Add 3D terrain to a map

Next, we will see how to create a 3D terrain map. To make our 3D map, we will use the elevation data from MapTiler Terrain RGB

To create the 3D map, we must add a new layer. To do this, we must wait until the map resources have been loaded, including the style. Only after this can we add our layers to the map. The load event is fired immediately after all necessary resources have been downloaded and the first visually complete rendering of the map has occurred. Add these lines after the map initialization.

zoom: 12,  
});  
  
map.on('load', () => {  
// Add new sources and layers  
});

When adding a new layer, the first thing we have to do is define the layer’s data source. Inside the load event callback function, write the followings lines.

map.on('load', () => {  
  // Add new sources and layers  
  map.addSource("terrain", {  
   "type": "raster-dem",  
   "url": `https://api.maptiler.com/tiles/terrain-rgb-v2/tiles.json?key=${API_KEY}`  
 });  
});

The valid types for the encoding option are: “mapbox”, “mtk” and “terrarium”.

To add the terrain layer, we use the setTerrain method that receives the id of the data source as a parameter. Add the following line just after where we have added the data source.

"maxzoom": 14  
});  
map.setTerrain({  
source: "terrain"  
});  
});

Finally, to see the effect of the 3D of the map, we will give some tilt to the map’s initial view. Add the following line to the maps options.

const map = new maplibregl.Map({  
container: 'map',  
style: `https://api.maptiler.com/maps/winter-v2/style.json?key=${API_KEY}`,  
center: [11.40416, 47.26475],  
zoom: 12,  
pitch: 70,  
maxPitch: 85  
});

Your script should look like this.

const API_KEY='YOUR_MAPTILER_API_KEY';  
const map = new maplibregl.Map({  
  container: 'map',  
  style: `https://api.maptiler.com/maps/winter-v2/style.json?key=${API_KEY}`,  
  center: [11.40416, 47.26475],  
  zoom: 12,  
  pitch: 70,  
  maxPitch: 85  
});  
  
map.on('load', () => {  
  // Add new sources and layers  
  map.addSource("terrain", {  
    "type": "raster-dem",  
    "url": `https://api.maptiler.com/tiles/terrain-rgb-v2/tiles.json?key=${API_KEY}`  
  });  
  map.setTerrain({  
    source: "terrain"  
  });  
});

Refresh the page in your browser and see a 3D map like this one.

3d-map.png

You can use any of your maps and add the Terrain RGB to see them in 3D.
MapTiler SDK (which extends MapLibre) makes this a one-line problem!

Conclusion

Congratulations! You have finished your fullscreen 3D map app using MapLibre GL JS. You can explore more about MapLibre GL JS for your map in the MapLibre API reference.

API Reference | MapLibre GL JS Docs
npm: maplibre-gl
MapLibre - Open Maps SDKs
Customize map design to fit your project – MapTiler