DEV Community

Cover image for How to highlight countries with Mapbox
ngnijland
ngnijland

Posted on • Updated on • Originally published at nieknijland.nl

How to highlight countries with Mapbox

I'm working on a trips section on my personal website. To visualize the countries I have visited, I wanted to show a map and highlight every country I visited. Since this was not a straightforward task and it took me longer than expected I thought I would share how this works.

Just here for the code? Checkout this repository.

Setup Mapbox

First, we want a running instance of Mapbox. I choose to use Mapbox GL JS as I wanted a smooth experience for future animations and transitions on the map of my personal website. Mapbox GL JS is a JavaScript library that uses WebGL to promise this smooth experience.

Include sources

To render a Mapbox map you need to include the Mapbox GL JS library and styles in your code. You can either add it using Mapbox's CDN with a script and link tag or use a module bundler like npm or yarn.

To be able to setup up a bare minimum as an example I chose to use Mapbox's CDN. It is done by adding the following lines of code to the <head> of your HTML file:

<head>
  <!-- ... -->
  <script src='https://api.mapbox.com/mapbox-gl-js/v2.0.0/mapbox-gl.js'></script>
  <link href='https://api.mapbox.com/mapbox-gl-js/v2.0.0/mapbox-gl.css' rel='stylesheet' />
</head>
Enter fullscreen mode Exit fullscreen mode

If you want to use a module bundler checkout their documentation.

Access token

To use a Mapbox map you need an access token. To get one, you need to create a Mapbox account (https://account.mapbox.com/auth/signup/) and retrieve an access token from your account page (https://account.mapbox.com/). Once you have your access token it is time to render a map on your page!

Render map

Mapbox needs an element to render its map in. Let's add one:

<div id="map"></div>
Enter fullscreen mode Exit fullscreen mode

To make it fill the entire page add the following CSS to the <head> of your HTML file:

html,
body,
#map {
  height: 100%;
  margin: 0;
}
Enter fullscreen mode Exit fullscreen mode

Now hand Mapbox your access token and initialize a new Map instance by adding the following script tag to the <body> of your HTML file:

<script>
  mapboxgl.accessToken = '<YOUR ACCESS TOKEN HERE>';

  var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/streets-v11',
    center: [5, 46],
    zoom: 3
  });
</script>
Enter fullscreen mode Exit fullscreen mode

We now have a fully working Mapbox map running in our browser!

A browser window showing a full-size Mapbox map.

The complete code to achieve this:

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1'>
  <title>Highlight countries in mapbox</title>
  <script src='https://api.mapbox.com/mapbox-gl-js/v2.0.0/mapbox-gl.js'></script>
  <link href='https://api.mapbox.com/mapbox-gl-js/v2.0.0/mapbox-gl.css' rel='stylesheet' />
  <style>
    html,
    body,
    #map {
      height: 100%;
      margin: 0;
    }
  </style>
</head>
<body>
  <div id='map'></div>

  <script>
    mapboxgl.accessToken = '<YOUR ACCESS TOKEN HERE>';

    var map = new mapboxgl.Map({
      container: 'map',
      style: 'mapbox://styles/mapbox/streets-v11',
      center: [5, 46],
      zoom: 3
    });
  </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Highlight countries

Now we have a map, the next step is to highlight individual countries.

Tilesets

Mapbox works with layers where you can display tilesets. These tilesets consist of vectors that render on a specific place on the map. You can create your own tileset or use existing ones.

We will use this countries tileset supplied by Mapbox.

Add a layer

To render this tileset on top of our map we have to add a layer to our map. We can do this on the callback of the Map's load event.

map.on('load', function() {
  map.addLayer();
});
Enter fullscreen mode Exit fullscreen mode

Now we add a config which will add the countries tileset to this layer:

map.on('load', function() {
  map.addLayer(
    {
      id: 'country-boundaries',
      source: {
        type: 'vector',
        url: 'mapbox://mapbox.country-boundaries-v1',
      },
      'source-layer': 'country_boundaries',
      type: 'fill',
      paint: {
        'fill-color': '#d2361e',
        'fill-opacity': 0.4,
      },
    },
    'country-label'
  );
});
Enter fullscreen mode Exit fullscreen mode

After the tileset config, we add 'country-label' to make sure the country names render on top of the country tileset.

In the paint section of the config, you can choose the color and opacity in which countries should highlight. In this case #d2361e with an opacity of 0.4.

This results in all countries being highlighted:

A browser window showing a full-size Mapbox map highlighting all countries in red with a 60% opacity.

Filter

Mapbox's country tileset identify countries with ISO 3166-1 country codes. You can add a filter to the country-boundaries layer and use these country codes to highlight specific countries. This should also be done in the Map's load event:

map.setFilter('country-boundaries', [
  "in",
  "iso_3166_1_alpha_3",
  'NLD',
  'ITA'
]);
Enter fullscreen mode Exit fullscreen mode

This will highlight The Netherlands and Italy.

Alt Text

Now we achieved what we wanted! Check out all the code needed here:

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1'>
  <title>Highlight countries in mapbox</title>
  <script src='https://api.mapbox.com/mapbox-gl-js/v2.0.0/mapbox-gl.js'></script>
  <link href='https://api.mapbox.com/mapbox-gl-js/v2.0.0/mapbox-gl.css' rel='stylesheet' />
  <style>
    html,
    body,
    #map {
      height: 100%;
      margin: 0;
    }
  </style>
</head>
<body>
  <div id='map'></div>

  <script>
    mapboxgl.accessToken = '<YOUR ACCESS TOKEN HERE>';

    var map = new mapboxgl.Map({
      container: 'map',
      style: 'mapbox://styles/mapbox/streets-v11',
      center: [5, 46],
      zoom: 3
    });

    map.on('load', function() {
      map.addLayer(
        {
          id: 'country-boundaries',
          source: {
            type: 'vector',
            url: 'mapbox://mapbox.country-boundaries-v1',
          },
          'source-layer': 'country_boundaries',
          type: 'fill',
          paint: {
            'fill-color': '#d2361e',
            'fill-opacity': 0.4,
          },
        },
        'country-label'
      );

      map.setFilter('country-boundaries', [
        "in",
        "iso_3166_1_alpha_3",
        'NLD',
        'ITA'
      ]);
    });
  </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Conclusion

Thanks for reading this article! Check out all the code needed in this repository. If you're interested in how I applied it on my website you can find it at https://nieknijland.nl/trips.

Do you like this article? Maybe you'll like these as well:

Let's get in contact! Comment below on this article or follow me on Twitter @ngnijland.

Oldest comments (0)