All roads vector map: part 3

This is the final entry in my three part series detailing the creation of a vector map from scratch. This post covers displaying the vector tiles created in part 1 with the styling of part 2, in a JavaScript web map, here using Mapbox GL JS.

If not already active, first start a localhost instance of tileserver-gl to serve the style from part 2, by running the below command in a terminal within the directory containing the server files – config.json; road.mbtiles; and the style file.

docker run --rm -it -v $PWD:/data -p 80:80 klokantech/tileserver-gl

Connect to tileserver at localhost, and make a note of the url for the style.json listed under GL Style e.g. http://localhost/styles/road/style.json. This is the endpoint of our styled tiles, and what is needed to display them in a web map.

For the web map, I am using Mapbox’s GL JavaScript library, probably the most fully featured and simple solution for displaying vector tiles. To start, take the simple map example and copy this to a text file named index.html like below.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Display a map</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<script src="https://api.mapbox.com/mapbox-gl-js/v1.11.0/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.11.0/mapbox-gl.css" rel="stylesheet" />
<style>
    body { margin: 0; padding: 0; }
    #map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
    // TO MAKE THE MAP APPEAR YOU MUST
    // ADD YOUR ACCESS TOKEN FROM
    // https://account.mapbox.com
    mapboxgl.accessToken = '<your access token here>';
    var map = new mapboxgl.Map({
        container: 'map', // container id
        style: 'mapbox://styles/mapbox/streets-v11', // stylesheet location
        center: [-74.5, 40], // starting position [lng, lat]
        zoom: 9 // starting zoom
    });
</script>

</body>
</html>

Then, simply edit the map object to refer to our own style url from tileserver-gl – the mapbox token can also be removed, this is not required when using non-Mapbox styles. So, replace the lines within the <script> tags with something like:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Display a map</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<script src="https://api.mapbox.com/mapbox-gl-js/v1.11.0/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.11.0/mapbox-gl.css" rel="stylesheet" />
<style>
    body { margin: 0; padding: 0; }
    #map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
    var map = new mapboxgl.Map({
        container: 'map',
        style: 'http://localhost/styles/road/style.json',
        center: [-80.0, 50],
        zoom: 4,
        minZoom: 4,
        maxZoom: 16
    });

    // Add zoom and rotation controls to the map.
    map.addControl(new mapboxgl.NavigationControl());
</script>

</body>
</html>

This also updates the default map view with the zoom and center parameters to display Ontario when connecting to the map, and limits in min and max zoom levels to match the zoom levels present in the tiles. We can also add a control with map.addControl, in this case zoom and rotation controls.

Opening index.html in a browser should give you something like below – a fully functioning web map, running off of tileserver-gl.