Skip to content

Global Landcover Tiles for the web with MapLibre GL JS





Global Landcover Tiles are based on the ESA's excellent WorldCover project and help you add color to the lower zoom levels (focused on zooms 0-6) utilizing landcover derived from Sentinel satellite imagery. The layer is intended to smoothly transition to our landcover layer in our standard vector tiles.

For this tutorial, we'll be using MapLibre GL JS: a robust, free, and open-source library with 3D rendering, dynamic styling, and many other features. Stadia Maps is a founding member of the MapLibre project, which facilitates the ongoing development of MapLibre GL JS and other rendering technologies.

In this tutorial, you'll learn how to extend an existing map's richness by adding the Global Landcover layers.

Drawing a map

We'll dive in, assuming you know how to setup a basic MapLibre GL JS map with vector tiles. If you are new to MapLibre GL JS or need a refresher, check out our Vector Maps with MapLibre GL JS tutorial.

For local development on a web server at localhost or, you can get started without any special setup! For mobile, server, and non-local web development, sign up for a free account to configure domain auth or an API key. Our authentication guide has all the gritty details.

To make experimenting even easier, we've packaged the example code as a JSFiddle playground. Click the "Try it in JSFiddle" button to start experimenting right from your web browser.

Try it in JSFiddle
<!DOCTYPE html>
        <meta charset="utf-8" />
        <title>Vector Map Demo</title>
        <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
        <script type="text/javascript" src="//"></script>
        <link href="//" rel="stylesheet" />
        <style type="text/css">
            body {
              margin: 0;
              padding: 0;

            #map {
              position: absolute;
              top: 0;
              bottom: 0;
              width: 100%;
        <div id="map"></div>
        <script type="text/javascript">
            var map = new maplibregl.Map({
                container: 'map',
                style: '', // Style URL; see our documentation for more options
                center: [133, -25],  // Initial focus coordinate
                zoom: 0

            // MapLibre GL JS does not handle RTL text by default,
            // so we recommend adding this dependency to fully support RTL rendering if your style includes RTL text

            // Add zoom and rotation controls to the map
            map.addControl(new maplibregl.NavigationControl());

            // Include our landcover source
            // (1)
            map.on('load', function () {
                map.addSource('landcover', {
                        "type": "vector",
                        "tiles": [
                        "minZoom": 0,
                        "maxZoom": 6

                // Add the layers we would like to include, define their stops, colors, and other attributes
                // (2)
                // (3)
                    "id": "global-landcover",
                    "type": "fill",
                    "source": "landcover",
                    "source-layer": "global_landcover",
                    // (4)
                    "paint": {
                        "fill-color": {
                        "property": "class",
                        "type": "categorical",
                        // (5)
                        "stops": [
                            {"zoom": 0, "value": "ice"},
                            {"zoom": 0, "value": "grass"},
                            {"zoom": 0, "value": "wood"},
                        // (6)
                        "default": "#00000000"
                        "fill-opacity": {
                        "stops": [
                            [0, 0.2],
                            [7, 0.1]
                        "fill-antialias": true
                    "maxzoom": 7,
                    "layout": {"visibility": "visible"}
  1. When we load the map, we'll add a function to initiate the map.addSource method, define the source's name, type, tiles URL, along with the minZoom and maxZoom we want to have this dataset available:
  2. You can find all of the available sources and source-layers on the Global Landcover Tiles docs page.
  3. With the source added, we can specify which layers from the tileset we want to include by using the map.addLayer method and defining the id, type, source, and source-layer.
  4. We'll add the paint section and define the fill-color's property and type:
  5. Now we can add the specific layers in the stops array, including their starting zoom level, the layer value, along with its color:
  6. After adding the specific classes from the tileset you would like to include, define the default color for layers that not included in the previously defined stops, the fill-opacity for each zoom level stop, the maxZoom for these layers, and the layout:

Next Steps

This tutorial shows you some of the power behind incorporating additional tilesets, such as Global Landcover, with MapLibre GL JS. Now you can incoproate additional layers or entirely new tilesets.

You can get inspiration from what others have built at the MapLibre GL JS Examples page. They have in-depth examples covering everything from GeoJSON lines to interactive time sliders. And don't forget to check out the plugins and the rest of the MapLibre GL JS documentation either.

Once you're ready to move beyond localhost testing, sign up for a free Stadia Maps account, and we'll walk through the next steps.

Get Started With a Free Account