Skip to content

Global Landcover Tiles for the web with MapLibre GL JS

Free

Starter

Standard

Professional

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 127.0.0.1, you can get started without any API keys or domain setup!

For mobile, backend, and non-local web development, you'll need either domain auth or an API key. If you don't already have a Stadia Maps account, sign up for a free to get started.

Domain-based authentication

Domain-based authentication is the easiest form of authentication for production web apps. No additional application code is required, and you don't need to worry about anyone scraping your API keys. We recommend this for most browser-based applications.

  1. Sign in to the client dashboard.
  2. Click "Manage Properties."
  3. Under "Authentication Configuration," click the button to add your domain.
API key authentication

Authenticating requests via API key

You can authenticate your requests by adding an API key to the query string or HTTP header.

The simplest is to add a query string parameter api_key=YOUR-API-KEY to your request URL. For example, to access the /tz/lookup API endpoint, your request URL might look like this.

Example URL with an API key placeholder
https://api.stadiamaps.com/tz/lookup/v1?lat=59.43696&lng=24.75357&api_key=YOUR-API-KEY

You can also use an Authorization HTTP header instead of a query string as shown below. Don't forget the Stadia-Auth prefix!

Example Authorization header with an API key placeholder
Authorization: Stadia-Auth YOUR-API-KEY

How to get an API key

Don't have an API key yet? Follow these easy steps!

  1. Sign in to the client dashboard. (If you don't have an account yet, sign up for free; no credit card required!)
  2. Click "Manage Properties."
  3. If you have more than one property (ex: for several websites or apps), make sure you have selected the correct property from the dropdown at the top of the page.
  4. Under "Authentication Configuration," you can generate, view or revoke your API key.

Video: How to generate your API key

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>
<html>
    <head>
        <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="//unpkg.com/maplibre-gl@4.0.2/dist/maplibre-gl.js"></script>
        <link href="//unpkg.com/maplibre-gl@4.0.2/dist/maplibre-gl.css" rel="stylesheet" />
        <style type="text/css">
            body {
              margin: 0;
              padding: 0;
            }

            #map {
              position: absolute;
              top: 0;
              bottom: 0;
              width: 100%;
            }
        </style>
    </head>
    <body>
        <div id="map"></div>
        <script type="text/javascript">
            var map = new maplibregl.Map({
                container: 'map',
                style: 'https://tiles.stadiamaps.com/styles/outdoors.json', // 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
            maplibregl.setRTLTextPlugin('https://unpkg.com/@mapbox/mapbox-gl-rtl-text@0.2.3/mapbox-gl-rtl-text.min.js');

            // 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": [
                            "https://tiles.stadiamaps.com/data/global_landcover_v1/{z}/{x}/{y}.pbf"
                        ],
                        "minZoom": 0,
                        "maxZoom": 6
                    });

                // Add the layers we would like to include, define their stops, colors, and other attributes
                // (2)
                // (3)
                map.addLayer(
                    {
                    "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"},
                            "#ced5ef"
                            ],
                            [
                            {"zoom": 0, "value": "grass"},
                            "#d8e8c8"
                            ],
                            [
                            {"zoom": 0, "value": "wood"},
                            "#679c4c"
                            ]
                        ],
                        // (6)
                        "default": "#00000000"
                        },
                        "fill-opacity": {
                        "stops": [
                            [0, 0.2],
                            [7, 0.1]
                        ]
                        },
                        "fill-antialias": true
                    },
                    "maxzoom": 7,
                    "layout": {"visibility": "visible"}
                    }
                );
            });
        </script>
    </body>
</html>
  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