Привет, Хабр!

Думаю, что все знают про YandexAPI, но знать недостаточно, надо применять. Сегодня разберу небольшую задачу, которая заключается в следующем:
-
необходимо создать форму, для ввода адресов точек отправления и прибытия;
-
создать карту и построить маршрут от точки отправления до точки прибытия.
Покажу одну из возможных реализаций на языке JavaScript, создам форму на HTML и приправлю все немножечко Bootstrap v5.
Что необходимо отобразить на странице для выполнения задачи:
-
поле ввода для точки отправления;
-
поле ввода для точки прибытия;
-
кнопку подтверждения отправки формы;
-
область для вывода карты с информацией откуда и куда в виде карточки, где карта располагается сверху, а прочая информация ниже.
Стоит отметить, что API работают только с ключом, который можно получить в личном кабинете разработчика Яндекс, там необходимо оформить бесплатный доступ к «JavaScript API и HTTP Геокодер». Расписывать процесс не буду, там легко разобраться.
Теперь программирование. Форма без применения стилей будет выглядеть посредственно, поэтому покажу конечный вариант с Bootstrap, чтобы не раздувать материал кодом, еще же на JavaScript писать. Реализация формы выглядит следующим образом:
<!DOCTYPE html> <html lang="en"> <head> <title>Задача</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous"> </head> <body> <form id="form" onsubmit="postRequest()"> <p class="text-center">Тестовый образец!</p> <div class="route mb-3 d-flex flex-column"> <label class="form-label"> Откуда: </label> <input id="labelPick" name="pick_up" type="text" class="form-control" onblur="" value="" > <label class="form-label"> Куда: </label> <input id="labelDrop validationServer02" name="drop_to" type="text" class="form-control" onblur="" value="" > </div> <button id="btnRequest" type="submit" class="btn btn-primary" > Submit </button> </form> <div class="containerCards"> <div class="card mb-3"> <div id="mapWay" class="card-img-top" style="width:100%; height:350px;" > </div> <div class="card-body"> <p id="departure" class="card-text"> Откуда: </p> <p id="destination" class="card-text"> Куда: </p> <p class="card-text"> <small class="text-muted"> Дата создания: </small> </p> </div> </div> </div> </body> </html>
В коде можно заметить, что в input стоит метод onblur. Его применение будет вызываться, когда фокус с поля будет снят. Для чего же это необходимо? Для вызова JavaScript, чтобы получить корректный адрес, ведь человек может ошибиться в написании адресов, чтобы избежать это вытащу результат из геокодера предоставляемый API, и заменю на него значение поля ввода.
Так как полей ввода два, то функцию необходимо адаптировать так, чтобы оба поля могли использовать. Для этого будем передавать в функцию содержимое поля и его id, чтобы подставить новое значение в нужное место.
Реализация скрипта будет выглядеть следующим образом:
ymaps.ready(getcoords); form.addEventListener('submit', getFormValue); function getFormValue(event) { event.preventDefault(); } // функция получения корректного адреса function getcoords(value, inputID){ // очистка текста от лишних символов let check = value.replace(/[!@#$%^&*()+]/g, ' ').replace(/\s+/g, ' ').trim(); // проверка корректности введенного адреса if ((check !== "") && (check.length > 10)) { // запрос в геокодер let myGeo = new ymaps.geocode(check); // получение ответа myGeo.then( function (res) { // заменяем текст на результат геокодера убрав страну document.getElementById(idInput).value = res.geoObjects .get(0)["properties"]["_data"]["text"] .slice(8,); } ); // в случае ошибки выводим сообщение }else{ alert("Введите корректное значение!") } }
На этом этапе работа с полями ввода закончена, при вводе адреса скрипт меняет на адрес, который хранится в базе данных Яндекса и является корректным.
Следующий шаг заключается в реализации демонстрации маршрута на карте с метками точек отправления и прибытия. API Яндекса позволяет отобразить карту с необходимыми параметрами, лучше ограничиться парочкой чтобы карта отображала только то, что нужно. Для выполнения задачи понадобятся:
-
центральная точка в координатах;
-
зум.
Говоря про JavaScript, каждый элемент является объектом с набором функций, в данном случае это Map. В него передаются id элемента в котором будет располагаться карта, а также словарь из двух ключей со значениями, перечисленными выше. После из объекта вызывается метод route, который позволяет построить путь от точки до точки. В него необходимо передать список, в котором будет храниться информация о точках отправления и прибытия.
Список может хранить в себе следующую информацию о точке:
-
текстовый адрес;
-
координаты долготы и широты.
Текстовый вариант более удобен для решения, нужно получать адреса из полей ввода и отдавать их в метод.
После выполнения метода, по адресам необходимо отобразить метки на соответствующих координатах, это делается при помощи получения первой и последней точки маршрута и создании иконок на их месте. Можно задать текст на метках в виде «Точка отправления» и «Точка прибытия».
Чуть не забыл, крайне важно выполнить позиционирование карты на маршруте, чтобы его возможно было увидеть. Для этого есть метод setBounds у объекта Map, который принимает координаты точек, но основе которых центрует карту на точке между ними. Также можно передать настройки позиционирования карты, используя 2 параметра:
-
checkZoomRange – параметр, который определяет возможно ли установить коэффициент масштабирования, указанный пользователем;
-
zoomMargin – параметр, который определяет отступ от границ области карты.
Тогда код будет выглядеть следующим образом:
ymaps.ready(loadMapData); // функция для запуска отрисовки карт function loadMapData() { let cards = Array.from(document.getElementsByClassName("card mb-3")) for (card in cards) { let wayId = cards[card].firstElementChild.id; let dep = cards[card].innerText.split('\n')[2].slice(8,); let dest = cards[card].innerText.split('\n')[3].slice(6,); createWay(wayId, dep, dest); } } // функция создания карты function createWay(divId, departure, destination) { var myMap = new ymaps.Map(divId,{ center: [52, 104], zoom: 13 }); // получение точек на карте ymaps.route([ departure, destination ]).then( // доп функция для отображения меток и позиционирования карты function (route) { // получение данных по адресам myMap.geoObjects.add(route); // получение всех точек маршрута var points = route.getWayPoints(); var lastPoint = points.getLength() - 1; // Стиль меток – красный лого и авто выравнивание ширины points.options.set('preset', 'twirl#redStretchyIcon'); // Создание контента на первой и последней точках points.get(0).properties.set('iconContent', 'Точка отправления'); points.get(lastPoint).properties.set('iconContent', 'Точка прибытия'); // позиционирование карты myMap.setBounds([points.get(0).geometry._coordinates, points.get(lastPoint).geometry._coordinates], { checkZoomRange: true, zoomMargin: 10 }); }, // в случае ошибки function (error) { alert('Возникла ошибка: ' + error.message); } ); }
Вставку адресов в карточку реализовать просто, думаю проблем не возникнет.
В итоге, была рассмотрена API Яндекс для работы с картами и реализована задача по построению маршрута. Документация предоставляет возможность понять, как работают различные методы и как можно применять их. Думаю, данный материал будет полезен начинающим разработчикам, у которых возникла потребность в реализации построении карт на основе текстовых представлений адресов.
ссылка на оригинал статьи https://habr.com/ru/post/689766/
Добавить комментарий