How to highlight countries with Mapbox
21 Dec 2020I'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>
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>
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;
}
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>
We now have a fully working Mapbox map running in our browser!
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>
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();
});
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'
);
});
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:
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'
]);
This will highlight The Netherlands and Italy.
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>
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.