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!
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>
Open the index.html file in your browser, and you will see a full-screen map, like the one shown in the map below.
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.
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.
Useful links
API Reference | MapLibre GL JS Docs
npm: maplibre-gl
MapLibre - Open Maps SDKs
Customize map design to fit your project – MapTiler
Related guides
- Automatically created API key
- Check if MapLibre GL JS is supported
- Coordinates API
- Dataset upload - formats and limits
- Difference between 256x256, 512x512, and HiDPI/Retina rasterized tiles
- Exported Tiles Multiplier
- Generalization in maps
- How are the tile requests cached in web browser?
- How MapTiler map tiles are Generated and Delivered
- How to add Geocoding control to Maplibre GL JS map