Добавить карту на сайт для построения маршрута

Добавить карту на сайт для построения маршрута

В данной статье вы узнаете как встроить Яндекс карты на ваш сайт. Научитесь получать данные о маршрутах, такие как протяженность маршрута, время с учетом пробок и без пробок, узнавать есть ли на маршруте платные дороги или перекрытия. Мы создадим калькулятор, который в режиме реального времени будет считать затраты на топливо, в зависимости от маршрута и от введенных пользователем данных.

Для работы мы будем использовать Яндекс.Карты API. API Яндекс.Карт — это набор сервисов, которые позволяют использовать картографические данные и технологии Яндекса в ваших проектах. Для нас подойдет бесплатная версия, т.к. мы не будем строить коммерческий проект и наша карта будет доступна всем.

Подробнее об ограничениях на бесплатное использование API Яндекс.Карты можете почитать по адресу: https://tech.yandex.ru/maps/commercial/

Добавляем Яндекс.Карты на сайт

Чтобы добавить карты на сайт необходимо подключить библиотеку Javascript API. Сразу подключим плагин JQuery, который нам пригодится в нашем проекте. Для этого между тегами пишем следующий код.

<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous" type="text/javascript"></script>
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>

После подключения библиотеки нам необходимо создать слой с уникальным id=»map» (может быть любым), в который будет выводиться наша карта. Для этого в нужном нам месте пишем следующую строчку.

<div id="map"></div>

Нам осталось написать скрипт, который будет выводить карту на страницу. Для этого после нашего слоя пишем следующий код.

<script type="text/javascript">
ymaps.ready(init);

function init() { 
myMap = new ymaps.Map('map', { // Выводим в слой с id="map"
center: [59.9174, 30.3250], // центрируем карту на Санкт-Петербурге
zoom: 11, // Ставим зум кратный 11
controls: [] // Никакие кнопки управления пока не добавляем
})}
</script>

Добавим стили, чтобы карта выводилась на всю страницу.

<style>
 body, html, #map {
   width: 100%;
   height: 100%;
   padding: 0;
   margin: 0;
   position: absolute;
}
</style>

Сохраняем страницу и смотрим на результат!

Настраиваем Яндекс.Карты

Наша задача состоит в построении маршрута от точки А до точки В. Для этого нам необходима навигационная панель для ввода начальной и конечной точек. Добавим панель и кнопки масштабирования на карту, используя Яндекс.Карты API.

routePanelControl = new ymaps.control.RoutePanel({
    options: {
        showHeader: true, //Показывать заголовок навигационной панели
        title: 'Проложить маршрут', //Заголовок панели
        allowSwitch: true, //Отображать кнопку для смены местами Откуда/Куда
        maxWidth: '300px', //Ширина панели (макс. 400px)
        float: 'left' // Расположение в левой части карты
    }
}),
zoomControl = new ymaps.control.ZoomControl({
    options: {
        float: 'right', // Расположение в правой части карты
        position: {     //Координаты 
            top: 245,   //расположения
            right: 10   //кнопок зума
        }
    }
});
myMap.controls.add(routePanelControl).add(zoomControl);

Теперь мы имеем уже рабочую версию карт и даже можем строить маршруты.

Убираем возможность строить маршруты на общественном транспорте и пешеходные маршруты, т.к. для нашей задачи они не понадобятся. Для этого используйте следующий код:

// Пользователь сможет построить только автомобильный маршрут.
routePanelControl.routePanel.options.set({
   types: {auto: true},
});

Для удобства построения маршрутов можно указать в качестве точки отправления текущее положение пользователя. За это отвечает следующая строчка кода:

// Зададим координаты пункта отправления с помощью геолокации.
routePanelControl.routePanel.geolocate('from');

Добавим информацию о пробках на карту:

// Создадим элемент управления "Пробки".
    var trafficControl = new ymaps.control.TrafficControl({ state: {
            // Отображаются пробки "Сейчас".
            providerKey: 'traffic#actual',
            // Начинаем сразу показывать пробки на карте (true) или после нажатия на кнопку (false)
            trafficShown: false
        }});
    // Добавим контрол на карту.
    myMap.controls.add(trafficControl);
    // Получим ссылку на провайдер пробок "Сейчас" и включим показ инфоточек.
    trafficControl.getProvider('traffic#actual').state.set('infoLayerShown', true);

Получение информации об активном маршруте Яндекс.Карты

Теперь, когда у нас строятся маршруты, нам необходимо получить информацию о времени и протяженности маршрута. Эти данные нам понадобятся в дальнейшем для автоматизации расчетов затрат на топливо.

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

// Получим ссылку на маршрут.
    routePanelControl.routePanel.getRouteAsync().then(function (route) {

        // Зададим максимально допустимое число маршрутов, возвращаемых мультимаршрутизатором.
        route.model.setParams({results: 1}, true);
        //Искать оптимальный маршрут с учетом пробок
        route.model.setParams({avoidTrafficJams: true}, true);

        // Повесим обработчик на событие построения маршрута.
        route.model.events.add('requestsuccess', function () {
            var activeRoute = route.getActiveRoute();
            if (activeRoute) {
                activeRoute.balloon.open();
            }
        });
    });

В балун выводится краткая информация о маршруте. Мы знаем протяженность маршрута, время в пути с учетом пробок и без пробок, о платных участках на маршруте и о перекрытиях на дороге. Эти данные передаются в параметрах properties активного маршрута. Извлечем эти данные и выведем в консоль браузера для наглядности.

// Получим протяженность маршрута.
    length = route.getActiveRoute().properties.get("distance"), // Протяженность маршрута
    time = route.getActiveRoute().properties.get("duration"), // Время маршрута
    blocked = route.getActiveRoute().properties.get("blocked"), // Есть ли перекрытия на маршруте
    tolls = route.getActiveRoute().properties.get("hasTolls"), // Есть ли платные участки дороги
    timeintraffic = route.getActiveRoute().properties.get("durationInTraffic"); // Время с учетом пробок
    activeRoute.balloon.open();
    console.log('Протяженность маршрута ' + length.value); // Протяженность маршрута в метрах
    console.log('Протяженность маршрута ' + length.text); // Протяженность маршрута в текстовом представлении
    console.log('Время без пробок ' + time.value); // Время в секундах без учета пробок
    console.log('Время без пробок ' + time.text); // Время в текстовом представлении без учета пробок
    console.log('Время с пробками ' + timeintraffic.value); // Время в секундах с учетом пробок
    console.log('Время с пробками ' + timeintraffic.text); // Время в текстовом представлении с учетом пробок
    console.log('blocked' + blocked); // На маршруте есть перекрытия дороги
    console.log('tolls ' + tolls); // На маршруте есть платные участки дороги

Вывод информации о маршруте в собственное поле на карте

Информацию о маршруте мы будем выводить прямо на карту под навигационной панелью. Вы можете сделать вывод информации в любое место по аналогии. Не буду описывать стили для слоев в статье. Кому интересно, можете посмотреть в исходном коде на странице, которая будет указана в конце статьи.

Создаем свой слой, на который будет выводиться наша информация о маршруте и затратах. Прописываем ему стили, чтобы он располагался под навигационной панелью и был скрыт по умолчанию.

Добавим на слой форму для ввода расхода и стоимости топлива. Эти данные нам позже пригодятся. Сразу пропишем значения, которые будут подставляться по умолчанию.

У вас должно получиться примерно так:

<div id="map">
<div id="info">
<div style="padding-left: 25px; float:left" class="text">
<input type="number" name="fuel" id="fuel" value="40" /> литр/100 км
<input type="number" name="price" id="price" value="45" /> руб/литр
</div>
<div id="infotext"></div>
<div id="infotextprice"></div>
</div>
</div>

В данный момент наша карта никак изменилась и ничего не считает. Нам необходимо заполнять наши слои информацией при выводе маршрута на карту. Для этого пропишем формулы для расчетов и куда выводить информацию.

// Получим протяженность маршрута.
        $('#info').css("display", "block"); // Показываем наш блок с информацией
        length = route.getActiveRoute().properties.get("distance"), // Протяженность маршрута
        time = route.getActiveRoute().properties.get("duration"), // Время маршрута
        blocked = route.getActiveRoute().properties.get("blocked"), // Есть ли перекрытия на маршруте
        tolls = route.getActiveRoute().properties.get("hasTolls"), // Есть ли платные участки дороги
        timeintraffic = route.getActiveRoute().properties.get("durationInTraffic"); // Время с учетом пробок
        var fuel = document.getElementById("fuel").value; // Считываем расход топлива из формы
        var price = document.getElementById("price").value; // Считываем стоимость топлива из формы
        var rashod = Math.round((length.value/100000)*fuel); // Считаем сколько топлива потратим
        var money = Math.round(rashod*price); // Считаем сколько денег потратим на топливо
        mydis.innerHTML='';
        mydisprice.innerHTML='';
        mydis.insertAdjacentHTML("beforeend", 'Оптимальный маршрут составляет ' + length.text + '
');
        mydis.insertAdjacentHTML("beforeend", 'Время с учетом пробок ' + timeintraffic.text + '
');
        mydisprice.insertAdjacentHTML("beforeend", 'Примерные расходы топлива ' + rashod + ' л.
');
        mydisprice.insertAdjacentHTML("beforeend", 'Расходы на топливо ' + money + ' руб.
');
        if (blocked) {mydis.insertAdjacentHTML("beforeend", 'На участке есть перекрытия дороги!
');}
        if (tolls) {mydis.insertAdjacentHTML("beforeend", 'На маршруте есть платные участки дороги!
');}
        activeRoute.balloon.open();
        console.log('Протяженность маршрута ' + length.value); // Протяженность маршрута в метрах
        console.log('Протяженность маршрута ' + length.text); // Протяженность маршрута в текстовом представлении
        console.log('Время без пробок ' + time.value); // Время в секундах без учета пробок
        console.log('Время без пробок ' + time.text); // Время в текстовом представлении без учета пробок
        console.log('Время с пробками ' + timeintraffic.value); // Время в секундах с учетом пробок
        console.log('Время с пробками ' + timeintraffic.text); // Время в текстовом представлении с учетом пробок
        console.log('blocked' + blocked); // На маршруте есть перекрытия дороги
        console.log('tolls ' + tolls); // На маршруте есть платные участки дороги

Теперь нам необходимо пересчитывать затраты при изменении значений в форме. Для этого напишем функцию recalc() и пропишем ее вызов в форме.

<script type="text/javascript">
        function recalc() {
            var mydis = document.getElementById('infotext');
            var mydisprice = document.getElementById('infotextprice');
            var fuel = document.getElementById("fuel").value;
            var price = document.getElementById("price").value;
            var rashod = Math.round((window.length.value/100000)*fuel);
            var money = Math.round(rashod*price);
            mydisprice.innerHTML='';
            mydisprice.insertAdjacentHTML("beforeend", 'Примерные расходы топлива <strong>' + rashod + ' л.</strong><br />');
            mydisprice.insertAdjacentHTML("beforeend", 'Расходы на топливо <strong>' + money + ' руб.</strong><br />');
        }
    </script>
<div style="padding-left: 25px; float:left" class="text">
   <input type="number" name="fuel" id="fuel" value="40" oninput="recalc()"> литр/100км
   <input type="number" name="price" id="price" value="45" oninput="recalc()"> руб/литр
</div>

Можно разрешить пользователю изменять маршрут простым перетягиванием любой его точки по карте. Для этого добавляем код.

//Разрешаем перетаскивать точки между начальной и конечной точками
   route.editor.start();

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

Разместить форму расчета расстояния и затрат на топливо между городами на сайте

У вас появилась возможность установить нашу форму расчета расстояния между городами, поиска кратчайшего пути и подсчета примерных затрат на топливо на ваш сайт бесплатно!

Вам необходимо разместить в нужном месте на вашем сайте следующий код:

<script src="https://demo.pogrommist.ru/route/embed.js"></script>

После этого на вашем сайте появится форма расчета расстояния между городами. Сервис предоставляется абсолютно бесплатно!

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

Если у вас возникнут проблемы с установкой формы на ваш сайт, пишите нам в комментарии. Сервис предоставляется на условиях «Как есть».

Исходный код вы можете посмотреть здесь: https://pogrommist.ru/route/

Больше примеров можно посмотреть в Песочнице Яндекса: https://tech.yandex.ru/maps/jsbox/2.1/