Come creare un'app di geocodifica in Vue.js usando Mapbox

Pubblicato: 2022-03-10
Riassunto rapido ↬ In questa guida, daremo uno sguardo generale ai concetti di geocodifica diretta e geocodifica inversa. Costruiremo una mini-app che applica questi concetti per visualizzare posizioni specifiche, utilizzando Mapbox e Vue.js 2.6.11 per raggiungere questo obiettivo.

La precisione millimetrica e la modularità sono tra i vantaggi che rendono i geocodici il mezzo perfetto per trovare una posizione particolare.

In questa guida creeremo da zero una semplice app di geocodifica, utilizzando Vue.js e Mapbox. Tratteremo il processo dalla costruzione dell'impalcatura front-end fino alla creazione di un geocodificatore per gestire la geocodifica in avanti e la geocodifica inversa. Per ottenere il massimo da questa guida, avrai bisogno di una conoscenza di base di JavaScript e Vue.js e di come effettuare chiamate API.

Che cos'è la geocodificazione?

La geocodifica è la trasformazione di posizioni basate su testo in coordinate geografiche (tipicamente longitudine e latitudine) che indicano una posizione nel mondo.

La geocodifica è di due tipi: avanti e indietro . La geocodifica in avanti converte i testi di posizione in coordinate geografiche, mentre la geocodifica inversa converte le coordinate in testi di posizione.

In altre parole, la geocodifica inversa trasforma 40.714224, -73.961452 in "277 Bedford Ave, Brooklyn" e la geocodifica in avanti fa l'opposto, trasformando "277 Bedford Ave, Brooklyn" in 40.714224, -73.961452.

Per fornire maggiori informazioni, costruiremo una mini app Web che utilizza una mappa Web interattiva con indicatori personalizzati per visualizzare le coordinate della posizione, che successivamente decodificheremo in testi di posizione.

La nostra app avrà le seguenti funzioni di base:

  • dare all'utente l'accesso a una visualizzazione mappa interattiva con un marker;
  • consentire all'utente di spostare il marker a piacimento, visualizzando le coordinate;
  • restituire una posizione basata su testo o coordinate di posizione su richiesta dell'utente.
Altro dopo il salto! Continua a leggere sotto ↓

Configura il progetto utilizzando Vue CLI

Useremo il boilerplate trovato in questo repository. Contiene un nuovo progetto con Vue CLI e yarn come gestore di pacchetti. Dovrai clonare il repository. Assicurati di lavorare dal ramo geocoder/boilerplate .

Impostare la struttura dei file dell'applicazione

Successivamente, dovremo impostare la struttura del file del nostro progetto. Rinomina il file Helloworld.vue nella cartella del componente in Index.vue e lascialo vuoto per ora. Vai avanti e copia quanto segue nel file 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>

Qui abbiamo importato e quindi registrato localmente il componente rinominato di recente. Abbiamo anche aggiunto una barra di navigazione per migliorare l'estetica della nostra app.

Abbiamo bisogno di un file .env per caricare le variabili di ambiente. Vai avanti e aggiungine uno nella radice della cartella del tuo progetto.

Installa i pacchetti e le librerie richiesti

Per avviare il processo di sviluppo, dovremo installare le librerie richieste. Ecco un elenco di quelli che useremo per questo progetto:

  1. Mapbox GL JS
    Questa libreria JavaScript utilizza WebGL per eseguire il rendering di mappe interattive da riquadri vettoriali e Mapbox.
  2. Mapbox-gl-geocoder
    Questo controllo del geocodificatore per Mapbox GL aiuterà con la nostra geocodifica in avanti.
  3. Dotenv
    Non dovremo installarlo perché viene preinstallato con Vue CLI. Ci aiuta a caricare le variabili di ambiente da un file .env in process.env . In questo modo, possiamo mantenere le nostre configurazioni separate dal nostro codice.
  4. Asso
    Questa libreria ci aiuterà a fare richieste HTTP.

Installa i pacchetti nella tua CLI in base al tuo gestore di pacchetti preferito. Se stai usando Yarn, esegui il comando seguente:

 cd geocoder && yarn add mapbox-gl @mapbox/mapbox-gl-geocoder axios

Se stai usando npm, esegui questo:

 cd geocoder && npm i mapbox-gl @mapbox/mapbox-gl-geocoder axios --save

Abbiamo dovuto prima entrare nella cartella del geocoder prima di eseguire il comando di installazione.

Impalcatura del front-end con Vue.js

Andiamo avanti e creiamo un layout per la nostra app. Avremo bisogno di un elemento per ospitare la nostra mappa, una regione per visualizzare le coordinate mentre si ascolta il movimento dell'indicatore sulla mappa e qualcosa per visualizzare la posizione quando chiamiamo l'API di geocodifica inversa. Possiamo ospitare tutto questo all'interno di un componente della carta.

Copia quanto segue nel tuo file 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>

Per vedere cosa abbiamo attualmente, avvia il tuo server di sviluppo. Per filato:

 yarn serve

Oppure per npm:

 npm run serve

La nostra app ora dovrebbe apparire così:

Anteprima dell'impalcatura
Anteprima dell'impalcatura dell'app di geocodifica. (Grande anteprima)

Il punto vuoto a sinistra sembra spento. Dovrebbe ospitare la nostra visualizzazione della mappa. Aggiungiamolo.

Visualizzazione interattiva della mappa con Mapbox

La prima cosa che dobbiamo fare è accedere alle librerie Mapbox GL e Geocoder. Inizieremo importando le librerie Mapbox GL e Geocoder nel file 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 richiede un token di accesso univoco per calcolare i riquadri vettoriali della mappa. Prendi il tuo e aggiungilo come variabile ambientale nel tuo file .env .

 .env
 VUE_APP_MAP_ACCESS_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Abbiamo anche bisogno di definire proprietà che aiutino a mettere insieme i nostri riquadri della mappa nella nostra istanza di dati. Aggiungi quanto segue sotto il punto in cui abbiamo importato le librerie:

 export default { data() { return { loading: false, location: "", access_token: process.env.VUE_APP_MAP_ACCESS_TOKEN, center: [0, 0], map: {}, }; }, }
  • La proprietà location sarà modellata sull'input che abbiamo nel nostro scaffolding. Lo useremo per gestire la geocodifica inversa (cioè visualizzare una posizione dalle coordinate).
  • La proprietà center ospita le nostre coordinate (longitudine e latitudine). Questo è fondamentale per mettere insieme le nostre tessere mappa, come vedremo a breve.
  • La proprietà access_token si riferisce alla nostra variabile ambientale, che abbiamo aggiunto in precedenza.
  • La proprietà map funge da costruttore per il nostro componente map.

Procediamo con la creazione di un metodo che traccia la nostra mappa interattiva con il nostro geocoder in avanti incorporato in essa. Questo metodo è la nostra funzione di base, fungendo da intermediario tra il nostro componente e Mapbox GL; chiameremo questo metodo createMap . Aggiungi questo sotto l'oggetto dati:

 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); } }, },

Per creare la nostra mappa, abbiamo specificato un container che ospita la mappa, una proprietà di style per il formato di visualizzazione della nostra mappa e una proprietà center per ospitare le nostre coordinate. La proprietà center è un tipo di matrice e contiene la longitudine e la latitudine.

Mapbox GL JS inizializza la nostra mappa in base a questi parametri nella pagina e ci restituisce un oggetto Map . L'oggetto Map si riferisce alla mappa sulla nostra pagina, mentre espone metodi e proprietà che ci consentono di interagire con la mappa. Abbiamo archiviato questo oggetto restituito nella nostra istanza di dati, this.map .

Geocodifica in avanti con il geocodificatore Mapbox

Ora aggiungeremo il geocoder e il marker personalizzato. Il geocoder gestisce la geocodifica in avanti trasformando le posizioni basate su testo in coordinate. Questo apparirà sotto forma di una casella di input di ricerca aggiunta alla nostra mappa.

Aggiungi quanto segue sotto l'inizializzazione this.map che abbiamo sopra:

 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()); }); });

Qui, abbiamo prima creato una nuova istanza di un geocoder usando il costruttore MapboxGeocoder . Questo inizializza un geocoder in base ai parametri forniti e restituisce un oggetto, esposto a metodi ed eventi. La proprietà accessToken si riferisce al nostro token di accesso Mapbox e mapboxgl si riferisce alla libreria di mappe attualmente utilizzata.

Il fulcro della nostra app è l'indicatore personalizzato; il geocoder ne viene fornito uno per impostazione predefinita. Questo, tuttavia, non ci darebbe tutta la personalizzazione di cui abbiamo bisogno; quindi, l'abbiamo disabilitato.

Andando avanti, abbiamo passato il nostro geocoder appena creato come parametro al metodo addControl , esposto a noi dal nostro oggetto mappa. addControl accetta un control come parametro.

Per creare il nostro marcatore personalizzato, abbiamo utilizzato un evento a noi esposto dal nostro oggetto geocoder. Il listener di eventi on ci consente di iscriverci agli eventi che si verificano all'interno del geocoder. Accetta vari eventi come parametri. Stiamo ascoltando l'evento result , che viene attivato quando viene impostato un input.

In poche parole, su result , il nostro costruttore di marker crea un marker, in base ai parametri che abbiamo fornito (un attributo trascinabile e un colore, in questo caso). Restituisce un oggetto, con il quale utilizziamo il metodo setLngLat per ottenere le nostre coordinate. Aggiungiamo il marcatore personalizzato alla nostra mappa esistente usando il metodo addTo . Infine, aggiorniamo la proprietà del center nella nostra istanza con le nuove coordinate.

Dobbiamo anche tracciare il movimento del nostro marcatore personalizzato. Abbiamo ottenuto questo risultato utilizzando il listener di eventi dragend e abbiamo aggiornato la nostra proprietà del center con le coordinate correnti.

Aggiorniamo il modello per visualizzare la nostra mappa interattiva e il geocoder in avanti. Aggiorna la sezione di visualizzazione delle coordinate nel nostro modello con quanto segue:

 <div class="coordinates-header"> <h3>Current Coordinates</h3> <p>Latitude: {{ center[0] }}</p> <p>Longitude: {{ center[1] }}</p> </div>

Ricordi come abbiamo sempre aggiornato la nostra struttura del center a seguito di un evento? Stiamo visualizzando le coordinate qui in base al valore corrente.

Per migliorare l'estetica della nostra app, aggiungi il seguente file CSS nella sezione head del file index.html . Metti questo file nella cartella pubblica.

 <link href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.53.0/mapbox-gl.css" rel="stylesheet" />

La nostra app ora dovrebbe apparire così:

Anteprima di geocodifica in avanti
Anteprima di geocodifica in avanti. (Grande anteprima)

Geocodifica inversa della posizione con l'API Mapbox

Ora ci occuperemo della geocodifica inversa delle nostre coordinate in posizioni basate su testo. Scriviamo un metodo che lo gestisca e lo attiviamo con il pulsante Get Location nel nostro modello.

La geocodifica inversa in Mapbox è gestita dall'API di geocodifica inversa. Questo accetta longitude , latitude e access token come parametri di richiesta. Questa chiamata restituisce un payload di risposta, in genere con vari dettagli. La nostra preoccupazione è il primo oggetto nell'array delle features , dove si trova la posizione geocodificata inversa.

Dovremo creare una funzione che invii longitude , latitude e access_token della posizione che vogliamo ottenere all'API Mapbox. Dobbiamo inviarli per ottenere i dettagli di quella posizione.

Infine, dobbiamo aggiornare la proprietà location nella nostra istanza con il valore della chiave place_name nell'oggetto.

Sotto la funzione createMap() , aggiungiamo una nuova funzione che gestisce ciò che vogliamo. Ecco come dovrebbe apparire:

 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); } },

Questa funzione effettua una richiesta GET all'API Mapbox. La risposta contiene place_name — il nome della posizione selezionata. Otteniamo questo dalla risposta e quindi lo impostiamo come valore di this.location .

Fatto ciò, dobbiamo modificare e impostare il pulsante che chiamerà questa funzione che abbiamo creato. Useremo un listener di eventi click , che chiamerà il metodo getLocation quando un utente fa clic su di esso. Vai avanti e modifica il componente del pulsante su questo.

 <button type="button" :disabled="loading" :class="{ disabled: loading }" class="location-btn" @click="getLocation" > Get Location </button>

Come ciliegina sulla torta, alleghiamo una funzione per copiare la posizione visualizzata negli appunti. Aggiungi questo appena sotto la funzione getLocation :

 copyLocation() { if (this.location) { navigator.clipboard.writeText(this.location); alert("Location Copied") } return; },

Aggiorna il componente del pulsante Copy per attivare questo:

 <button type="button" class="copy-btn" @click="copyLocation">

Conclusione

In questa guida, abbiamo esaminato la geocodifica utilizzando Mapbox. Abbiamo creato un'app di geocodifica che trasforma le posizioni basate su testo in coordinate, visualizzando la posizione su una mappa interattiva e che converte le coordinate in posizioni basate su testo, in base alla richiesta dell'utente. Questa guida è solo l'inizio. Si potrebbe ottenere molto di più con le API di geocodifica, come modificare la presentazione della mappa utilizzando i vari stili di mappa forniti da Mapbox.

  • Il codice sorgente è disponibile su GitHub.

Risorse

  • “Geocodifica”, documentazione Mapbox
  • “Stili”, documentazione Mapbox
  • "Utilizzo di variabili Env nel codice lato client", in "Modalità e variabili di ambiente", Vue CLI