Transforma Direcciones en Coordenadas y Viceversa con Vue.js, OpenStreetMap y Leaflet: ¡Un Tutorial Práctico de Geolocalización! (APIS GRATUITAS)
— vuejs, geolocalización, tutorial, programación — 3 min read
Hola, ¿qué tal? 👋
En este tutorial, como bien dice en el titulo, veremos como transformar direcciones en coordenadas y viceversa usando una API gratuita que nos provee OpenStreetMap, por otro lado esto lo integraremos con otra capa de mapas, que también es gratuito y muy popular, Leaflet.
En esta ocasión usaré Vue.js, pero tengamos en cuenta que esto es aplicable a cualquier framework o librería de JavaScript.
¡Vamos a ello! 🚀
Si quieres seguir este tutorial, necesitarás:
- Conocimientos básicos de Javascript
- Node.js instalado en tu computadora
- Vue.js instalado en tu computadora
Paso 1: Crear un nuevo proyecto de Vue.js
Para comenzar, crearemos un nuevo proyecto de Vue.js. Para ello, ejecutamos el siguiente comando en nuestra terminal:
1npm install -g @vue/cli2vue create geolocalizacion-leaflet #(En este paso el proyecto por defecto de vue3 y usando npm)3cd geolocalizacion-leaflet
Paso 2: Instalar Leaflet y Axios
Axios nos ayudará a realizar peticiones a la API de OpenStreetMap, mientras que Leaflet nos ayudará a mostrar el mapa en nuestra aplicación. Instalamos ambas dependencias con el siguiente comando:
1npm install axios leaflet vue3-leaflet
Solo para asegurarnos que hasta ahora todo va bien, dentro de la carpeta de nuestro proyecto ejecutamos el siguiente comando:
1npm run serve
Si todo va bien, deberíamos ver algo así en nuestra terminal:
Y al ingresar a http://localhost:8080/
deberíamos ver algo como esto:
Paso 3: Crear un componente de mapa
Dentro de la carpeta src/components
creamos un nuevo archivo llamado Map.vue
y agregamos el siguiente código:
1<template>2 <div>3 <l-map ref="map" :zoom="zoom" :center="center">4 <l-tile-layer :url="url" />5 <l-marker :lat-lng="center"></l-marker>6 </l-map>7 </div>8</template>9
10<script>11import { LMap, LTileLayer, LMarker } from "vue3-leaflet";12import "leaflet/dist/leaflet.css";13
14export default {15 name: "MapComponent",16 components: {17 LMap,18 LTileLayer,19 LMarker20 },21 props: {22 center: {23 type: Array,24 required: true25 },26 zoom: {27 type: Number28 },29 },30 data() {31 return {32 url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"33 };34 },35 methods: {36 recenterMap() {37 setTimeout(() => {38 this.$refs.map.setZoom(this.zoom);39 this.$refs.map.setView(this.center);40 }, 100);41 }42 }43};44</script>45
46<style>47 div[center] {48 height: 80vh;49 }50 div#map {51 height: 80vh !important;52 }53</style>
Este componente utiliza vue3-leaflet
para mostrar un mapa de OpenStreetMap, con un marcador en el centro del mapa. A continuación, explicamos cada parte del componente:
la parte
1<template>2 <div>3 <l-map ref="map" :zoom="zoom" :center="center">4 <l-tile-layer :url="url" />5 <l-marker :lat-lng="center"></l-marker>6 </l-map>7 </div>8</template>
<l-map>
: Este componente es el contenedor principal del mapa. Se le pasan dos propiedades:zoom
ycenter
y adicionalmente tiene un ref para poder acceder a él desde el código.
zoom
: Es el nivel de zoom del mapacenter
: Es el centro del mapa, en este caso, la posición del marcadorref
: Referencia al mapa para poder acceder a él desde el código
<l-tile-layer>
: Este componente añade las capas de mosaicos (tiles) al mapa, utilizando una URL específica para obtener las imágenes. En este caso, estamos utilizando los mosaicos de OpenStreetMap.<l-marker>
: Este componente coloca un marcador en el mapa en las coordenadas especificadas porlat-lng
.
la parte
1<script>2import { LMap, LTileLayer, LMarker } from "vue3-leaflet";3import "leaflet/dist/leaflet.css";4
5export default {6 name: "MapComponent",7 components: {8 LMap,9 LTileLayer,10 LMarker11 },12 props: {13 center: {14 type: Array,15 required: true16 },17 zoom: {18 type: Number19 },20 },21 data() {22 return {23 url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"24 };25 },26 methods: {27 recenterMap() {28 setTimeout(() => {29 this.$refs.map.setZoom(this.zoom);30 this.$refs.map.setView(this.center);31 }, 100);32 }33 }34};35</script>
- Importaciones
LMap
,LTileLayer
yLMarker
: Componentes devue3-leaflet
que necesitamos para mostrar el mapa y el marcadorleaflet/dist/leaflet.css
: Estilos de Leaflet para que el mapa se vea correctamente
name
: Nombre del componentecomponents
: Componentes que estamos utilizando en este componenteprops
: Propiedades que recibe el componentecenter
yzoom
center
: Coordenadas del centro del mapazoom
: Nivel de zoom del mapa
data
: Datos del componente
url
: URL de los mosaicos de OpenStreetMap
methods
: Métodos del componente
recenterMap
: Método para centrar el mapa en las coordenadas especificadas porcenter
, se utiliza unsetTimeout
para asegurarse de que el mapa se haya renderizado antes de centrarlo
Por ultimo el bloque de estilos es para darle altura al mapa, en este caso le damos una altura de 80vh.
Paso 4: Crear un servicio de Geolocalización
Dentro de la carpeta src
creamos una nueva carpeta llamada services
y dentro de ella un archivo llamado geolocation.js
, en este archivo agregamos el siguiente código:
1import axios from 'axios';2
3const GEOCODE_API_URL = 'https://nominatim.openstreetmap.org/search';4const REVERSE_GEOCODE_API_URL = 'https://nominatim.openstreetmap.org/reverse';5
6export const geocode = (address) => {7 return axios.get(GEOCODE_API_URL, {8 params: {9 q: address,10 format: 'json'11 }12 });13};14
15export const reverseGeocode = (lat, lon) => {16 return axios.get(REVERSE_GEOCODE_API_URL, {17 params: {18 lat,19 lon,20 format: 'json'21 }22 });23};
Este servicio contiene dos funciones principales:
geocode
: Esta función recibe una dirección y realiza una petición a la API de OpenStreetMap para obtener las coordenadas correspondientes a esa dirección.reverseGeocode
: Esta función recibe una latitud y longitud y realiza una petición a la API de OpenStreetMap para obtener la dirección correspondiente a esas coordenadas.
Paso 5: Integrar el servicio de Geolocalización en el componente de mapa
Vamos a usar el archivo App.vue para integrar el componente de mapa y el servicio de geolocalización. Borramos todo el contenido desrc/App.vue
y agregamos el siguiente código:
1<template>2 <div id="app">3 <div class="input-container">4 <input v-model="address" placeholder="Enter an address" />5 <button @click="getCoordinates">Get Coordinates</button>6 </div>7 <div class="info">8 <p>Latitud: {{ coordinates.lat }}</p>9 <p>Longitud: {{ coordinates.lon }}</p>10 <p>11 Nombre de la dirección:12 {{ reverseResponse.display_name || "Busca una dirección" }}13 </p>14 </div>15 <MapComponent16 ref="mapComponent"17 :center="[coordinates.lat, coordinates.lon]"18 :zoom="zoom"19 />20 </div>21</template>22
23<script>24import { geocode, reverseGeocode } from "./services/geolocation";25import MapComponent from "./components/Map.vue";26
27export default {28 name: "App",29 components: {30 MapComponent,31 },32 data() {33 return {34 address: "",35 coordinates: {36 lat: 4.570868,37 lon: -74.297333,38 },39 zoom: 15,40 reverseResponse: {},41 };42 },43 methods: {44 async getCoordinates() {45 try {46 const response = await geocode(this.address);47 if (response.data && response.data.length > 0) {48 this.coordinates = {49 lat: parseFloat(response.data[0].lat),50 lon: parseFloat(response.data[0].lon),51 };52 this.$refs.mapComponent.recenterMap();53 const reverseResponse = await reverseGeocode(54 this.coordinates.lat,55 this.coordinates.lon56 );57 this.reverseResponse = reverseResponse.data;58 }59 } catch (error) {60 console.error("Error fetching coordinates:", error);61 }62 },63 },64};65</script>66
67<style>68#app {69 font-family: Arial, sans-serif;70 margin: 0 auto;71 padding: 20px;72}73
74.input-container {75 display: flex;76 gap: 10px;77 margin-bottom: 20px;78}79
80input {81 flex: 1;82 padding: 10px;83 font-size: 16px;84 border: 1px solid #8501B0;85 border-radius: 4px;86}87
88button {89 padding: 10px 20px;90 font-size: 16px;91 color: #fff;92 background-color: #8501B0;93 border: none;94 border-radius: 4px;95 cursor: pointer;96}97
98button:hover {99 background-color: #6a0186;100}101
102.info {103 margin-bottom: 20px;104}105
106.info p {107 margin: 5px 0;108 font-size: 16px;109}110
111l-map {112 border: 1px solid #8501B0;113 border-radius: 4px;114}115</style>
Este archivo contiene lo siguiente:
- Un campo de entrada para ingresar una dirección y un botón para obtener las coordenadas correspondientes a esa dirección.
- El componente
MapComponent
que recibe las coordenadas y el nivel de zoom del mapa. - Un objeto
coordinates
que contiene las coordenadas de la dirección ingresada por el usuario (por defecto, Bogotá, Colombia) y que es la respuesta de la API de OpenStreetMap al realizar una petición de geolocalización. - Un objeto
reverseResponse
que contiene la respuesta de la API de OpenStreetMap al realizar una petición de geolocalización inversa, usamos las coordenadas de la respuesta de la petición de geolocalización para obtener la dirección correspondiente. - El método
getCoordinates
que se encarga de llamar al servicio de geolocalización para obtener las coordenadas de la dirección ingresada por el usuario y de llamar al servicio de geolocalización inversa para obtener la dirección correspondiente a esas coordenadas. - Estilos para darle un aspecto visual a la aplicación.
Paso 6: Ejecutar la aplicación
Para ejecutar la aplicación, ejecutamos el siguiente comando en nuestra terminal:
1npm run serve
Si todo va bien, al ingresar a http://localhost:8080/
deberíamos ver algo así:
¡Y listo! Hemos creado una aplicación de geolocalización que transforma direcciones en coordenadas y viceversa utilizando Vue.js, OpenStreetMap y Leaflet.
Podemos ver que realmente no es complejo de implementar, tiene tiempos de respuesta muy rápidos y, además, ¡es gratuito!
Espero que este tutorial te haya sido de utilidad, y que puedas aplicar estos conocimientos en tus proyectos.
Repositorio del proyecto en GitHubNos vemos en línea