Sorry, you need to enable JavaScript to visit this website.

Add a layer between map layers

Overview of the tutorial

This tutorial shows how to insert a layer behind traffic flow information.

To start using the latest version of the Maps SDK for Web, you need the following:

  • The Maps library can be used in three ways:
    • Downloaded from NPM: https://www.npmjs.com/package/@tomtom-international/web-sdk-maps.
    • With CDN: https://api.tomtom.com/maps-sdk-for-web/cdn/5.x/<version>/maps/maps-web.min.js - NOTE: include latest version in the URL.
    • Downloaded from here: Downloads.

        In this tutorial, we are using CDN as an example.

  • API Key
     

    Get your API Key now

    To create a new API Key you need to first register on the portal. Once you are logged in there is only one step remaining:

    Go to your Dashboard:

    dashboard

    You can now click on your app - My first app and copy your API Key:

    copy your API key

We recommend that you have npm and Node.js already installed on your computer to quickly spin up a HTTP server to display the page we will create.

 

Create a HTML file

Now let us create a basic HTML file to display a map with traffic flow information. For this example I created a file named index.html.

Next, copy the following script to your index.html file.


<!DOCTYPE html>
<html class='use-all-space'>
<head>
    <meta http-equiv='X-UA-Compatible' content='IE=Edge' />
    <meta charset='UTF-8'>
    <title>Demo app</title>
    <meta name='viewport'
          content='width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no'/>
    <link rel='stylesheet' type='text/css' href='https://api.tomtom.com/maps-sdk-for-web/cdn/5.x/5.38.0/maps/maps.css'/>
    <script src="https://api.tomtom.com/maps-sdk-for-web/cdn/5.x/5.38.0/maps/maps-web.min.js"></script>
    <style>
        #map {
            width: 800px;
            height: 600px;
        }
    </style>
</head>
<body>
    <div id='map' class='map'></div>
    <script>
        var map = tt.map({
            key: '<YOUR-MAP-API-KEY>',
            container: 'map',
            style: 'tomtom://vector/1/basic-main',
            center: [-0.12634, 51.50276],
            zoom: 10
        });

        var config = {
            key: '<YOUR-TRAFFIC-FLOW-API-KEY>',
            style: 'tomtom://vector/1/relative',
            refresh: 30000
        };

        map.on('load', function() {
            map.addTier(new tt.TrafficFlowTilesTier(config));
        });
    </script>
</body>
</html>

Let's go over the important lines

First, we import all the necessary assets, in this case the JavaScript SDK and its styles.


    <!-- Include SDK's stylesheet -->
    <link rel='stylesheet' type='text/css' href='https://api.tomtom.com/maps-sdk-for-web/cdn/5.x/5.38.0/maps/maps.css'/>
    <!-- Include JavaScript SDK -->
    <script src='https://api.tomtom.com/maps-sdk-for-web/cdn/5.x/5.38.0/maps/maps-web.min.js'></script>

Then, we can create our new map.


//...
//Initializes TomTom map with an id set to 'map' and given style, zoom and center position
var map = tt.map({
    key: '<YOUR-MAP-API-KEY>',
    container: 'map',
    style: 'tomtom://vector/1/basic-main',
    center: [-0.12634, 51.50276],
    zoom: 10
});
//...

Next, we enable traffic flow information.


//...
//Traffic flow configuration
var config = {
    key: '<YOUR-TRAFFIC-FLOW-API-KEY>',
    style: 'tomtom://vector/1/relative',
    refresh: 30000
};

//We need to wait till the map is initialized
map.on('load', function() {
    //Now we enable traffic flow
    map.addTier(new tt.TrafficFlowTilesTier(config));
});
//...

Remember to replace the placeholders with your real data.

<YOUR-MAP-API-KEY> Your TomTom Map API Key generated earlier.
<YOUR-TRAFFIC-FLOW-API-KEY> Your TomTom Traffic Flow API Key generated earlier.

Run a HTTP server

Navigate to the directory containing our example using a terminal.

For example:

  ~$  cd sdk-example/
  ~sdk-example$

Install a light-weight HTTP server (you might need to run this command with admin/root privileges):

  npm install --global http-server

Then just simply run the following command:

  http-server

Note that npm comes bundled with Node.js, so please make sure you have it installed on your machine.

So now it is time to see the results!

Open a browser and type this url in the address bar: http://localhost:8080/index.html. You should be able to see a map with traffic flow!

 

vector-map

Add a custom GeoJson layer

To add a custom layer to a style we use 'map.addLayer' method. For example:


//...
map.on('load', function() {
//...
    map.addLayer({
        'id': 'overlay',
        'type': 'fill',
        'source': {
            'type': 'geojson',
            'data': {
                'type': 'Feature',
                'geometry': {
                    'type': 'Polygon',
                    'coordinates': [[[-0.2046175878910219, 51.52327158962092],
                        [-0.05355557617221507, 51.53523241868879],
                        [-0.13045987304786877, 51.46299250930767]]]
                }
            }
        },
        'layout': {},
        'paint': {
            'fill-color': '#db356c',
            'fill-opacity': 0.5,
            'fill-outline-color': 'black'
        }
    });
});
//...

If you do it like this you will notice that a triangle is drawn on top of the map.

 

triangle on top

 

However, we achieved only a partial victory since we want to have this layer to be drawn under traffic flow information. How to do it? Thankfully, the "map.addLayer" method takes another parameter called "beforeLayerId" which should point to a layer's id under which we want to draw our custom layer. Only how can we find information about the layer and its id under which we want to put our custom layer? Let's start from inspecting the map's current style. You do it by invoking:


map.getStyle();

This method provides your style as a JSON object. You may notice it constains multiple layers. Those layers define what will be rendered and how it will be rendered on your map. Their order matters - rendering starts from the first layer on the list and ends on the last one which means that layers at the begining might be covered by those at the end. That's why its important to find a proper position for our layer. You could do it by browsing layers provided by the object returned from the "map.getStyle" method. The problem is there are a lot of them and it might be hard to find a proper one. Fortunately, there is an easier way but it requires to know how our SDK combines styles defined for different types of map information provided by TomTom. At the moment of writing TomTom hosts predefined styles for:

If you create a map without additional traffic data our SDK uses only a style created for map data. Which one exactly is based on information passed in the "style" configuration option. When you add traffic data information by invoking the "map.addTier" method an additional style is fetched and combined together with the one defined for map data. For example, in our case we add traffic flow information:


//...
map.addTier(new tt.TrafficFlowTilesTier({
    key: '<YOUR-TRAFFIC-FLOW-API-KEY>',
    style: 'tomtom://vector/1/relative',
    refresh: 30000
}));
//...

"style" property points to "tomtom://vector/1/relative" which is mapped to a given hosted style url:

https://api.tomtom.com/traffic/map/4/style/<STYLE-VERSION>/flow_relative.json?key=<YOUR-TRAFFIC-FLOW-API-KEY>

You can find STYLE-VERSION by checking the SDK documentation. It should be located in the place shown at the picture below.

 

vector-map

 

At the moment of writing it is: 20.0.2-5.

In the style returned by this url you need to find the first layer and its id is the id we have been looking for.

 

vector-map

 

Now we can render our layer on the map in the proper place.


//...
map.on('load', function() {
//...
    map.addLayer({
            'id': 'overlay',
            'type': 'fill',
            'source': {
                'type': 'geojson',
                'data': {
                    'type': 'Feature',
                    'geometry': {
                        'type': 'Polygon',
                        'coordinates': [[[-0.2046175878910219, 51.52327158962092],
                            [-0.05355557617221507, 51.53523241868879],
                            [-0.13045987304786877, 51.46299250930767]]]
                    }
                }
            },
            'layout': {},
            'paint': {
                'fill-color': '#db356c',
                'fill-opacity': 0.5,
                'fill-outline-color': 'black'
            }
        },
        'Vector Traffic Outline One Side Parking road'
    );
});
//...

Here is the result:

 

vector-map

 

And that is the full source code:


<!DOCTYPE html>
<html class='use-all-space'>
<head>
    <meta http-equiv='X-UA-Compatible' content='IE=Edge' />
    <meta charset='UTF-8'>
    <title>Demo app</title>
    <meta name='viewport'
          content='width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no'/>
    <link rel='stylesheet' type='text/css' href='https://api.tomtom.com/maps-sdk-for-web/cdn/5.x/5.38.0/maps/maps.css'/>
    <script src="https://api.tomtom.com/maps-sdk-for-web/cdn/5.x/5.38.0/maps/maps-web.min.js"></script>
    <style>
        #map {
            width: 800px;
            height: 600px;
        }
    </style>
</head>
<body>
<div id='map' class='map'></div>
<script>
    var map = tt.map({
        key: '<YOUR-MAP-API-KEY>',
        container: 'map',
        style: 'tomtom://vector/1/basic-main',
        center: [-0.12634, 51.50276],
        zoom: 10
    });

    var config = {
        key: '<YOUR-TRAFFIC-FLOW-API-KEY>',
        style: 'tomtom://vector/1/relative',
        refresh: 30000
    };
    map.on('load', function() {
        map.addTier(new tt.TrafficFlowTilesTier(config)).then(function() {
            map.addLayer({
                    'id': 'overlay',
                    'type': 'fill',
                    'source': {
                        'type': 'geojson',
                        'data': {
                            'type': 'Feature',
                            'geometry': {
                                'type': 'Polygon',
                                'coordinates': [[[-0.2046175878910219, 51.52327158962092],
                                    [-0.05355557617221507, 51.53523241868879],
                                    [-0.13045987304786877, 51.46299250930767]]]
                            }
                        }
                    },
                    'layout': {},
                    'paint': {
                        'fill-color': '#db356c',
                        'fill-opacity': 0.5,
                        'fill-outline-color': 'black'
                    }
                },
                'Vector Traffic Outline One Side Parking road');
        });
    });
</script>
</body>
</html>

You are here