Как создать приложение геокодирования в Vue.js с помощью Mapbox
Опубликовано: 2022-03-10Высочайшая точность и модульность являются одними из преимуществ, которые делают геокодирование идеальным средством поиска определенного местоположения.
В этом руководстве мы создадим простое приложение для геокодирования с нуля, используя Vue.js и Mapbox. Мы рассмотрим весь процесс, начиная с создания внешнего каркаса и заканчивая созданием геокодера для прямого геокодирования и обратного геокодирования. Чтобы получить максимальную отдачу от этого руководства, вам необходимо иметь базовое представление о JavaScript и Vue.js, а также о том, как выполнять вызовы API.
Что такое геокодирование?
Геокодирование — это преобразование текстовых местоположений в географические координаты (обычно долготу и широту), которые указывают местоположение в мире.
Геокодирование бывает двух видов: прямое и обратное . Прямое геокодирование преобразует тексты местоположения в географические координаты, тогда как обратное геокодирование преобразует координаты в тексты местоположения.
Другими словами, обратное геокодирование превращает 40.714224, -73.961452 в «277 Bedford Ave, Brooklyn», а прямое геокодирование делает обратное, превращая «277 Bedford Ave, Brooklyn» в 40.714224, -73.961452.
Чтобы дать больше информации, мы создадим мини-веб-приложение, которое использует интерактивную веб-карту с пользовательскими маркерами для отображения координат местоположения, которые мы впоследствии декодируем в тексты местоположения.
Наше приложение будет иметь следующие основные функции:
- предоставить пользователю доступ к интерактивному отображению карты с маркером;
- разрешить пользователю перемещать маркер по желанию, отображая при этом координаты;
- возвращать текстовое местоположение или координаты местоположения по запросу пользователя.
Настройте проект с помощью Vue CLI
Мы будем использовать шаблон, найденный в этом репозитории. Он содержит новый проект с Vue CLI и yarn
в качестве менеджера пакетов. Вам нужно будет клонировать репозиторий. Убедитесь, что вы работаете с веткой geocoder/boilerplate
.
Настройка файловой структуры приложения
Далее нам нужно настроить файловую структуру нашего проекта. Переименуйте файл Helloworld.vue
в папке компонента в Index.vue
и пока оставьте его пустым. Продолжайте и скопируйте следующее в файл App.vue
:
<template> <div> <!--Navbar Here --> <div> <nav> <div class="header"> <h3>Geocoder</h3> </div> </nav> </div> <!--Index Page Here --> <index /> </div> </template> <script> import index from "./components/index.vue"; export default { name: "App", components: { index, }, }; </script>
Здесь мы импортировали, а затем зарегистрировали недавно переименованный компонент локально. Мы также добавили панель навигации, чтобы улучшить эстетику нашего приложения.
Нам нужен файл .env
для загрузки переменных среды. Идите вперед и добавьте один в корень папки вашего проекта.
Установите необходимые пакеты и библиотеки
Чтобы запустить процесс разработки, нам нужно будет установить необходимые библиотеки. Вот список тех, которые мы будем использовать для этого проекта:
- Мапбокс GL JS
Эта библиотека JavaScript использует WebGL для рендеринга интерактивных карт из векторных листов и Mapbox. - Mapbox-gl-геокодер
Этот элемент управления геокодером для Mapbox GL поможет в нашем прямом геокодировании. - Дотенв
Нам не нужно его устанавливать, потому что он поставляется с предустановленным Vue CLI. Это помогает нам загружать переменные среды из файла.env
вprocess.env
. Таким образом, мы можем хранить наши конфигурации отдельно от нашего кода. - Аксиос
Эта библиотека поможет нам делать HTTP-запросы.
Установите пакеты в CLI в соответствии с вашим предпочтительным менеджером пакетов. Если вы используете Yarn, выполните следующую команду:
cd geocoder && yarn add mapbox-gl @mapbox/mapbox-gl-geocoder axios
Если вы используете npm, запустите это:
cd geocoder && npm i mapbox-gl @mapbox/mapbox-gl-geocoder axios --save
Сначала нам нужно было войти в папку geocoder
перед запуском команды установки.
Создание внешнего интерфейса с помощью Vue.js
Давайте продолжим и создадим макет для нашего приложения. Нам понадобится элемент для размещения нашей карты, регион для отображения координат при прослушивании движения маркера на карте и что-то для отображения местоположения при вызове API обратного геокодирования. Мы можем разместить все это в карточном компоненте.
Скопируйте следующее в файл Index.vue
:
<template> <div class="main"> <div class="flex"> <!-- Map Display here --> <div class="map-holder"> <div></div> </div> <!-- Coordinates Display here --> <div class="dislpay-arena"> <div class="coordinates-header"> <h3>Current Coordinates</h3> <p>Latitude:</p> <p>Longitude:</p> </div> <div class="coordinates-header"> <h3>Current Location</h3> <div class="form-group"> <input type="text" class="location-control" :value="location" readonly /> <button type="button" class="copy-btn">Copy</button> </div> <button type="button" class="location-btn">Get Location</button> </div> </div> </div> </div> </template>
Чтобы увидеть, что у нас есть на данный момент, запустите свой сервер разработки. Для пряжи:
yarn serve
Или для нпм:
npm run serve
Теперь наше приложение должно выглядеть так:
Пустое место слева выглядит не так. В нем должен разместиться наш дисплей карты. Добавим это.
Интерактивное отображение карты с помощью Mapbox
Первое, что нам нужно сделать, это получить доступ к библиотекам Mapbox GL и Geocoder. Мы начнем с импорта библиотек Mapbox GL и Geocoder в файл Index.vue
.
import axios from "axios"; import mapboxgl from "mapbox-gl"; import MapboxGeocoder from "@mapbox/mapbox-gl-geocoder"; import "@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css";
Mapbox требует уникальный токен доступа для вычисления векторных фрагментов карты. Получите свой и добавьте его в качестве переменной среды в файл .env
.
.env
VUE_APP_MAP_ACCESS_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Нам также необходимо определить свойства, которые помогут совместить наши листы карты в нашем экземпляре данных. Добавьте следующее ниже места, куда мы импортировали библиотеки:
export default { data() { return { loading: false, location: "", access_token: process.env.VUE_APP_MAP_ACCESS_TOKEN, center: [0, 0], map: {}, }; }, }
- Свойство
location
будет смоделировано в соответствии с входными данными, которые у нас есть в наших лесах. Мы будем использовать это для обработки обратного геокодирования (т. е. отображения местоположения по координатам). - Свойство
center
содержит наши координаты (долготу и широту). Это очень важно для соединения фрагментов карты, как мы скоро увидим. - Свойство
access_token
относится к нашей переменной окружения, которую мы добавили ранее. - Свойство
map
служит конструктором для нашего компонента карты.
Давайте перейдем к созданию метода, который строит нашу интерактивную карту со встроенным в нее прямым геокодировщиком. Этот метод является нашей базовой функцией, служащей посредником между нашим компонентом и Mapbox GL; мы назовем этот метод createMap
. Добавьте это ниже объекта данных:
mounted() { this.createMap() }, methods: { async createMap() { try { mapboxgl.accessToken = this.access_token; this.map = new mapboxgl.Map({ container: "map", style: "mapbox://styles/mapbox/streets-v11", center: this.center, zoom: 11, }); } catch (err) { console.log("map error", err); } }, },
Чтобы создать нашу карту, мы указали container
, в котором находится карта, свойство style
для формата отображения нашей карты и свойство center
для размещения наших координат. Свойство center
является типом массива и содержит долготу и широту.
Mapbox GL JS инициализирует нашу карту на основе этих параметров на странице и возвращает нам объект Map
. Объект Map
ссылается на карту на нашей странице, предоставляя методы и свойства, которые позволяют нам взаимодействовать с картой. Мы сохранили этот возвращенный объект в нашем экземпляре данных, this.map
.
Прямое геокодирование с помощью Mapbox Geocoder
Теперь мы добавим геокодер и пользовательский маркер. Геокодер выполняет прямое геокодирование, преобразовывая текстовые местоположения в координаты. Это появится в виде поля ввода поиска, добавленного к нашей карте.
Добавьте следующее ниже инициализации this.map
, которую мы имеем выше:
let geocoder = new MapboxGeocoder({ accessToken: this.access_token, mapboxgl: mapboxgl, marker: false, }); this.map.addControl(geocoder); geocoder.on("result", (e) => { const marker = new mapboxgl.Marker({ draggable: true, color: "#D80739", }) .setLngLat(e.result.center) .addTo(this.map); this.center = e.result.center; marker.on("dragend", (e) => { this.center = Object.values(e.target.getLngLat()); }); });
Здесь мы сначала создали новый экземпляр геокодера с помощью конструктора MapboxGeocoder
. Это инициализирует геокодер на основе предоставленных параметров и возвращает объект, доступный для методов и событий. Свойство accessToken
относится к нашему токену доступа к Mapbox, а mapboxgl
относится к используемой в данный момент библиотеке карт.
Ядром нашего приложения является пользовательский маркер; геокодер поставляется с одним по умолчанию. Это, однако, не дало бы нам всей необходимой настройки; следовательно, мы отключили его.
Двигаясь вперед, мы передали наш вновь созданный геокодер в качестве параметра методу addControl
, доступного нам через наш объект карты. addControl
принимает элемент control
в качестве параметра.
Чтобы создать наш собственный маркер, мы использовали событие, предоставленное нам нашим объектом геокодера. Слушатель событий on
позволяет нам подписываться на события, происходящие в геокодере. Он принимает различные события в качестве параметров. Мы слушаем событие result
, которое запускается при установке ввода.
В двух словах, в result
наш конструктор маркера создает маркер на основе предоставленных нами параметров (в данном случае перетаскиваемый атрибут и цвет). Он возвращает объект, с которым мы используем метод setLngLat
для получения наших координат. Мы добавляем пользовательский маркер к нашей существующей карте, используя метод addTo
. Наконец, мы обновляем свойство center
в нашем экземпляре новыми координатами.
Мы также должны отслеживать движение нашего пользовательского маркера. Мы добились этого с помощью прослушивателя событий dragend
и обновили свойство center
текущими координатами.
Давайте обновим шаблон, чтобы отобразить нашу интерактивную карту и перенаправить геокодер. Обновите раздел отображения координат в нашем шаблоне следующим образом:
<div class="coordinates-header"> <h3>Current Coordinates</h3> <p>Latitude: {{ center[0] }}</p> <p>Longitude: {{ center[1] }}</p> </div>
Помните, как мы всегда обновляли наш center
собственности после события? Мы отображаем координаты здесь на основе текущего значения.
Чтобы улучшить эстетику нашего приложения, добавьте следующий файл CSS в раздел head
файла index.html
. Поместите этот файл в общую папку.
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.53.0/mapbox-gl.css" rel="stylesheet" />
Теперь наше приложение должно выглядеть так:
Обратное геокодирование местоположения с помощью Mapbox API
Теперь мы займемся обратным геокодированием наших координат в текстовые местоположения. Давайте напишем метод, который обрабатывает это и активирует его с помощью кнопки « Get Location
» в нашем шаблоне.
Обратное геокодирование в Mapbox обрабатывается API обратного геокодирования. Это принимает longitude
, latitude
и access token
в качестве параметров запроса. Этот вызов возвращает полезную нагрузку ответа — обычно с различными подробностями. Нас интересует первый объект в массиве features
, где находится обратное геокодированное местоположение.
Нам нужно создать функцию, которая отправляет longitude
, latitude
и access_token
местоположения, которое мы хотим получить, в API Mapbox. Нам нужно послать их, чтобы получить информацию об этом месте.
Наконец, нам нужно обновить свойство location
в нашем экземпляре значением ключа place_name
в объекте.
Под createMap()
давайте добавим новую функцию, которая обрабатывает то, что нам нужно. Вот как это должно выглядеть:
async getLocation() { try { this.loading = true; const response = await axios.get( `https://api.mapbox.com/geocoding/v5/mapbox.places/${this.center[0]},${this.center[1]}.json?access_token=${this.access_token}` ); this.loading = false; this.location = response.data.features[0].place_name; } catch (err) { this.loading = false; console.log(err); } },
Эта функция делает запрос GET
к API Mapbox. Ответ содержит place_name
— название выбранной локации. Мы получаем это из ответа, а затем устанавливаем его как значение this.location
.
После этого нам нужно отредактировать и настроить кнопку, которая будет вызывать эту функцию, которую мы создали. Мы будем использовать прослушиватель событий click
, который будет вызывать метод getLocation
, когда пользователь нажимает на него. Идите вперед и отредактируйте компонент кнопки следующим образом.
<button type="button" :disabled="loading" :class="{ disabled: loading }" class="location-btn" @click="getLocation" > Get Location </button>
В качестве вишенки на торте давайте добавим функцию для копирования отображаемого местоположения в буфер обмена. Добавьте это чуть ниже функции getLocation
:
copyLocation() { if (this.location) { navigator.clipboard.writeText(this.location); alert("Location Copied") } return; },
Обновите компонент кнопки « Copy
», чтобы вызвать это:
<button type="button" class="copy-btn" @click="copyLocation">
Заключение
В этом руководстве мы рассмотрели геокодирование с помощью Mapbox. Мы создали приложение для геокодирования, которое преобразует текстовые местоположения в координаты, отображает местоположение на интерактивной карте и преобразует координаты в текстовые местоположения в соответствии с запросом пользователя. Это руководство — только начало. С API-интерфейсами геокодирования можно добиться гораздо большего, например изменить представление карты с помощью различных стилей карты, предоставляемых Mapbox.
- Исходный код доступен на GitHub.
Ресурсы
- «Геокодирование», документация Mapbox
- «Стили», документация Mapbox
- «Использование переменных среды в клиентском коде», в «Режимы и переменные среды», Vue CLI