Построение маршрута на карте, по заданным точкам — API Яндекс.Карт 2.х

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

Мне задали вопрос, а как можно строить маршруты по кликам на карте?

В этой заметке я отвечаю на него.

С начала рассмотрим работу примера, а затем я поясню его код.

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

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

Затем, нажимаем на кнопку «Построить маршрут» и происходит построение маршрута через заданные точки.

Если нам необходимо построить новый маршрут, мы нажимаем на кнопку «Очистить» и можем повторять действия для добавления другого маршрута.

Рассмотрим код примера:

<!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://api-maps.yandex.ru/2.0/?load=package.full&lang=ru-RU" type="text/javascript"></script>
 
    <script type="text/javascript">   
 
		var myMap, route, ch =1;
 
		var markers = [];
 
		var point = [];	
 
        ymaps.ready(init);
 
        function init () {
 
            myMap = new ymaps.Map('map', {
                    center: [56.314102,44.017161], 
                    zoom: 14
                });
 
		//Добавляем элементы управления	
			 myMap.controls                
                .add('zoomControl')               
                .add('typeSelector')                
                .add('mapTools')	
 
		//Отсеживаем событие клика по карте		
		myMap.events.add('click', function (e) {                
            var coords = e.get('coordPosition');
			if(markers.length < 10)
			{
             myPlacemark = new ymaps.Placemark([coords[0].toPrecision(6),coords[1].toPrecision(6)], {
                    // Свойства
                    // Текст метки
                    iconContent: ch
                }, {
                    // Опции
                    // Иконка метки будет растягиваться под ее контент
                    preset: 'twirl#blueStretchyIcon'
                });     
 
			 markers.push(myPlacemark);
			 myMap.geoObjects.add(myPlacemark);
			 ch++;
			 }
			 else
			 {
			 alert("Вы задали максимальное количество точек");
			 }
            });				
 
        }
 
		function calcRoute() {		
		for(var i = 0, l = markers.length; i < l; i++) {
				point[i] = markers[i].geometry.getCoordinates();
			}
 
            ymaps.route(point, {
                // Опции маршрутизатора
                mapStateAutoApply: true // автоматически позиционировать карту
            }).then(function (router) {
 
				route = router;
                myMap.geoObjects.add(route);
            }, function (error) {
                alert("Возникла ошибка: " + error.message);
            });		
		}
 
		//Удаление маршрута и меток с карты и очистка данных
		function reset() {
			route && myMap.geoObjects.remove(route);
			for(var i = 0, l = markers.length; i < l; i++) {
				myMap.geoObjects.remove(markers[i]);
			}
			markers = []; 
			point = [];
			ch = 1;
		}
 
 
    </script>
</head>
 
<body>
 
<div id="map" style="width:800px; height:600px"></div>
<input type="button" value="Построить маршрут" onclick="calcRoute()" />
<input type="button" value="Очистить" onclick="reset()" />
 
</body>
</html>

В самом начале мы определяем глобальные переменные для карты — myMap, маршрута — route, счетчик для нумерации меток, массивов для меток markers и точек маршрута point.

После этого определяем начальные параметры карты и добавляем на нее необходимые элементы управления.

Затем мы пишем код для отслеживания события клика по карте.

myMap.events.add('click', function (e) {                
            var coords = e.get('coordPosition');
			if(markers.length < 10)
			{
             myPlacemark = new ymaps.Placemark([coords[0].toPrecision(6),coords[1].toPrecision(6)], {
                    // Свойства
                    // Текст метки
                    iconContent: ch
                }, {
                    // Опции
                    // Иконка метки будет растягиваться под ее контент
                    preset: 'twirl#blueStretchyIcon'
                });     
 
			 markers.push(myPlacemark);
			 myMap.geoObjects.add(myPlacemark);
			 ch++;
			 }
			 else
			 {
			 alert("Вы задали максимальное количество точек");
			 }
            });

При каждом клике, мы добавляем метку на карту и заносим ее в массив markers.

Проверяем общее количество меток, оно должно быть меньше 10.

После нажатия на кнопку «Построить маршрут», вызывается функция calcRoute для построения маршрута.

Когда мы нажимаем кнопку «Очистить», вызывается функция reset в которой, удаляется маршрут с карты и метки.

Также обнуляются массивы для хранения меток и точек на карте.

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

  • Гость: Чудненько. Спасибо! Проблемка: Кнопка "Очистить" удаляет только последний маршрут(из двух(как мин.) маршрутов).
  • Гость: На карте можно рисовать одновременно только один маршрут, а после нажимать «Очистить».
  • Гость: &lt;!-- Евгений 9 июля 2012 в 10:48 Чудненько. Спасибо! Проблемка: Кнопка «Очистить» удаляет только последний маршрут(из двух(как мин.) маршрутов). admin 11 июля 2012 в 22:23 На карте можно рисовать одновременно только один маршрут, а после нажимать «Очистить». -------------------------------------- Здесь, наверно, Евгений, также как и я, столкнулся с следующей ситуацией: Метки расставлены и маршрут проложен. Ставим ещё метки и нажимаем &quot;Построить маршрут&quot; и ещё так несколько раз. Происходит построение ещё нескольких маршрутов, но &quot;Очистить&quot; можно только результат с последними установленными метками. Остальные маршруты убираются с карты только после перезагрузки страницы. ---------------- Большое спасибо за статью!
  • Гость: Я проблему с очисткой нескольких маршрутов решил таким образом, добавил после: function calcRoute() { строку if(route) myMap.geoObjects.remove(route); перед построением нового маршрута проверяет были ли уже проложены старые и удаляет если да ------------------------- У меня вопрос следующий, добавил к карте TrafficControl и теперь по клику на улицу где отображается трафик не ставится точка, а показывается состояние этой улицы трафикконтролом ( по сути он перехватывает событие ). Как решить эту проблему? Ряд событий с трафикконтрола надо оставить ( такие как "показывать дорожные события" и т.п.) Добавленный мной код: .add(new ymaps.control.TrafficControl({providerKey: 'traffic#actual', shown: true, infoLayerShown: false, expanded:false}), { right: 0, top: 75 })
  • Гость: Добрый день! Спасибо за хороший пример. Подскажите пожалуйста как можно сохранить проложенный маршрут на сервисе Мои карты или на YMapsML xml файле своем?
  • Гость: Нет
  • Гость: Здравствуйте! Скажите, пожалуйста, почему в момент построения маршрута появляются дубликаты меток? Как этого можно избежать в данном примере?
  • Алексей Дементьев: Здравствуйте, помогите сделать так. Нужно что бы 1 точка уже была при загрузке карты, а вторую точку ставит пользователь и прокладывается маршрут. Как это реализовать ?
  • Вадим: Добрый день! Отличные примеры, спасибо за проделанную работу! Сделал на сайте прокладывание маршрутов, все работало до недавнего времени. Сейчас появляется ошибка "Возникла ошибка: rll parameter malformed" Подскажите в чем может быть проблема?
  • Гость: то же самое..работало ,а теперь ошибка "Возникла ошибка: rll parameter malformed"
  • Гость: нашел...надо исправить передачу параметров start и end надо убрать кваратные скобки, должно остаться так ..... ymaps.route([start, end], {........ ......
  • Вадим: Мне не помогло Убрал скобки, все без изменений, ошибка выскакивает
  • Сашка Рукавишников: помогло, спасибо
  • Гость: тоже помогло, спасибо!
  • Алексей Спесивцев: Не помогло... вместо rll parameter malformed пишет can't consruct route
  • Александр Зеленогорский: Очень странно. Один помогло - другим нет. Если прописать начальную и конечную точки, то все работает. Например: ..... ymaps.route(['Москва', 'Красноярск'], {........ ...... Кто знает как исправить ошибку, помогите пожалуйста!
  • Александр Зеленогорский: Ура!!! Разобрался!!! Этот код: --------------------------------- ymaps.route([ [start], [end]], { mapStateAutoApply: true, }).then(function (router) { --------------------------------- заменить на этот --------------------------------- ymaps.route([start, end], {mapStateAutoApply: true,}) .then(function (router) { ---------------------------------
  • Гость: как вывести расчет расстояний между точками?
  • Alexandr Malinin: Подскажите, а как определить расстояние не по прямой, а по проложенному маршруту? А лучше, вообще просто между двумя заданными парами координат, но тоже по маршруту
  • Гость: У меня есть карта здания одноэтажного в png, создав тайлы, т.е создав свою карту на яндекс. Могу ли я там прокладывать маршруты от комнаты до комнаты?