HTML, JavaScript, YandexAPI и щепотку Bootstrap

от автора

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

Думаю, что все знают про 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *