Building routes | MapGL | 2GIS Documentation
MapGL JS API

Directions

Directions functionality allows you to find an optimal route between multiple points (up to ten) and draw it on the map.

This plugin uses Directions API. To start using the plugin, get an API key for Directions API: see the instruction on obtaining API keys.

Next, you need to include the Directions plugin in your project. To do this, add the following line after the main MapGL script:

<script src="https://unpkg.com/@2gis/mapgl-directions@^2/dist/directions.js"></script>

Or you can install the needed package using npm:

npm install @2gis/mapgl-directions

This plugin calls Directions API under the hood to find a route. If you want, you can use your Directions API key to call the API directly instead of (or in addition to) using the plugin.

To draw routes on the map, first you need to initialize the Directions object:

const directions = new mapgl.Directions(map, {
    directionsApiKey: 'Your Directions API key',
});

Or, if you are using npm:

// Import either as an ES module...
import { Directions } from '@2gis/mapgl-directions';
// ...or as a CommonJS module
const { Directions } = require('@2gis/mapgl-directions');

const directions = new Directions(map, {
    directionsApiKey: 'Your Directions API key',
});

Then you can call the carRoute() method to display a car route or the pedestrianRoute() method to display a pedestrian route. Both methods take an array of geographical coordinates as the points parameter.

directions.carRoute({
    points: [
        [55.27887, 25.21001],
        [55.30771, 25.20314],
    ],
});
directions.pedestrianRoute({
    points: [
        [55.27887, 25.21001],
        [55.30771, 25.20314],
    ],
});

To clear the route, call the clear() method:

directions.clear();

Try clicking on any two points on the map to display a car route between them.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Urbi Map API</title>
        <meta name="description" content="MapGL API directions example" />
        <style>
            html,
            body,
            #container {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
            }
            #reset {
                padding: 4px 10px;
                background: #00a81f;
                border-radius: 4px;
                box-shadow: 0 1px 3px 0 rgba(38, 38, 38, 0.5);
                border: none;
                color: #fff;
                font-size: 12px;
                cursor: pointer;
            }
        </style>
    </head>
    <body>
        <div id="container"></div>
        <script src="https://mapgl.2gis.com/api/js/v1"></script>
        <script src="https://unpkg.com/@2gis/mapgl-directions@^2/dist/directions.js"></script>
        <script>
            const map = new mapgl.Map('container', {
                center: [55.31878, 25.23584],
                zoom: 13,
                key: 'Your API access key',
            });

            const directions = new mapgl.Directions(map, {
                // This key can be used for demo purpose only!
                // You can get your own key on https://urbi.ae/urbi-navigation#contact
                directionsApiKey: 'Your directions API access key',
            });
            const markers = [];

            let firstPoint;
            let secondPoint;
            // A current selecting point
            let selecting = 'a';

            const controlsHtml = `<button id="reset">Reset points</button> `;
            new mapgl.Control(map, controlsHtml, {
                position: 'topLeft',
            });
            const resetButton = document.getElementById('reset');

            resetButton.addEventListener('click', function() {
                selecting = 'a';
                firstPoint = undefined;
                secondPoint = undefined;
                directions.clear();
            });

            map.on('click', (e) => {
                const coords = e.lngLat;

                if (selecting != 'end') {
                    // Just to visualize selected points, before the route is done
                    markers.push(
                        new mapgl.Marker(map, {
                            coordinates: coords,
                            icon: 'https://docs.2gis.com/img/dotMarker.svg',
                        }),
                    );
                }

                if (selecting === 'a') {
                    firstPoint = coords;
                    selecting = 'b';
                } else if (selecting === 'b') {
                    secondPoint = coords;
                    selecting = 'end';
                }

                // If all points are selected — we can draw the route
                if (firstPoint && secondPoint) {
                    directions.carRoute({
                        points: [firstPoint, secondPoint],
                    });
                    markers.forEach((m) => {
                        m.destroy();
                    });
                }
            });
        </script>
    </body>
</html>

Try clicking on any two points on the map to display a pedestrian route between them.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Urbi Map API</title>
        <meta name="description" content="MapGL API directions example" />
        <style>
            html,
            body,
            #container {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
            }
            #reset {
                padding: 4px 10px;
                background: #00a81f;
                border-radius: 4px;
                box-shadow: 0 1px 3px 0 rgba(38, 38, 38, 0.5);
                border: none;
                color: #fff;
                font-size: 12px;
                cursor: pointer;
            }
        </style>
    </head>
    <body>
        <div id="container"></div>
        <script src="https://mapgl.2gis.com/api/js/v1"></script>
        <script src="https://unpkg.com/@2gis/mapgl-directions@^2/dist/directions.js"></script>
        <script>
            const map = new mapgl.Map('container', {
                center: [55.31878, 25.23584],
                zoom: 17,
                key: 'Your API access key',
            });

            const directions = new mapgl.Directions(map, {
                // This key can be used for demo purpose only!
                // You can get your own key on https://urbi.ae/urbi-navigation#contact
                directionsApiKey: 'Your directions API access key',
            });
            const markers = [];

            let firstPoint;
            let secondPoint;
            // A current selecting point
            let selecting = 'a';

            const controlsHtml = `<button id="reset">Reset points</button> `;
            new mapgl.Control(map, controlsHtml, {
                position: 'topLeft',
            });
            const resetButton = document.getElementById('reset');

            resetButton.addEventListener('click', function() {
                selecting = 'a';
                firstPoint = undefined;
                secondPoint = undefined;
                directions.clear();
            });

            map.on('click', (e) => {
                const coords = e.lngLat;

                if (selecting != 'end') {
                    // Just to visualize selected points, before the route is done
                    markers.push(
                        new mapgl.Marker(map, {
                            coordinates: coords,
                            icon: 'https://docs.2gis.com/img/dotMarker.svg',
                        }),
                    );
                }

                if (selecting === 'a') {
                    firstPoint = coords;
                    selecting = 'b';
                } else if (selecting === 'b') {
                    secondPoint = coords;
                    selecting = 'end';
                }

                // If all points are selected — we can draw the route
                if (firstPoint && secondPoint) {
                    directions.pedestrianRoute({
                        points: [firstPoint, secondPoint],
                    });
                    markers.forEach((m) => {
                        m.destroy();
                    });
                }
            });
        </script>
    </body>
</html>

Route is a line on a map that consists of three sub-lines drawn under each other: the main route line at the top (green), a "substrate" line in the middle (white), and a "halo" line at the bottom (red). You can change the width of any of these sublines using the style parameter.

Width can be specified in pixels or as InterpolateExpression, in which case it will change depending on the current zoom level. To hide a subline, set its width to 0.

directions.carRoute({
    points: [
        [55.28273111108218, 25.234131928828333],
        [55.35242563034581, 25.23925607042088],
    ],
    style: {
        routeLineWidth: [
            'interpolate',
            ['linear'],
            ['zoom'],
            10,
            30, // width will change from 30 px at zoom level 10 and below...
            14,
            3, // ...to 3 px at zoom level 14 and above
        ],
        substrateLineWidth: [
            'interpolate',
            ['linear'],
            ['zoom'],
            10,
            3, // width will change from 3 px at zoom level 10 and below...
            14,
            50, // ...to 50 px at zoom level 14 and above
        ],
        // Width will stay constant at all zoom levels
        haloLineWidth: 60,
    },
});

Try zooming in and out to see the width interpolation in action.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Urbi Map API</title>
        <meta name="description" content="MapGL API directions example" />
        <style>
            html,
            body,
            #container {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
            }
            #reset {
                padding: 4px 10px;
                background: #00a81f;
                border-radius: 4px;
                box-shadow: 0 1px 3px 0 rgba(38, 38, 38, 0.5);
                border: none;
                color: #fff;
                font-size: 12px;
                cursor: pointer;
            }
        </style>
    </head>
    <body>
        <div id="container"></div>
        <script src="https://mapgl.2gis.com/api/js/v1"></script>
        <script src="https://unpkg.com/@2gis/mapgl-directions@^2/dist/directions.js"></script>
        <script>
            const map = new mapgl.Map('container', {
                center: [55.31878, 25.23584],
                zoom: 13,
                key: 'Your API access key',
            });
            const directions = new mapgl.Directions(map, {
                // This key can be used for demo purpose only!
                // You can get your own key on https://urbi.ae/urbi-navigation#contact
                directionsApiKey: 'Your directions API access key',
            });

            directions.carRoute({
                points: [
                    [55.28273111108218, 25.234131928828333],
                    [55.35242563034581, 25.23925607042088]
                ],
                style: {
                    routeLineWidth: ['interpolate', ['linear'], ['zoom'],
                        10, 30, // zoom - width
                        14, 3 // zoom - width
                    ],
                    substrateLineWidth: ['interpolate', ['linear'], ['zoom'],
                        10, 3, // zoom - width
                        14, 50 // zoom - width
                    ],
                    // Or just static width value
                    haloLineWidth: 60,
                }
            });
        </script>
    </body>
</html>