Yandex API создает 2 разных маршрута по одному адресу
Работаю над функционалом расчета стоимости доставки. В пределах КАД фиксированная стоимость, а за его пределами тарифная за каждый километр. По примерам из Яндекс песочницы, соединил в один скрипт 2 варианта :
- https://yandex.ru/dev/maps/jsbox/2.1/deliveryCalculator
- https://yandex.ru/dev/maps/jsbox/2.1/route_inside_polygon
Логика скрипта должна была быть следующая:
Из поля адрес пользователем вводится адрес, и создается маршрут от склада до введенного адреса. Далее скрипт разбивает этот маршрут на отрезки и красит их в зависимости от нахождения в полигоне. Далее, если введенный адрес находится за пределами КАД, то находим координаты, где заканчивается КАД и координаты адреса. Начинаем расчет длины пути от этих двух координат.
И вот вроде бы работает, но почему-то не проходит проверка, чтобы отрисовать путь, если адрес введен в пределах КАД, и по некоторым адресам отображается 2 разных маршрута. Как так получается, и как это исправить?
ymaps.ready(init);
function init() {
var DELIVERY_TARIFF = 40,
MINIMUM_COST = 1200,
suggestView1 = new ymaps.SuggestView('delivery_adress', {
results: 5
}),
routeTo,
myMap = new ymaps.Map("map", {
center: [59.941574, 30.347597],
zoom: 9,
controls: []
}),
routePanelControl = new ymaps.control.RoutePanel({
options: {
// Добавим заголовок панели.
showHeader: false,
title: 'Расчёт доставки',
visible: false
}
}),
zoomControl = new ymaps.control.ZoomControl({
options: {
size: 'small',
float: 'none',
position: {
bottom: 145,
right: 10
}
}
}),
finalRouteStart,
finalRouteEnd,
finalRoute,
kadPolygon;
suggestView1.events.add("select", function(e) {
routeTo = e.get('item').value;
$.ajax({
url: '/wp-content/themes/shablon/kad.json',
dataType: 'json',
success: onPolygonLoad
});
})
// Пользователь сможет построить только автомобильный маршрут.
myMap.controls.add(routePanelControl).add(zoomControl);
function onPolygonLoad (json) {
myMap.geoObjects.removeAll();
kadPolygon = new ymaps.Polygon(json.coordinates);
// Если мы не хотим, чтобы контур был виден, зададим соответствующую опцию.
kadPolygon.options.set('visible', false);
// Чтобы корректно осуществлялись геометрические операции
// над спроецированным многоугольником, его нужно добавить на карту.
myMap.geoObjects.add(kadPolygon);
routePanelControl.routePanel.options.set({
types: {auto: false}
});
ymaps.route([[59.963499,30.463677], routeTo]).then(
function (res) {
// Объединим в выборку все сегменты маршрута.
var pathsObjects = ymaps.geoQuery(res.getPaths()),
edges = [];
// Переберем все сегменты и разобьем их на отрезки.
pathsObjects.each(function (path) {
var coordinates = path.geometry.getCoordinates();
for (var i = 1, l = coordinates.length; i < l; i++) {
edges.push({
type: 'LineString',
coordinates: [coordinates[i], coordinates[i - 1]]
});
}
});
// Создадим новую выборку, содержащую:
// - отрезки, описываюшие маршрут;
// - начальную и конечную точки;
// - промежуточные точки.
var routeObjects = ymaps.geoQuery(edges)
.add(res.getWayPoints())
.add(res.getViaPoints())
.setOptions('strokeWidth', 4)
.addToMap(myMap),
// Найдем все объекты, попадающие внутрь КАД.
objectsInPiter = routeObjects.searchInside(kadPolygon),
// Найдем объекты, пересекающие КАД.
boundaryObjects = routeObjects.searchIntersect(kadPolygon);
// Раскрасим в разные цвета объекты внутри, снаружи и пересекающие КАД.
boundaryObjects.setOptions({
strokeColor: '#06ff00',
preset: 'islands#greenIcon'
});
objectsInPiter.setOptions({
strokeColor: '#ff0005',
preset: 'islands#redIcon'
});
// Объекты за пределами КАД получим исключением полученных выборок из
// исходной.
routeObjects.remove(objectsInPiter).remove(boundaryObjects).setOptions({
strokeColor: '#000000',
preset: 'islands#blueIcon'
});
finalRoute = routeObjects.remove(objectsInPiter).remove(boundaryObjects),
finalRouteStart = finalRoute.get(0).geometry.get(1),
finalRouteEnd = finalRoute.get(finalRoute.getLength() - 1).geometry.getCoordinates();
if (routeObjects.getLength() == objectsInPiter.getLength()) {
console.log('Попал в функцию InKAD');
getDistanceInKAD();
} else {
console.log('Попал в функцию OutKAD');
getDistanceOutKAD();
}
}
);
function getDistanceOutKAD() {
routePanelControl.routePanel.state.set({
fromEnabled: false,
from: finalRouteStart,
to: finalRouteEnd
});
routePanelControl.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"),
// Вычислим стоимость доставки.
price = calculate(Math.round(length.value / 1000)),
// Создадим макет содержимого балуна маршрута.
balloonContentLayout = ymaps.templateLayoutFactory.createClass(
'<span>Расстояние: ' + length.text + '.</span><br/>' +
'<span style="font-weight: bold; font-style: italic">Стоимость доставки: ' + price + ' р.</span>');
// Зададим этот макет для содержимого балуна.
route.options.set('routeBalloonContentLayout', balloonContentLayout);
// Откроем балун.
activeRoute.balloon.open();
}
});
});
function calculate(routeLength) {
return Math.max(routeLength * DELIVERY_TARIFF + MINIMUM_COST);
}
}
function getDistanceInKAD() {
routePanelControl.routePanel.state.set({
fromEnabled: false,
from: 'Санкт-Петербург Шоссе Революции 88 Ж',
to: routeTo
});
routePanelControl.routePanel.getRouteAsync().then(function (route) {
// Зададим максимально допустимое число маршрутов, возвращаемых мультимаршрутизатором.
route.model.setParams({results: 1}, true);
// Повесим обработчик на событие построения маршрута.
route.model.events.add('requestsuccess', function () {
var activeRoute = route.getActiveRoute();
if (activeRoute) {
// Вычислим стоимость доставки.
var price = 1200,
// Создадим макет содержимого балуна маршрута.
balloonContentLayout = ymaps.templateLayoutFactory.createClass(
'<span style="font-weight: bold; font-style: italic">Стоимость доставки: ' + price + ' р.</span>');
// Зададим этот макет для содержимого балуна.
route.options.set('routeBalloonContentLayout', balloonContentLayout);
// Откроем балун.
activeRoute.balloon.open();
}
});
});
}
/*уmaps.route([finalRouteStart, finalRouteEnd]).then(function (route){
var distance = Math.round(route.getLength() / 1000);
console.log(distance);
})*/
}
}
