Пересечение маршрута с многоугольником на примере МКАД

Open in CodeSandbox

Часто возникает задача проложить маршрут между заданными точками, а затем проанализировать, в какие области или города попадают сегменты этого маршрута. В данном примере по заранее подготовленным данным создается многоугольник, описывающий МКАД. После получения маршрута делается проверка на попадание его сегментов в этот многоугольник с помощью метода searchInside.

С помощью объекта GeoQueryResult можно задавать опции или данные сразу группе геообъектов. Здесь показано, как сегменты маршрута, лежащие внутри и снаружи кольцевой автодороги, раскрашиваются в разные цвета.

<!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&amp;apikey=<ваш API-ключ>"
            type="text/javascript"
        ></script>
        <script
            type="text/javascript"
            src="https://yandex.st/jquery/2.2.3/jquery.js"
        ></script>
        <script
            src="route_inside_polygon.js"
            type="text/javascript"
        ></script>
        <style>
            body,
            html {
                font-family: Arial;
                font-size: 11pt;
                padding: 0;
                margin: 0;
                width: 100%;
                height: 95%;
            }
            p {
                padding: 10px;
            }
            #map {
                width: 100%;
                height: 90%;
            }
        </style>
    </head>
    <body>
        <p>Маршрут внутри МКАД помечен красным, снаружи - синим</p>
        <div id="map"></div>
    </body>
</html>
ymaps.ready(init);

function init() {
    var myMap = new ymaps.Map(
            "map",
            {
                center: [55.73, 37.75],
                zoom: 9,
            },
            {
                searchControlProvider: "yandex#search",
            }
        ),
        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.9761],
            ])
            .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: "moscow.json",
        dataType: "json",
        success: onPolygonLoad,
    });
}