Работа с данными и событиями модели мультимаршрута
В данном примере для модели добавленного на карту мультимаршрута мы создаем еще одно пользовательское отображение. Данное отображение выводит краткое текстовое описание мультимаршурта и реагирует на изменение состояния модели. Пример иллюстрирует работу с событиями и данными модели мультимаршрута.
index.html
custom_view.js
multiroute_data_access.js
<!DOCTYPE html>
<html>
<head>
<title>Работа с данными и событиями модели мультимаршрута</title>
<meta
http-equiv="Content-Type"
content="text/html; charset=utf-8"
/>
<script
src="https://yandex.st/jquery/2.2.3/jquery.min.js"
type="text/javascript"
></script>
<!--
Укажите свой API-ключ. Тестовый ключ НЕ БУДЕТ работать на других сайтах.
Получить ключ можно в Кабинете разработчика: https://developer.tech.yandex.ru/keys/
-->
<script
src="https://api-maps.yandex.ru/2.1/?lang=ru_RU&apikey=<ваш API-ключ>"
type="text/javascript"
></script>
<script src="custom_view.js" type="text/javascript"></script>
<script
src="multiroute_data_access.js"
type="text/javascript"
></script>
<style>
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#map {
width: 95%;
height: 50%;
}
#viewContainer {
margin: 8px;
}
</style>
</head>
<body>
<div id="map"></div>
<div id="viewContainer"></div>
</body>
</html>
ymaps.modules.define(
"MultiRouteCustomView",
["util.defineClass"],
function (provide, defineClass) {
// Класс простого текстового отображения модели мультимаршрута.
function CustomView(multiRouteModel) {
this.multiRouteModel = multiRouteModel;
// Объявляем начальное состояние.
this.state = "init";
this.stateChangeEvent = null;
// Элемент, в который будет выводиться текст.
this.outputElement =
$("<div></div>").appendTo("#viewContainer");
this.rebuildOutput();
// Подписываемся на события модели, чтобы
// обновлять текстовое описание мультимаршрута.
multiRouteModel.events.add(
["requestsuccess", "requestfail", "requestsend"],
this.onModelStateChange,
this
);
}
// Таблица соответствия идентификатора состояния имени его обработчика.
CustomView.stateProcessors = {
init: "processInit",
requestsend: "processRequestSend",
requestsuccess: "processSuccessRequest",
requestfail: "processFailRequest",
};
// Таблица соответствия типа маршрута имени его обработчика.
CustomView.routeProcessors = {
driving: "processDrivingRoute",
masstransit: "processMasstransitRoute",
pedestrian: "processPedestrianRoute",
};
defineClass(CustomView, {
// Обработчик событий модели.
onModelStateChange: function (e) {
// Запоминаем состояние модели и перестраиваем текстовое описание.
this.state = e.get("type");
this.stateChangeEvent = e;
this.rebuildOutput();
},
rebuildOutput: function () {
// Берем из таблицы обработчик для текущего состояния и исполняем его.
var processorName = CustomView.stateProcessors[this.state];
this.outputElement.html(
this[processorName](
this.multiRouteModel,
this.stateChangeEvent
)
);
},
processInit: function () {
return "Инициализация ...";
},
processRequestSend: function () {
return "Запрос данных ...";
},
processSuccessRequest: function (multiRouteModel, e) {
var routes = multiRouteModel.getRoutes(),
result = ["Данные успешно получены."];
if (routes.length) {
result.push("Всего маршрутов: " + routes.length + ".");
for (var i = 0, l = routes.length; i < l; i++) {
result.push(this.processRoute(i, routes[i]));
}
} else {
result.push("Нет маршрутов.");
}
return result.join("<br/>");
},
processFailRequest: function (multiRouteModel, e) {
return e.get("error").message;
},
processRoute: function (index, route) {
// Берем из таблицы обработчик для данного типа маршрута и применяем его.
var processorName =
CustomView.routeProcessors[
route.properties.get("type")
];
return index + 1 + ". " + this[processorName](route);
},
processDrivingRoute: function (route) {
var result = ["Автомобильный маршрут."];
result.push(this.createCommonRouteOutput(route));
return result.join("<br/>");
},
processMasstransitRoute: function (route) {
var result = ["Маршрут на общественном транспорте."];
result.push(this.createCommonRouteOutput(route));
result.push(
"Описание маршута: <ul>" +
this.createMasstransitRouteOutput(route) +
"</ul>"
);
return result.join("<br/>");
},
processPedestrianRoute: function (route) {
var result = ["Пешеходный маршрут."];
result.push(this.createCommonRouteOutput(route));
return result.join("<br/>");
},
// Метод, формирующий общую часть описания для всех типов маршрутов.
createCommonRouteOutput: function (route) {
return (
"Протяженность маршрута: " +
route.properties.get("distance").text +
"<br/>" +
"Время в пути: " +
route.properties.get("duration").text
);
},
// Метод, строящий список текстовых описаний для
// всех сегментов маршрута на общественном транспорте.
createMasstransitRouteOutput: function (route) {
var result = [];
for (var i = 0, l = route.getPaths().length; i < l; i++) {
var path = route.getPaths()[i];
for (
var j = 0, k = path.getSegments().length;
j < k;
j++
) {
result.push(
"<li>" +
path
.getSegments()
[j].properties.get("text") +
"</li>"
);
}
}
return result.join("");
},
destroy: function () {
this.outputElement.remove();
this.multiRouteModel.events.remove(
["requestsuccess", "requestfail", "requestsend"],
this.onModelStateChange,
this
);
},
});
provide(CustomView);
}
);
function init() {
// Создаем модель мультимаршрута.
var multiRouteModel = new ymaps.multiRouter.MultiRouteModel(
[[55.734876, 37.59308], "Москва, ул. Мясницкая"],
{
// Путевые точки можно перетаскивать.
// Маршрут при этом будет перестраиваться.
wayPointDraggable: true,
boundsAutoApply: true,
}
),
// Создаём выпадающий список для выбора типа маршрута.
routeTypeSelector = new ymaps.control.ListBox({
data: {
content: "Как добраться",
},
items: [
new ymaps.control.ListBoxItem({
data: { content: "Авто" },
state: { selected: true },
}),
new ymaps.control.ListBoxItem({
data: { content: "Общественным транспортом" },
}),
new ymaps.control.ListBoxItem({
data: { content: "Пешком" },
}),
],
options: {
itemSelectOnClick: false,
},
}),
// Получаем прямые ссылки на пункты списка.
autoRouteItem = routeTypeSelector.get(0),
masstransitRouteItem = routeTypeSelector.get(1),
pedestrianRouteItem = routeTypeSelector.get(2);
// Подписываемся на события нажатия на пункты выпадающего списка.
autoRouteItem.events.add("click", function (e) {
changeRoutingMode("auto", e.get("target"));
});
masstransitRouteItem.events.add("click", function (e) {
changeRoutingMode("masstransit", e.get("target"));
});
pedestrianRouteItem.events.add("click", function (e) {
changeRoutingMode("pedestrian", e.get("target"));
});
ymaps.modules.require(
["MultiRouteCustomView"],
function (MultiRouteCustomView) {
// Создаем экземпляр текстового отображения модели мультимаршрута.
// см. файл custom_view.js
new MultiRouteCustomView(multiRouteModel);
}
);
// Создаем карту с добавленной на нее кнопкой.
var myMap = new ymaps.Map(
"map",
{
center: [55.750625, 37.626],
zoom: 7,
controls: [routeTypeSelector],
},
{
buttonMaxWidth: 300,
}
),
// Создаем на основе существующей модели мультимаршрут.
multiRoute = new ymaps.multiRouter.MultiRoute(multiRouteModel, {
// Путевые точки можно перетаскивать.
// Маршрут при этом будет перестраиваться.
wayPointDraggable: true,
boundsAutoApply: true,
});
// Добавляем мультимаршрут на карту.
myMap.geoObjects.add(multiRoute);
function changeRoutingMode(routingMode, targetItem) {
multiRouteModel.setParams({ routingMode: routingMode }, true);
// Отменяем выбор элементов.
autoRouteItem.deselect();
masstransitRouteItem.deselect();
pedestrianRouteItem.deselect();
// Выбираем элемент и закрываем список.
targetItem.select();
routeTypeSelector.collapse();
}
}
ymaps.ready(init);