Como construir um aplicativo de geocodificação no Vue.js usando o Mapbox
Publicados: 2022-03-10A precisão pontual e a modularidade estão entre as vantagens que tornam os geocódigos o meio perfeito de encontrar um local específico.
Neste guia, construiremos um aplicativo de geocodificação simples do zero, usando Vue.js e Mapbox. Abordaremos o processo desde a construção do andaime de front-end até a construção de um geocodificador para lidar com geocodificação direta e geocodificação reversa. Para aproveitar ao máximo este guia, você precisará de um conhecimento básico de JavaScript e Vue.js e de como fazer chamadas de API.
O que é geocodificação?
A geocodificação é a transformação de localizações baseadas em texto em coordenadas geográficas (normalmente, longitude e latitude) que indicam uma localização no mundo.
A geocodificação é de dois tipos: direta e reversa . A geocodificação direta converte textos de localização em coordenadas geográficas, enquanto a geocodificação reversa converte coordenadas em textos de localização.
Em outras palavras, a geocodificação reversa transforma 40,714224, -73,961452 em “277 Bedford Ave, Brooklyn”, e a geocodificação direta faz o oposto, transformando “277 Bedford Ave, Brooklyn” em 40,714224, -73,961452.
Para dar mais informações, construiremos um mini aplicativo da web que usa um mapa da web interativo com marcadores personalizados para exibir as coordenadas de localização, que posteriormente decodificaremos em textos de localização.
Nosso aplicativo terá as seguintes funções básicas:
- dar ao usuário acesso a uma exibição de mapa interativa com um marcador;
- permitir que o usuário mova o marcador à vontade, enquanto exibe as coordenadas;
- retornar uma localização baseada em texto ou coordenadas de localização mediante solicitação do usuário.
Configurar projeto usando Vue CLI
Faremos uso do clichê encontrado neste repositório. Ele contém um novo projeto com o Vue CLI e o yarn
como gerenciador de pacotes. Você precisará clonar o repositório. Certifique-se de estar trabalhando a partir do branch geocoder/boilerplate
.
Configurar a estrutura de arquivos do aplicativo
Em seguida, precisaremos configurar a estrutura de arquivos do nosso projeto. Renomeie o arquivo Helloworld.vue
na pasta do componente para Index.vue
e deixe-o em branco por enquanto. Vá em frente e copie o seguinte no arquivo 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>
Aqui, importamos e registramos o componente recentemente renomeado localmente. Também adicionamos uma barra de navegação para melhorar a estética do nosso aplicativo.
Precisamos de um arquivo .env
para carregar as variáveis de ambiente. Vá em frente e adicione um na raiz da pasta do seu projeto.
Instale os pacotes e bibliotecas necessários
Para iniciar o processo de desenvolvimento, precisaremos instalar as bibliotecas necessárias. Aqui está uma lista dos que usaremos para este projeto:
- Mapbox GL JS
Esta biblioteca JavaScript usa WebGL para renderizar mapas interativos de mosaicos vetoriais e Mapbox. - Mapbox-gl-geocoder
Este controle de geocodificador para Mapbox GL ajudará com nossa geocodificação avançada. - Dotenv
Não teremos que instalar isso porque ele vem pré-instalado com o Vue CLI. Ele nos ajuda a carregar variáveis de ambiente de um arquivo.env
paraprocess.env
. Dessa forma, podemos manter nossas configurações separadas do nosso código. - Axios
Esta biblioteca nos ajudará a fazer solicitações HTTP.
Instale os pacotes em sua CLI de acordo com seu gerenciador de pacotes preferido. Se você estiver usando o Yarn, execute o comando abaixo:
cd geocoder && yarn add mapbox-gl @mapbox/mapbox-gl-geocoder axios
Se você estiver usando o npm, execute isto:
cd geocoder && npm i mapbox-gl @mapbox/mapbox-gl-geocoder axios --save
Primeiro tivemos que entrar na pasta do geocoder
antes de executar o comando de instalação.
Montando o front-end com Vue.js
Vamos em frente e criar um layout para nosso aplicativo. Precisaremos de um elemento para abrigar nosso mapa, uma região para exibir as coordenadas enquanto escutamos o movimento do marcador no mapa e algo para exibir a localização quando chamamos a API de geocodificação reversa. Podemos abrigar tudo isso dentro de um componente de cartão.
Copie o seguinte em seu arquivo 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>
Para ver o que temos atualmente, inicie seu servidor de desenvolvimento. Para fios:
yarn serve
Ou para npm:
npm run serve
Nosso aplicativo deve ficar assim agora:
O ponto em branco à esquerda parece fora. Deve abrigar nossa exibição de mapa. Vamos adicionar isso.
Exibição interativa do mapa com o Mapbox
A primeira coisa que precisamos fazer é obter acesso às bibliotecas Mapbox GL e Geocoder. Começaremos importando as bibliotecas Mapbox GL e Geocoder no arquivo 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";
O Mapbox requer um token de acesso exclusivo para calcular os blocos de vetores do mapa. Obtenha o seu e adicione-o como uma variável de ambiente em seu arquivo .env
.
.env
VUE_APP_MAP_ACCESS_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Também precisamos definir propriedades que ajudarão a juntar nossos blocos de mapa em nossa instância de dados. Adicione o seguinte abaixo do local onde importamos as bibliotecas:
export default { data() { return { loading: false, location: "", access_token: process.env.VUE_APP_MAP_ACCESS_TOKEN, center: [0, 0], map: {}, }; }, }
- A propriedade de
location
será modelada para a entrada que temos em nosso andaime. Usaremos isso para lidar com geocodificação reversa (ou seja, exibir uma localização das coordenadas). - A propriedade
center
abriga nossas coordenadas (longitude e latitude). Isso é fundamental para juntar nossos blocos de mapa, como veremos em breve. - A propriedade
access_token
refere-se à nossa variável de ambiente, que adicionamos anteriormente. - A propriedade
map
serve como um construtor para nosso componente map.
Vamos continuar criando um método que plota nosso mapa interativo com nosso geocodificador avançado embutido nele. Este método é nossa função base, servindo como intermediário entre nosso componente e o Mapbox GL; chamaremos esse método createMap
. Adicione isto abaixo do objeto de dados:
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); } }, },
Para criar nosso mapa, especificamos um container
que abriga o mapa, uma propriedade de style
para o formato de exibição de nosso mapa e uma propriedade center
para abrigar nossas coordenadas. A propriedade center
é um tipo de matriz e contém a longitude e a latitude.
O Mapbox GL JS inicializa nosso mapa com base nesses parâmetros na página e retorna um objeto Map
para nós. O objeto Map
se refere ao mapa em nossa página, enquanto expõe métodos e propriedades que nos permitem interagir com o mapa. Armazenamos esse objeto retornado em nossa instância de dados, this.map
.
Encaminhar geocodificação com o Mapbox Geocoder
Agora, adicionaremos o geocodificador e o marcador personalizado. O geocodificador lida com a geocodificação avançada transformando localizações baseadas em texto em coordenadas. Isso aparecerá na forma de uma caixa de entrada de pesquisa anexada ao nosso mapa.
Adicione o seguinte abaixo da inicialização do this.map
que temos acima:
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()); }); });
Aqui, primeiro criamos uma nova instância de um geocodificador usando o construtor MapboxGeocoder
. Isso inicializa um geocodificador com base nos parâmetros fornecidos e retorna um objeto, exposto a métodos e eventos. A propriedade accessToken
refere-se ao nosso token de acesso Mapbox, e mapboxgl
refere-se à biblioteca de mapas usada atualmente.
O núcleo do nosso aplicativo é o marcador personalizado; o geocoder vem com um por padrão. Isso, no entanto, não nos daria toda a personalização de que precisamos; portanto, nós o desabilitamos.
Continuando, passamos nosso geocodificador recém-criado como parâmetro para o método addControl
, exposto a nós pelo nosso objeto map. addControl
aceita um control
como parâmetro.
Para criar nosso marcador personalizado, usamos um evento exposto a nós pelo nosso objeto geocodificador. O ouvinte on
eventos nos permite assinar eventos que acontecem dentro do geocoder. Aceita vários eventos como parâmetros. Estamos ouvindo o evento de result
, que é acionado quando uma entrada é definida.
Em poucas palavras, em result
, nosso construtor de marcador cria um marcador, com base nos parâmetros que fornecemos (um atributo arrastável e uma cor, neste caso). Ele retorna um objeto, com o qual usamos o método setLngLat
para obter nossas coordenadas. Anexamos o marcador personalizado ao nosso mapa existente usando o método addTo
. Por fim, atualizamos a propriedade center
em nossa instância com as novas coordenadas.
Também temos que rastrear o movimento do nosso marcador personalizado. Conseguimos isso usando o ouvinte de evento dragend
e atualizamos nossa propriedade center
com as coordenadas atuais.
Vamos atualizar o modelo para exibir nosso mapa interativo e geocodificador de encaminhamento. Atualize a seção de exibição de coordenadas em nosso modelo com o seguinte:
<div class="coordinates-header"> <h3>Current Coordinates</h3> <p>Latitude: {{ center[0] }}</p> <p>Longitude: {{ center[1] }}</p> </div>
Lembra como sempre atualizamos nossa propriedade center
após um evento? Estamos exibindo as coordenadas aqui com base no valor atual.
Para melhorar a estética do nosso aplicativo, adicione o seguinte arquivo CSS na seção head
do arquivo index.html
. Coloque este arquivo na pasta pública.
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.53.0/mapbox-gl.css" rel="stylesheet" />
Nosso aplicativo deve ficar assim agora:
Localização de geocódigo reverso com API Mapbox
Agora, vamos lidar com a geocodificação reversa de nossas coordenadas para locais baseados em texto. Vamos escrever um método que lide com isso e acione-o com o botão Get Location
em nosso modelo.
A geocodificação reversa no Mapbox é tratada pela API de geocodificação reversa. Isso aceita longitude
, latitude
e access token
como parâmetros de solicitação. Essa chamada retorna uma carga útil de resposta — normalmente, com vários detalhes. Nossa preocupação é o primeiro objeto na matriz de features
, onde está a localização geocodificada reversa.
Precisaremos criar uma função que envie a longitude
, latitude
e access_token
do local que queremos obter para a API do Mapbox. Precisamos enviá-los para obter os detalhes desse local.
Finalmente, precisamos atualizar a propriedade location
em nossa instância com o valor da chave place_name
no objeto.
Abaixo da função createMap()
, vamos adicionar uma nova função que trata do que queremos. É assim que deve ficar:
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); } },
Esta função faz uma solicitação GET
para a API Mapbox. A resposta contém place_name
— o nome do local selecionado. Obtemos isso da resposta e, em seguida, definimos como o valor de this.location
.
Feito isso, precisamos editar e configurar o botão que irá chamar esta função que criamos. Usaremos um ouvinte de evento de click
— que chamará o método getLocation
quando um usuário clicar nele. Vá em frente e edite o componente do botão para isso.
<button type="button" :disabled="loading" :class="{ disabled: loading }" class="location-btn" @click="getLocation" > Get Location </button>
Como cereja do bolo, vamos anexar uma função para copiar o local exibido para a área de transferência. Adicione isso logo abaixo da função getLocation
:
copyLocation() { if (this.location) { navigator.clipboard.writeText(this.location); alert("Location Copied") } return; },
Atualize o componente do botão Copy
para acionar isso:
<button type="button" class="copy-btn" @click="copyLocation">
Conclusão
Neste guia, analisamos a geocodificação usando o Mapbox. Construímos um aplicativo de geocodificação que transforma localizações baseadas em texto em coordenadas, exibindo a localização em um mapa interativo, e que converte coordenadas em localizações baseadas em texto, de acordo com a solicitação do usuário. Este guia é apenas o começo. Muito mais poderia ser alcançado com as APIs de geocodificação, como alterar a apresentação do mapa usando os vários estilos de mapa fornecidos pelo Mapbox.
- O código-fonte está disponível no GitHub.
Recursos
- “Geocodificação”, documentação do Mapbox
- “Estilos”, documentação do Mapbox
- “Usando variáveis de ambiente no código do lado do cliente”, em “Modos e variáveis de ambiente”, Vue CLI