маршрут к метке на карте
Не получается выстраивание маршрута к метке при её выборе на карте по примерам в песочнице. Помогите разобраться!!! Другой вопрос: как в балуне сделать адрес метки в виде кнопки для построения маршрута до этой метки от геолокации пользователя?
`
<script type="text/javascript">
ymaps.ready(function () {
var myMap = new ymaps.Map('map', {
center: [59.935,30.416],
zoom: 11,
controls: ['zoomControl', 'typeSelector', 'routeButtonControl']
}, {
searchControlProvider: 'yandex#search'
});
/* var control = myMap.controls.get('routeButtonControl');
// Зададим координаты пункта отправления с помощью геолокации.
control.routePanel.geolocate('from');
// Откроем панель для построения маршрутов.
control.state.set('expanded', true); */
// Создаём макет содержимого.
MyIconContentLayout = ymaps.templateLayoutFactory.createClass(
'<div style="color: #FFFFFF; font-weight: bold;">$[properties.iconContent]</div>'
),
myPlacemark1 = new ymaps.Placemark([59.60,30.30], {
hintContent: 'Тех. Центр ”Садовая”',
balloonContentHeader: "Тех. Центр ”Садовая”",
balloonContentBody: '<img src="images/icon.png" height="150" width="200"> <br/> ' +
'<a href="tel:+7 (111) 123-45-67"><b>+7 (111) 123-45-67</b></a><br/>' +
'<b>Санкт-Петербург, ул. Садовая 2</b><br/>',
balloonContentFooter: "Ежедневно с 9:00 до 20:00",
}, {
// Опции.
// Необходимо указать данный тип макета.
iconLayout: 'default#image',
// Своё изображение иконки метки.
iconImageHref: 'images/icon.png',
// Размеры метки.
iconImageSize: [96, 61],
// Смещение левого верхнего угла иконки относительно
// её "ножки" (точки привязки).
iconImageOffset: [-48, -61]
}),
myPlacemark2 = new ymaps.Placemark([59.80,30.40], {
hintContent: 'Тех. Центр ”Б. Морская”',
balloonContentHeader: "Тех. Центр ”Б. Морская”",
balloonContentBody: '<img src="images/icon.png" height="150" width="200"> <br/> ' +
'<a href="tel:+7 (111) 123-45-68"><b>+7 (111) 123-45-68</b></a><br/>' +
'<b>Санкт-Петербург, ул. Б. Морская 11</b><br/>',
balloonContentFooter: "Ежедневно с 9:00 до 20:00",
}, {
// Опции.
// Необходимо указать данный тип макета.
iconLayout: 'default#image',
// Своё изображение иконки метки.
iconImageHref: 'images/icon.png',
// Размеры метки.
iconImageSize: [96, 61],
// Смещение левого верхнего угла иконки относительно
// её "ножки" (точки привязки).
iconImageOffset: [-48, -61]
});
myMap.geoObjects
.add(myPlacemark1)
.add(myPlacemark2);
});
</script>`
НО, как вишенка на торте... ... предполагаю, лучше сделать так, что бы: 1. балун сворачивался при открытии "Маршрутной панели", 2. где-то по траектории маршрута указывалось онлайн-продолжительность поездки и/или прибытия к выбранной метке 3. и в случае с мобильной версией необходимо предложение открытия/загрузки Яндекс.Навигатора, а не Яндекс.Карт. На этом я бы "Сказку о Золотой рыбке" завершил ТАКОЕ ВОЗМОЖНО???
Ответы (1 шт):
Примеры в песочнице:
- кнопка в балуне: https://tech.yandex.ru/maps/jsbox/2.1/placemark_balloon_layout
- задание активной области макету метки: https://tech.yandex.ru/maps/jsbox/2.1/placemark_shape
- события гообъектов: https://tech.yandex.ru/maps/jsbox/2.1/event_properties
- маршрут от местоположения пользователя: https://tech.yandex.ru/maps/jsbox/2.1/geolocated_multiroute
- информация о расстоянии и времени в пути: https://tech.yandex.ru/maps/jsbox/2.1/deliveryCalculator
Еще может быть полезным почитать про макеты и шаблоны: https://tech.yandex.ru/maps/jsapi/doc/2.1/dg/concepts/layouts-docpage/ https://tech.yandex.ru/maps/jsapi/doc/2.1/ref/reference/Template-docpage/
В итоге у меня получилось вот так: https://jsfiddle.net/naivv/0gvztauk/
Теперь балун с кнопкой сворачивается и выводится новый балун - с информацией о расстоянии и времени в пути.
Что касается вопроса о мобильной версии - кажется, это уже не совсем JS API. Полагаю, начинать нужно отсюда: https://yandex.ru/dev/yandex-apps-launch/maps/doc/concepts/About-docpage/ (есть ограничения: https://yandex.ru/dev/yandex-apps-launch/maps/doc/concepts/yandexmaps-commercial-use-docpage/ - лучше спросить у техподдержки).
ymaps.ready(init);
function init() {
var myMap = new ymaps.Map('map', {
center: [59.7, 30.4],
zoom: 11,
// Добавим панель маршрутизации.
controls: ['zoomControl', 'typeSelector', 'routeButtonControl']
}, {
searchControlProvider: 'yandex#search'
});
var control = myMap.controls.get('routeButtonControl');
// Создаём макет содержимого.
MyIconContentLayout = ymaps.templateLayoutFactory.createClass(
'<div style="color: #FFFFFF; font-weight: bold;">$[properties.iconContent]</div>'
);
// Создание макета содержимого балуна.
// Макет создается с помощью фабрики макетов с помощью текстового шаблона.
MyBalloonContentLayout = ymaps.templateLayoutFactory.createClass(
// https://tech.yandex.ru/maps/jsapi/doc/2.1/ref/reference/Template-docpage/
'<div style="margin: 10px;">' +
'<h3>{{properties.balloonContentHeader|raw}}</h3>' +
'<div class="popover-content">{{properties.balloonContentBody|raw}}</div>' +
'<br />' +
'<button id="counter-button"><b>{{properties.myAddr}}</b></button>' +
'<br />' +
'<h5>{{properties.balloonContentFooter}}</h5>' +
'</div>', {
// Переопределяем функцию build, чтобы при создании макета начинать
// слушать событие click на кнопке-счетчике.
build: function() {
// Сначала вызываем метод build родительского класса.
MyBalloonContentLayout.superclass.build.call(this);
// А затем выполняем дополнительные действия.
//console.log(this);
$('#counter-button').bind('click', this.onCounterClick);
},
// Аналогично переопределяем функцию clear, чтобы снять
// прослушивание клика при удалении макета с карты.
clear: function() {
// Выполняем действия в обратном порядке - сначала снимаем слушателя,
// а потом вызываем метод clear родительского класса.
//console.log(this);
$('#counter-button').unbind('click', this.onCounterClick);
MyBalloonContentLayout.superclass.clear.call(this);
},
onCounterClick: function() {
//console.log($(this).text());
routeTo($(this).text());
}
});
// Создание метки со сложной фигурой активной области
// https://tech.yandex.ru/maps/jsapi/doc/2.1/dg/concepts/layouts-docpage/
var polygonLayout = ymaps.templateLayoutFactory.createClass('<div class="placemark_layout_container"><div class="polygon_layout">1</div></div>');
function routeTo(to) {
// https://tech.yandex.ru/maps/jsbox/2.1/geolocated_multiroute
// Зададим координаты пункта отправления с помощью геолокации.
control.routePanel.geolocate('from');
// Откроем панель для построения маршрутов.
control.state.set('expanded', true);
// https://tech.yandex.ru/maps/jsapi/doc/2.1/ref/reference/control.RouteButton-docpage/
control.routePanel.state.set({
to: to
});
//закроем балун с кнопкой
myMap.balloon.close();
control.routePanel.getRouteAsync().then(function(route) {
// Зададим максимально допустимое число маршрутов, возвращаемых мультимаршрутизатором.
route.model.setParams({
results: 1
}, true);
// Повесим обработчик на событие построения маршрута.
route.model.events.add('requestsuccess', function() {
var activeRoute = route.getActiveRoute();
if (activeRoute) {
// Получим протяженность маршрута.
var length = route.getActiveRoute().properties.get("distance"),
duration = route.getActiveRoute().properties.get("durationInTraffic");
// Создадим макет содержимого балуна маршрута.
balloonContentLayout = ymaps.templateLayoutFactory.createClass(
'<span style="font-weight: bold">Расстояние: ' + length.text + '.</span><br/>' +
'<span style="font-style: italic">Время проезда пути с учетом пробок: ' + duration.text + '</span>');
// Зададим этот макет для содержимого балуна.
route.options.set('routeBalloonContentLayout', balloonContentLayout);
// Откроем балун.
activeRoute.balloon.open();
}
})
})
}
var polygonPlacemark = new ymaps.Placemark(
[59.693409, 30.433196], {
hintContent: 'HTML метка сложной формы'
}, {
iconLayout: polygonLayout,
// Описываем фигуру активной области "Полигон".
iconShape: {
type: 'Polygon',
// Полигон описывается в виде трехмерного массива. Массив верхнего уровня содержит контуры полигона.
// Первый элемента массива - это внешний контур, а остальные - внутренние.
coordinates: [
// Описание внешнего контура полигона в виде массива координат.
[
[-28, -76],
[28, -76],
[28, -20],
[12, -20],
[0, -4],
[-12, -20],
[-28, -20]
]
// , ... Описание внутренних контуров - пустых областей внутри внешнего.
]
}
}
);
// Подпишемся на событие клика
polygonPlacemark.events.add('click', function(e) {
// Получим ссылку на геообъект, по которому кликнул пользователь.
var target = e.get('target');
routeTo(target.geometry.getCoordinates());
});
var myPlacemark1 = new ymaps.Placemark([59.60, 30.30], {
hintContent: 'Тех. Центр ”Садовая”',
myAddr: 'Санкт-Петербург, ул. Садовая 2',
balloonContentHeader: "Тех. Центр ”Садовая”",
balloonContentBody: '<img src="https://sandbox.api.maps.yandex.net/examples/ru/2.1/balloon_html/img/cinema.jpg" height="150" width="200"> <br/> ' +
'<a href="tel:+7 (111) 123-45-67"><b>+7 (111) 123-45-67</b></a><br/>' +
'<b>Санкт-Петербург, ул. Садовая 2</b><br/>',
balloonContentFooter: "Ежедневно с 9:00 до 20:00",
}, {
// Опции.
balloonContentLayout: MyBalloonContentLayout,
// Запретим замену обычного балуна на балун-панель.
// Если не указывать эту опцию, на картах маленького размера откроется балун-панель.
balloonPanelMaxMapArea: 0,
// Не скрываем иконку при открытом балуне.
hideIconOnBalloonOpen: false,
// И дополнительно смещаем балун, для открытия над иконкой.
balloonOffset: [0, -48],
// Необходимо указать данный тип макета.
iconLayout: 'default#image',
// Своё изображение иконки метки.
iconImageHref: 'https://sandbox.api.maps.yandex.net/examples/ru/2.1/icon_customImage/images/ball.png',
// Размеры метки.
iconImageSize: [48, 48],
// Смещение левого верхнего угла иконки относительно
// её "ножки" (точки привязки).
iconImageOffset: [-24, -48]
}),
myPlacemark2 = new ymaps.Placemark([59.80, 30.40], {
hintContent: 'Тех. Центр ”Б. Морская”',
myAddr: 'Санкт-Петербург, ул. Б. Морская 11',
balloonContentHeader: "Тех. Центр ”Б. Морская”",
balloonContentBody: '<img src="https://sandbox.api.maps.yandex.net/examples/ru/2.1/balloon_html/img/cinema.jpg" height="150" width="200"> <br/> ' +
'<a href="tel:+7 (111) 123-45-68"><b>+7 (111) 123-45-68</b></a><br/>' +
'<b>Санкт-Петербург, ул. Б. Морская 11</b><br/>',
balloonContentFooter: "Ежедневно с 9:00 до 20:00",
}, {
// Опции.
balloonContentLayout: MyBalloonContentLayout,
// Запретим замену обычного балуна на балун-панель.
// Если не указывать эту опцию, на картах маленького размера откроется балун-панель.
balloonPanelMaxMapArea: 0,
// Не скрываем иконку при открытом балуне.
hideIconOnBalloonOpen: false,
// И дополнительно смещаем балун, для открытия над иконкой.
balloonOffset: [0, -48],
// Необходимо указать данный тип макета.
// Необходимо указать данный тип макета.
iconLayout: 'default#image',
// Своё изображение иконки метки.
iconImageHref: 'https://sandbox.api.maps.yandex.net/examples/ru/2.1/icon_customImage/images/ball.png',
// Размеры метки.
iconImageSize: [48, 48],
// Смещение левого верхнего угла иконки относительно
// её "ножки" (точки привязки).
iconImageOffset: [-24, -48]
});
myMap.geoObjects
.add(myPlacemark1)
.add(myPlacemark2)
.add(polygonPlacemark);
}
html,
body,
#map {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
.placemark_layout_container {
position: relative;
font-family: Georgia;
font-size: 40px;
text-align: center;
font-weight: bold;
}
/* Макет метки с "хвостиком" */
.polygon_layout {
position: relative;
background: #ffffff;
border: 4px solid #943A43;
width: 50px;
height: 50px;
position: absolute;
left: -28px;
top: -76px;
color: #943A43;
}
.polygon_layout:after,
.polygon_layout:before {
top: 100%;
left: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
}
.polygon_layout:after {
border-top-color: #943A43;
border-width: 10px;
margin-left: -10px;
}
.polygon_layout:before {
border-top-color: #943A43;
border-width: 16px;
margin-left: -16px;
}
<!DOCTYPE html>
<html>
<head>
<title>Маршрут от местоположения пользователя</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!--
Укажите свой API-ключ. Тестовый ключ НЕ БУДЕТ работать на других сайтах.
Получить ключ можно в Кабинете разработчика: https://developer.tech.yandex.ru/keys/
-->
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU&apikey=60445215-6d3a-4f88-87fe-8d52b72e5bc9" type="text/javascript"></script>
<script src="https://yandex.st/jquery/2.2.3/jquery.min.js" type="text/javascript"></script>
<style>
</style>
</head>
<body>
<div id="map"></div>
</body>
</html>