Проверка адреса на попадание в зону доставки

Open in CodeSandbox

В примере показано, как проверить адрес на попадание в зону доставки. Проверяются адрес, введенный пользователем, а также его местоположение. Зоны доставки экспортируются из Конструктора Карт.

При клике по зоне доставки отображается контактная информация и стоимость доставки в этой зоне. Когда пользователь вводит адрес или нажимает на значок геолокации, выполняется проверка на попадание адреса в одну из зон доставки. Для проверки используется функция searchContaining(). Если введенный адрес попадает в зону доставки, метка перекрашивается в цвет этой зоны, а в балун добавляется стоимость доставки. Если адрес не попадает ни в одну из зон, метка окрашивается в черный цвет.

  <!DOCTYPE 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;coordorder=longlat&amp;apikey=<ваш API-ключ>" type="text/javascript"></script>
    <script src="delivery_zones.js" type="text/javascript"></script>
    <script type="text/javascript" src="https://yandex.st/jquery/2.2.3/jquery.js"></script>
    <style type="text/css">
        html, body, #map {
            width: 100%;
            height: 100%;
            padding: 0;
            margin: 0;
        }
    </style>
</head>
<body>
<div id="map"></div>
</body>
</html>
ymaps.ready(init);

function init() {
    var myMap = new ymaps.Map("map", {
            center: [30.264981955459618, 59.9567962610097],
            zoom: 9,
            controls: ["geolocationControl", "searchControl"],
        }),
        deliveryPoint = new ymaps.GeoObject(
            {
                geometry: { type: "Point" },
                properties: { iconCaption: "Адрес" },
            },
            {
                preset: "islands#blackDotIconWithCaption",
                draggable: true,
                iconCaptionMaxWidth: "215",
            }
        ),
        searchControl = myMap.controls.get("searchControl");
    searchControl.options.set({
        noPlacemark: true,
        placeholderContent: "Введите адрес доставки",
    });
    myMap.geoObjects.add(deliveryPoint);

    function onZonesLoad(json) {
        // Добавляем зоны на карту.
        var deliveryZones = ymaps.geoQuery(json).addToMap(myMap);
        // Задаём цвет и контент балунов полигонов.
        deliveryZones.each(function (obj) {
            obj.options.set({
                fillColor: obj.properties.get("fill"),
                fillOpacity: obj.properties.get("fill-opacity"),
                strokeColor: obj.properties.get("stroke"),
                strokeWidth: obj.properties.get("stroke-width"),
                strokeOpacity: obj.properties.get("stroke-opacity"),
            });
            obj.properties.set(
                "balloonContent",
                obj.properties.get("description")
            );
        });

        // Проверим попадание результата поиска в одну из зон доставки.
        searchControl.events.add("resultshow", function (e) {
            highlightResult(
                searchControl.getResultsArray()[e.get("index")]
            );
        });

        // Проверим попадание метки геолокации в одну из зон доставки.
        myMap.controls
            .get("geolocationControl")
            .events.add("locationchange", function (e) {
                highlightResult(e.get("geoObjects").get(0));
            });

        // При перемещении метки сбрасываем подпись, содержимое балуна и перекрашиваем метку.
        deliveryPoint.events.add("dragstart", function () {
            deliveryPoint.properties.set({
                iconCaption: "",
                balloonContent: "",
            });
            deliveryPoint.options.set("iconColor", "black");
        });

        // По окончании перемещения метки вызываем функцию выделения зоны доставки.
        deliveryPoint.events.add("dragend", function () {
            highlightResult(deliveryPoint);
        });

        function highlightResult(obj) {
            // Сохраняем координаты переданного объекта.
            var coords = obj.geometry.getCoordinates(),
                // Находим полигон, в который входят переданные координаты.
                polygon = deliveryZones.searchContaining(coords).get(0);

            if (polygon) {
                // Уменьшаем прозрачность всех полигонов, кроме того, в который входят переданные координаты.
                deliveryZones.setOptions("fillOpacity", 0.4);
                polygon.options.set("fillOpacity", 0.8);
                // Перемещаем метку с подписью в переданные координаты и перекрашиваем её в цвет полигона.
                deliveryPoint.geometry.setCoordinates(coords);
                deliveryPoint.options.set(
                    "iconColor",
                    polygon.properties.get("fill")
                );
                // Задаем подпись для метки.
                if (typeof obj.getThoroughfare === "function") {
                    setData(obj);
                } else {
                    // Если вы не хотите, чтобы при каждом перемещении метки отправлялся запрос к геокодеру,
                    // закомментируйте код ниже.
                    ymaps
                        .geocode(coords, { results: 1 })
                        .then(function (res) {
                            var obj = res.geoObjects.get(0);
                            setData(obj);
                        });
                }
            } else {
                // Если переданные координаты не попадают в полигон, то задаём стандартную прозрачность полигонов.
                deliveryZones.setOptions("fillOpacity", 0.4);
                // Перемещаем метку по переданным координатам.
                deliveryPoint.geometry.setCoordinates(coords);
                // Задаём контент балуна и метки.
                deliveryPoint.properties.set({
                    iconCaption: "Доставка транспортной компанией",
                    balloonContent: "Cвяжитесь с оператором",
                    balloonContentHeader: "",
                });
                // Перекрашиваем метку в чёрный цвет.
                deliveryPoint.options.set("iconColor", "black");
            }

            function setData(obj) {
                var address = [
                    obj.getThoroughfare(),
                    obj.getPremiseNumber(),
                    obj.getPremise(),
                ].join(" ");
                if (address.trim() === "") {
                    address = obj.getAddressLine();
                }
                var price = polygon.properties.get("description");
                price = price.match(/<strong>(.+)<\/strong>/)[1];
                deliveryPoint.properties.set({
                    iconCaption: address,
                    balloonContent: address,
                    balloonContentHeader: price,
                });
            }
        }
    }

    $.ajax({
        url: "data.geojson",
        dataType: "json",
        success: onZonesLoad,
    });
}