Расчёт длины маршрута Yandex Maps по примеру из песочницы

Рейтинг: 2Ответов: 2Опубликовано: 20.04.2015

Никак не пойму, как можно имея объект типа GeoQueryResult, получить длину маршрута в метрах. Пробовал с объекта objectsInMoscow методом each собирать все координаты точек, и создавать объект типа polyline (а у него уже работает метод polyline.geometry.getDistance()), но ничего хорошего из этого не вышло, потому что по непонятным мне причинам, эта полилиния соединяла конец с началом, и длина маршрута считалась как у замкнутого кольца.

ymaps.ready(init);

function init() {
    var myMap = new ymaps.Map("map", {
            center: [55.73, 37.75],
            zoom: 9
        }),
        moscowPolygon;
    
    function onPolygonLoad (json) {
        moscowPolygon = new ymaps.Polygon(json.coordinates);
        // Если мы не хотим, чтобы контур был виден, зададим соответствующую опцию.
        moscowPolygon.options.set('visible', false);
        // Чтобы корректно осуществлялись геометрические операции
        // над спроецированным многоугольником, его нужно добавить на карту.
        myMap.geoObjects.add(moscowPolygon);
        
        ymaps.route([[55.654884,37.527034], [55.767305,37.976100]]).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', 3)
                        .addToMap(myMap),
                    // Найдем все объекты, попадающие внутрь МКАД.
                    objectsInMoscow = routeObjects.searchInside(moscowPolygon),
                    // Найдем объекты, пересекающие МКАД.
                    boundaryObjects = routeObjects.searchIntersect(moscowPolygon);
                // Раскрасим в разные цвета объекты внутри, снаружи и пересекающие МКАД.
                boundaryObjects.setOptions({
                    strokeColor: '#06ff00',
                    preset: 'islands#greenIcon'
                });
                objectsInMoscow.setOptions({
                    strokeColor: '#ff0005',
                    preset: 'islands#redIcon'
                });
                // Объекты за пределами МКАД получим исключением полученных выборок из
                // исходной.
                routeObjects.remove(objectsInMoscow).remove(boundaryObjects).setOptions({
                    strokeColor: '#0010ff',
                    preset: 'islands#blueIcon'
                });
            }
        );
    }
    
    $.ajax({
        url: '//sandbox.api.maps.yandex.net/examples/ru/2.1/route_inside_polygon/moscow.json',
        dataType: 'json',
        success: onPolygonLoad
    });
}
        body, html {
            font-family: Arial;
            font-size: 11pt;
            padding: 0;
            margin: 0;
            width: 100%;
            height: 100%;
        }
        p {
            padding: 10px;
        }
        #map {
            width: 100%;
            height: 80%;
        }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU"></script>
<p>Маршрут внутри МКАД помечен красным, снаружи - синим</p>
    <div id="map"></div>

В примере из песочницы есть три "области" пути - красная, зелёная и синяя. Требуется найти длины маршрутов каждой.

Заранее благодарен.

Ответы

▲ 2

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

var MKADDistance = 0;
var insideMKADDistance = 0;
//объекты "минус" то, что внутри
//a-b
routeObjects.remove(objectsInMoscow).remove(boundaryObjects) 
.each(function (segment, i) 
{
    //есть ли такая фунция
    if (segment.geometry.getDistance != undefined)
        MKADDistance += segment.geometry.getDistance();
});

//то, что внутри
//это как a-(a-b)=b
routeObjects.remove(routeObjects.remove(objectsInMoscow).remove(boundaryObjects))
.each(function (segment, i) 
{
    if (segment.geometry.getDistance != undefined)
        insideMKADDistance += segment.geometry.getDistance();
});

P.S. Извините за плохой код заранее, писал на скорую руку, так как не было времени разбираться. Я уверен, найдутся те, кто перепишет это лучшим способом.

▲ 2

Вы можете добавить на карту все куски маршрута(без дополнительных точек)

var routeObjects = ymaps.geoQuery(edges).addToMap(myMap);
var objectsInMoscow = routeObjects.searchInside(moscowPolygon);

И посчитать их общую длину(сумма длин каждого куска) с помощью метода getDistance:

var dist = 0;
objectsInMoscow.each(function(path) {
    dist += path.geometry.getDistance();
});

console.log(dist / 1000); // dist в метрах

Тоже самое, что написал Karmilin Nikolay, просто без лишнего кода.