Skip to content
JoralmoPro
TwitterHomepage

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ón3 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/cli
2vue 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:

npm run serve

Y al ingresar a http://localhost:8080/ deberíamos ver algo como esto:

Resultado en el navegador

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:

Map.vue
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 LMarker
20 },
21 props: {
22 center: {
23 type: Array,
24 required: true
25 },
26 zoom: {
27 type: Number
28 },
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>
  1. <l-map>: Este componente es el contenedor principal del mapa. Se le pasan dos propiedades: zoom y center y adicionalmente tiene un ref para poder acceder a él desde el código.
  • zoom: Es el nivel de zoom del mapa
  • center: Es el centro del mapa, en este caso, la posición del marcador
  • ref: Referencia al mapa para poder acceder a él desde el código
  1. <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.

  2. <l-marker>: Este componente coloca un marcador en el mapa en las coordenadas especificadas por lat-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 LMarker
11 },
12 props: {
13 center: {
14 type: Array,
15 required: true
16 },
17 zoom: {
18 type: Number
19 },
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>
  1. Importaciones
  • LMap, LTileLayer y LMarker: Componentes de vue3-leaflet que necesitamos para mostrar el mapa y el marcador
  • leaflet/dist/leaflet.css: Estilos de Leaflet para que el mapa se vea correctamente
  1. name: Nombre del componente
  2. components: Componentes que estamos utilizando en este componente
  3. props: Propiedades que recibe el componente center y zoom
  • center: Coordenadas del centro del mapa
  • zoom: Nivel de zoom del mapa
  1. data: Datos del componente
  • url: URL de los mosaicos de OpenStreetMap
  1. methods: Métodos del componente
  • recenterMap: Método para centrar el mapa en las coordenadas especificadas por center, se utiliza un setTimeout 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:

src/services/geolocation.js
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:

  1. 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.
  2. 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:

App.vue
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 <MapComponent
16 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.lon
56 );
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:

  1. Un campo de entrada para ingresar una dirección y un botón para obtener las coordenadas correspondientes a esa dirección.
  2. El componente MapComponent que recibe las coordenadas y el nivel de zoom del mapa.
  3. 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.
  4. 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.
  5. 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.
  6. 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 GitHub

Nos vemos en línea