Построение автомобильных маршрутов, используя API Яндекс.Карт 2.х

Продолжаем знакомиться с особенностями API Яндекс.Карт версии 2.х (смотрите части 1, 2, 3).

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

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

Для примера, я возьму адрес недавно открывшегося в Нижнем Новгороде кинотеатра Синема Парк DeLuxe IMAX — ул. Бетанкура 1 ТРК Седьмое небо.

Рассмотрим работу примера.

Над окном карты расположена форма для ввода адреса отправления, конечный адрес у нас постоянный (Нижний Новгород, ул. Бетанкура 1).

После ввода адреса (Нижний Новгород, Варварская ул., 7), мы нажимаем на кнопку «Найти», происходит расчет и построение на карте маршрута.

Посмотреть пример в действии

Поясню исходный код примера.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Добавление маршрута на карту - API Яндекс.Карт 2.х</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 
<script src="http://yandex.st/jquery/1.6.4/jquery.min.js" type="text/javascript"></script>
 
    <script src="http://api-maps.yandex.ru/2.0/?load=package.full&lang=ru-RU"
            type="text/javascript"></script>
    <script type="text/javascript">	
		var myMap, route;
 
 
		// Как только будет загружен API и готов DOM, выполняем инициализацию
        ymaps.ready(init);
 
        function init () {
            myMap = new ymaps.Map("map", {
                    center: [56.326944, 44.0075],
                    zoom: 12
                });       
 
 
		 $('#search_route').submit(function () {                
			var start = $("#start").val();
			var end = $("#end").val();			
            ymaps.route([
                   // Список точек, которые необходимо посетить
                   [start], [end]], {
                // Опции маршрутизатора
                mapStateAutoApply: true // автоматически позиционировать карту
            }).then(function (router) {
			    route && myMap.geoObjects.remove(route);
				route = router;
                myMap.geoObjects.add(route);
            }, function (error) {
                alert("Возникла ошибка: " + error.message);
            });
				return false;
			});
		 }	
 
 
    </script>
</head>
 
<body>
<form id="search_route">
<b>Начало: </b>
<input id="start" type="text" value="Нижний Новгород, " style="width: 360px;"><br />
<b>Конец: Синема Парк DeLuxe IMAX</b>
<input id="end" type="text" value="Нижний Новгород, ул. Бетанкура 1" style="width: 260px;">
<input type="submit" value="Найти"/>
</form>
<br />
<div id="map" style="width:800px;height:600px"></div>
</body>
</html>

В самом начале, мы подключаем javascript-библиотеку jquery, т. к. ее нет в новой версии API API Яндекс.Карт 2.х.

По клику на кнопке «Найти» вызывается функция в которой определяются значения полей формы search_route начало и конец маршрута.

Эти значения передаются маршрутизатору ymaps.route, а в качестве дополнительного параметра mapStateAutoApply: true — для автоматического позиционирования карты, после построения маршрута.

Далее мы проверяем существует или нет на карте уже построенный ранее маршрут, если да то удаляем его с карты, после чего добавляем новый маршрут командой myMap.geoObjects.add(route);

Если в процессе построения маршрута возникнут ошибки, выводим их во всплывающем окне.

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

Перечислю остальные параметры:

avoidTrafficJams — значения true — строить маршрут с учетом пробок, false — без учета пробок При использовании опции учитывайте, что объезд пробок не всегда возможен.
Значение по умолчанию: false;

boundedBy — значение определяет область на карте, где предположительно находятся искомые объекты. Используется, если точки маршрута заданы почтовым адресом, а не координатами;

strictBounds — определяет возможность поиска только внутри области, заданной опцией boundedBy. Используется, если точки маршрута заданы почтовым адресом, а не координатами.
Значение по умолчанию: false

Давайте зададим область поиска в границах Нижнего Новгорода, тогда дополнительно указывать город в адресной строке ненужно.

Второй пример.

Посмотреть пример в действии

Код примера:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Ограничение области поиска - добавление маршрута на карту - API Яндекс.Карт 2.х</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 
<script src="http://yandex.st/jquery/1.6.4/jquery.min.js" type="text/javascript"></script>
 
    <script src="http://api-maps.yandex.ru/2.0/?load=package.full&lang=ru-RU"
            type="text/javascript"></script>
    <script type="text/javascript">	
		var myMap, route;
 
 
		// Как только будет загружен API и готов DOM, выполняем инициализацию
        ymaps.ready(init);
 
        function init () {
            myMap = new ymaps.Map("map", {
                    center: [56.326944, 44.0075],
                    zoom: 12
                });       
 
 
		 $('#search_route').submit(function () {                
			var start = $("#start").val();
			var end = $("#end").val();			
            ymaps.route([
                   // Список точек, которые необходимо посетить
                   [start], [end]], {
                // Опции маршрутизатора
                mapStateAutoApply: true, // автоматически позиционировать карту
				boundedBy: [[56.155974,43.549068],[56.421028,44.155787]],
				strictBounds: true
            }).then(function (router) {
			    route && myMap.geoObjects.remove(route);
				route = router;
                myMap.geoObjects.add(route);
            }, function (error) {
                alert("Возникла ошибка: " + error.message);
            });
				return false;
			});
		 }	
 
 
    </script>
</head>
 
<body>
<form id="search_route">
<b>Начало: </b>
<input id="start" type="text" value=" " style="width: 360px;"><br />
<b>Конец: Синема Парк DeLuxe IMAX</b>
<input id="end" type="text" value="Нижний Новгород, ул. Бетанкура 1" style="width: 260px;">
<input type="submit" value="Найти"/>
</form>
<br />
<div id="map" style="width:800px;height:600px"></div>
</body>
</html>

Здесь код примера похож на предыдущий, за исключением двух параметров:

boundedBy: [[56.155974,43.549068],[56.421028,44.155787]] — задает границы области;

strictBounds: true — возможность поиска только в заданной области.

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

Третий пример

Посмотреть пример в действии

В этом примере между точками start и end, мы добавляем промежуточную точку на пл. Ленина

{
	type: 'viaPoint', // площадь Ленина - транзитная точка (проезжать через эту точку, но не останавливаться в ней)
	point: 'Нижний Новгород, площадь Ленина'
},

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

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

Четвертый пример

Посмотреть пример в действии

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

Код примера:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Задание стиля для меток и маршрута - добавление маршрута на карту - API Яндекс.Карт 2.х</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 
<script src="http://yandex.st/jquery/1.6.4/jquery.min.js" type="text/javascript"></script>
 
    <script src="http://api-maps.yandex.ru/2.0/?load=package.full&lang=ru-RU"
            type="text/javascript"></script>
    <script type="text/javascript">	
		var myMap, route;
 
 
		// Как только будет загружен API и готов DOM, выполняем инициализацию
        ymaps.ready(init);
 
        function init () {
            myMap = new ymaps.Map("map", {
                    center: [56.326944, 44.0075],
                    zoom: 12
                });       
 
 
		 $('#search_route').submit(function () {                
			var start = $("#start").val();
			var end = $("#end").val();			
            ymaps.route([
                   // Список точек, которые необходимо посетить
                   [start], [end]], {
                // Опции маршрутизатора
                mapStateAutoApply: true, // автоматически позиционировать карту				
            }).then(function (router) {
			    route && myMap.geoObjects.remove(route);
				route = router;
				route.options.set({ strokeColor: '0000ffff', opacity: 0.9 });
                myMap.geoObjects.add(route);
				// С помощью метода getWayPoints() получаем массив точек маршрута 
                    // (массив транзитных точек маршрута можно получить с помощью метода getViaPoints)
                    var points = route.getWayPoints();  
                    // Задаем стиль метки - иконки будут красного цвета, и
                    // их изображения будут растягиваться под контент
                    points.options.set('preset', 'twirl#redStretchyIcon');
                    // Задаем контент меток в начальной и конечной точках
                    points.get(0).properties.set('iconContent', 'Точка отправления');
                    points.get(1).properties.set('iconContent', 'Точка прибытия');			
            }, function (error) {
                alert("Возникла ошибка: " + error.message);
            });
				return false;
			});
		 }	
 
 
    </script>
</head>
 
<body>
<form id="search_route">
<b>Начало: </b>
<input id="start" type="text" value="Нижний Новгород, " style="width: 360px;"><br />
<b>Конец: Синема Парк DeLuxe IMAX</b>
<input id="end" type="text" value="Нижний Новгород, ул. Бетанкура 1" style="width: 260px;">
<input type="submit" value="Найти"/>
</form>
<br />
<div id="map" style="width:800px;height:600px"></div>
</body>
</html>

Цвет и величина прозрачности маршрута задается в строке

route.options.set({ strokeColor: ‘0000ffff’, opacity: 0.9 });

Еще несколько строк кода отвечают за изменения стиля конечных точек маршрута:

// С помощью метода getWayPoints() получаем массив точек маршрута 
// (массив транзитных точек маршрута можно получить с помощью метода getViaPoints)
var points = route.getWayPoints();  
// Задаем стиль метки - иконки будут красного цвета, и
// их изображения будут растягиваться под контент
points.options.set('preset', 'twirl#redStretchyIcon');
// Задаем контент меток в начальной и конечной точках
points.get(0).properties.set('iconContent', 'Точка отправления');
 points.get(1).properties.set('iconContent', 'Точка прибытия');

Мы легко можем заменить стандартные иконки на свои.

Пятый пример

Посмотреть пример в действии

Здесь мы задаем стили для нашей картинки:

 points.options.set('preset', {
                    iconImageHref: 'my-markers.png', // картинка иконки
                    iconImageSize: [32, 37], // размеры картинки
                    iconImageOffset: [16, -37] // смещение картинки
  });

Можно вывести общую длину маршрута и время в пути под картой.

Шестой пример.

Посмотреть пример в действии

Добавив после строки:

myMap.geoObjects.add(route);

следующие строки

$("#resmarshrut").append('Общая длина маршрута: '+route.getHumanLength());
$("#resmarshrut").append('<br /> Время в пути: '+route.getHumanTime());

В этих строчках кода мы обращаемся к соответствующим методам объекта router.Route:

getHumanLength() — он возвращает строковое представление длины маршрута с единицами измерения;
GetHumanTime() — он возвращает строковое представление времени проезда маршрута с единицами измерения.

С другими методами можно познакомиться здесь

И последний пример — это вывод маршрутного листа.

Посмотреть пример в действии

Пример кода:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Вывод путевого листа - добавление маршрута на карту - API Яндекс.Карт 2.х</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 
<script src="http://yandex.st/jquery/1.6.4/jquery.min.js" type="text/javascript"></script>
 
    <script src="http://api-maps.yandex.ru/2.0/?load=package.full&lang=ru-RU"
            type="text/javascript"></script>
    <script type="text/javascript">	
		var myMap, route;
 
 
		// Как только будет загружен API и готов DOM, выполняем инициализацию
        ymaps.ready(init);
 
        function init () {
            myMap = new ymaps.Map("map", {
                    center: [56.326944, 44.0075],
                    zoom: 12
                });       
 
 
		 $('#search_route').submit(function () {                
			var start = $("#start").val();
			var end = $("#end").val();			
            ymaps.route([
                   // Список точек, которые необходимо посетить
                   [start], [end]], {
                // Опции маршрутизатора
                mapStateAutoApply: true, // автоматически позиционировать карту				
            }).then(function (router) {
			    route && myMap.geoObjects.remove(route);
				route = router;
                myMap.geoObjects.add(route);
				// Получаем первый маршрут
                  var way = route.getPaths().get(0),
                      // Маршрут состоит из сегментов. Сегмент - участок маршрута, который нужно проехать
                      // до следующего изменения направления движения.
                      segments = way.getSegments(),
                      moveList = 'Трогаемся,</br>';
                  for (var i = 0; i < segments.length; i++) {
                      var street = segments[i].getStreet();
                      moveList += ('Едем ' + segments[i].getHumanAction() + (street ? ' на ' + street : '') + ', проезжаем ' + segments[i].getLength() + ' м.,');
                      moveList += '</br>'
                  }
                  moveList += 'Останавливаемся.';
				  $("#list").empty();
                  // Выводим маршрутный лист
                  $('#list').append(moveList);
            }, function (error) {
                alert("Возникла ошибка: " + error.message);
            });
				return false;
			});
		 }	
 
 
    </script>
</head>
 
<body>
<form id="search_route">
<b>Начало: </b>
<input id="start" type="text" value="Нижний Новгород, " style="width: 360px;"><br />
<b>Конец: Синема Парк DeLuxe IMAX</b>
<input id="end" type="text" value="Нижний Новгород, ул. Бетанкура 1" style="width: 260px;">
<input type="submit" value="Найти"/>
</form>
<br />
<div id="map" style="width:800px;height:600px"></div>
<br /><br />
<div id="list"></div>
 
</body>
</html>

В этом примере весь маршрут разбивается на сегменты и для каждого с помощью методов объекта router.Segment формируется текстовая подсказка движения по маршруту.

С другими методами можно познакомиться здесь

После сформированный маршрутный лист передается в контейнер div с id="list".

Загрузить архив с файлами примеров

  • Гость: Благодарю. Отличные статьи
  • Гость: Отлично! А можно сделать так: тыкаешь на карте - ставится метка, тыкаешь второй раз - ставится вторая и между ними прокладывается маршрут?
  • Гость: Есть пример от разработчиков API <a href="http://ymapsapi.narod.ru/examples/deliveryCalculator.html" title="маршрутизация и расчет стоимости поездки" target="_blank" rel="nofollow">маршрутизация и расчет стоимости поездки</a>, в котором реализовано прокладка маршрута при клике на карте. Немного позже сделаю свой пример.
  • Гость: Проблема с "маршрутизатором" при добавлении "элементов управления картой" После добавления в код "Элементов управления картой" перестает работать "Маршрутизатор" во всех браузерах(IE, Opera, Google Chrome), кроме Mozilla Firefox. Версии браузеров актуальны. + сами "Элементы управления" не появляются в браузерах(коме Mozilla Firefox). Сайт на cms Joomla 1,5. Без Joomla во всех браузерах этот же код (с "элементами управления") работает без проблем. Добавляю следующие строки: //Элементы управления myMap.controls // Кнопка изменения масштаба - компактный вариант .add('smallZoomControl', { left: 10, top: 10 }) // Список типов карты .add('typeSelector') Как вылечить?
  • Гость: Проблема постом выше решилась обновлением mootools. По поводу прокладки маршрута при клике на карту - жду Ваш пример!
  • Гость: Написал по теме новую <a href="http://webmap-blog.ru/yandex-maps/postroenie-marshruta-na-karte-po-zadannym-tochkam-api-yandeks-kart-2-x" title="Построение маршрута на карте, по заданным точкам - API Яндекс.Карт 2.х" target="_blank" rel="nofollow">заметку</a> с примером
  • Гость: А можно чтоб маршруты в базу записывались желательно на жумле 2,5?
  • Гость: Уже руки опускаються, пишу на С# ASP в визуал студии Не понимаю в чем проблема, Просто создаю пустую страницу АСП, вставляю выше приведенный код, любой, Карта отображаеться, все хорошо, но, маршрут не строица, брал применр с яндекса, если ввожу названия улиц ручками все хорошо, если начинаю брать из текстбоксов, ничего не работает. Помогите кто может.
  • Гость: Подскажите пожайлуста - а что означает символ $ в строке ("#resmarshrut").append('Общая длина маршрута: '+route.getHumanLength());
  • Гость: Так $ обозначаются функции в jQuery, если на сайте применяются другие JavaScript библиотеки, где $ может использоваться для своих нужд, то можно использовать её синоним — jQuery.
  • Гость: А как добавить, чтобы в поле ввода, автоматически находил город из списка, как это сделано на яндекс картах
  • Гость: Нужно иметь базу данных с именами городов и делать автодополнение при помощи AJAX.
  • Гость: Подскажите, а как проложить маршрут, чтобы метки вообще не выводились, или можно было задать содержимое балунов!
  • Гость: Вот <a href="http://clubs.ya.ru/mapsapi/replies.xml?item_no=24525" title="Управление метки маршрутизатора?" target="_blank" rel="nofollow">обсуждение</a> в клубе разработчиков которое Вам поможет
  • Гость: Здравствуйте! На моем сайте, расчет маршрута выдается, только если пользователь зарегистрирован, есть мысли почему так?. Все модули и пункты меню включены для всех. Спасибо!
  • Гость: Скажите, а как определить лежит ли какая-либо произвольная точка на маршруте или может можно узнать удаленность точки от маршрута?
  • Гость: Добрый день. Как добавить меню для ввода транзитных пунктов? меню такое var items=0; function AddItem() { div=document.getElementById("items"); button=document.getElementById("add"); items++; newitem="<strong>Пункт " + items + ": </strong>"; newitem+=""; newnode=document.createElement("span"); newnode.innerHTML=newitem; div.insertBefore(newnode,button); } в функцию search_route добавил var items = $("#items").val();
  • Гость: а как в 6-м примере сделать так что бы не получалось вот такого: "Общая длина маршрута: 4.5 км Время в пути: 9 минОбщая длина маршрута: 4.5 км Время в пути: 9 минОбщая длина маршрута: 4.5 км Время в пути: 9 минОбщая длина маршрута: 4.5 км Время в пути: 9 минОбщая длина маршрута: 4.5 км Время в пути: 9 минОбщая длина маршрута: 4.5 км Время в пути: 9 мин"?
  • Владимир Некрасов: Я загнал в iframe и вся шляпа идет вниз, но самое главное, вдруг кому пригодится - расчет стоимости маршрута: $("#resmarshrut").prepend('Cтоимость: '+parseFloat(route.getHumanLength().split(' ')[0])*35+'<br /><br />');
  • Георгий Рукосуев: перед: $("#resmarshrut").append('Общая длина маршрута: '+route.getHumanLength()); вставить: $("#resmarshrut").empty();
  • Гость: Как бы еще добавить кнопки навигации и пробок?
  • Дмитрий: Да, ребята подскажите как перевести этот пример с 2.0 на 2.1? Если поменять версии, то перестает строится маршрут, что подкорректировать под 2.1 нужно?
  • Анатолий Петров: Уважаемые, как отобразить несколько РАЗНЫХ маршрутов на одной карте?? ни как ни где не могу это найти, странно
  • Гость: К сожалению, примеры не работают. Подскажите, пожалуйста, что нужно в них поменять, чтобы работали по умолчанию?
  • Александр Зеленогорский: Этот код: --------------------------------- ymaps.route([ [start], [end]], { mapStateAutoApply: true, }).then(function (router) { --------------------------------- заменить на этот --------------------------------- ymaps.route([start, end], {mapStateAutoApply: true,}) .then(function (router) { ---------------------------------