Построение маршрута | MapGL | 2GIS Documentation
MapGL JS API
Личный кабинет

Построение маршрута

Плагин Directions позволяет построить оптимальный маршрут между несколькими точками (до десяти).

Плагин использует Directions API, поэтому для его использования нужно получить ключ доступа к Directions API: см. инструкцию по оформлению ключей доступа.

Чтобы подключить плагин, нужно добавить следующую строку после подключения основного скрипта MapGL:

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

Или установить нужный пакет npm:

npm install @2gis/mapgl-directions

Чтобы отображать маршруты на карте, нужно сначала инициализировать объект Directions:

const directions = new mapgl.Directions(map, {
    directionsApiKey: 'Ключ Directions API',
});

В случае использования npm:

// Импортируйте плагин как ES-модуль...
import { Directions } from '@2gis/mapgl-directions';
// ...или как модуль CommonJS
const { Directions } = require('@2gis/mapgl-directions');

const directions = new Directions(map, {
    directionsApiKey: 'Ключ для Directions API',
});

После инициализации можно вызывать следующие методы:

  • carRoute() для построения автомобильного маршрута;
  • pedestrianRoute() для построения пешеходного маршрута.

Оба метода принимают массив географических координат в качестве параметра points.

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

Чтобы удалить маршрут, нужно вызвать метод clear():

directions.clear();

Выберите две точки на карте, чтобы построить между ними автомобильный маршрут.

<!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>

Выберите две точки на карте, чтобы построить между ними пешеходный маршрут.

<!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 line);
  • белая линия подложки посередине (substrate line);
  • красная линия обводки внизу (halo line).

Ширину любой из этих линий можно изменить с помощью параметра style.

Ширину можно указать в пикселях или как InterpolateExpression - в таком случае она будет меняться в зависимости от масштаба карты.

Чтобы скрыть линию, нужно указать для неё ширину 0.

directions.carRoute({
    points: [
        [55.28273111108218, 25.234131928828333],
        [55.35242563034581, 25.23925607042088],
    ],
    style: {
        // Основная линия (зелёная)
        routeLineWidth: [
            'interpolate',
            ['linear'],
            ['zoom'],
            10,
            30, // Ширина основной линии будет меняться от 30 пикселей на масштабе 10 и ниже...
            14,
            3, // ...до 3 пикселей на масштабе 14 и выше
        ],
        // Линия подложки (белая)
        substrateLineWidth: [
            'interpolate',
            ['linear'],
            ['zoom'],
            10,
            3, // Ширина линии подложки будет меняться от 3 пикселей на масштабе 10 и ниже...
            14,
            50, // ...до 50 пикселей на масштабе 14 и выше
        ],
        // Ширина линии обводки будет равна 60 пикселям на любом масштабе карты
        haloLineWidth: 60,
    },
});

Попробуйте изменить масштаб карты в примере ниже, чтобы увидеть как меняется ширина линий.

<!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>