DEV Community

Cover image for Mapeando tus movimientos con React y Leaflet
Ayoze Barrera 🇮🇨 for Capua

Posted on • Originally published at Medium

Mapeando tus movimientos con React y Leaflet

Hoy en día usamos mapas para todo… para buscar direcciones, consultar cuál es el mejor camino a tomar para llegar a un punto en concreto, para promocionar un local, o simplemente viajar desde casa (asi es, he visto a youtubers que se pasan horas dando vueltas por paises gracias a los mapas… y hacen visitas!)

Pues por ese motivo vamos a ver cómo podemos hacer un mapa con nuestros movimientos.

Moves

Moves app

Moves

Para registrar los movimientos, aunque hay otras, he usado la aplicación moves.

Moves se ejecuta en segundo plano y nos permite importar tus movimientos en diferentes formatos, y uno de ellos es geojson.

Para empezar nos vamos a la página web de moves. Allí nos permitirá importar lo registrado desde nuestro dispositivo.

Configuración

Lo primero será instalar los paquetes de leaflet y react-leaflet:

$ npm -i S leaflet react-leaflet
Enter fullscreen mode Exit fullscreen mode

React-leaflet lo que hace es cargar componentes pero sin renderizar nada, simplemente usa los métodos de leaflet en el lifecycle del componente.

Podríamos conseguir nuestro mapa sin react-leaflet pero lo he usado anteriormente y ayuda mucho.

El mapa

Ya estamos listos para empezar así que lo primero será importar los paquetes que vamos a necesitar.

import { Map, TileLayer } from 'react-leaflet';
import L from 'leaflet';
Enter fullscreen mode Exit fullscreen mode

De momento solo he importado dos componentes de react-leaflet: Map y TileLayer. Esto es lo básico que necesitarás para mostrar un mapa.

También he importado leaflet porque vamos a usar el método circleMarker para poder tratar los puntos de los geojsons de nuestros datos.

Map

Capa principal del mapa que controla el zoom, bordes y el centro. Lo que vayamos a representar en el mapa, lo pasaremos como hijos.

TileLayer

Componente que se encargará de mostrar los tiles correspondientes en base al zoom y al centro.

Este componente necesita la propiedad url que será al montarse.

Para este ejemplo, voy a usar un mapa en blanco y negro, pero puedes encontrar mas urls aquí.

https://stamen-tiles-{s}.a.ssl.fastly.net/toner/{z}/{x}/{y}{r}.png
Enter fullscreen mode Exit fullscreen mode

Ah! Antes de poder usar nuestro mapa, necesitaremos importar el css de leaflet, que puedes encontrar en su apartado de descargas.

Configurados estos dos componentes, deberíamos de tener algo muy parecido a esto:

Map

Tanto rollo para tener un mapa vacío?

Calma… ahora viene lo bueno 😁

Nuestros movimientos

Moves, aparte de ofrecerte muchos formatos, también te separa los datos en movimientos diarios, semanales, mensuales, anuales y por último, todos en un mismo fichero. Yo voy a utilizar mis lugares visitados separados por años. En concreto los de 2016, 2017 y 2018.

Para ello voy a usar una capa de GeoJSON de leaflet, que como no, también lo tenemos como componente en react-leaflet:

import { Map, TileLayer, GeoJSON } from 'react-leaflet';
Enter fullscreen mode Exit fullscreen mode

El siguiente paso sería importar los datos de nuestros movimientos:

import places2016 from './data/places_2016.js';
import places2017 from './data/places_2017.js';
import places2018 from './data/places_2018.js';
Enter fullscreen mode Exit fullscreen mode

Después, tenemos que usar el componente GeoJSON como un children más en nuestro component Map:

<Map style={styles.map} center={props.center} zoom={props.zoom}>
  <TileLayer url={props.url} />
  <GeoJSON
    data={places2016}
  />
</Map>
Enter fullscreen mode Exit fullscreen mode

Además de pasarle los datos a la capa GeoJSON, el componente necesita la propiedad style, que es una función que usará internamente para aplicar el style que queramos a cada elemento de nuestro geojson:

function getStyle(feature, layer) {
  return {
    weight: 1,
    opacity: 1,
    color: '#000'
  }
}
Enter fullscreen mode Exit fullscreen mode

Cuidado! La función anterior solo te servirá para elementos que NO sean de tipo Point.

Dentro de mis geojsons, solo tengo elementos de tipo Point, asi necesitaré utilizar una propiedad extra: pointToLayer.

const geojsonMarkerOptions = {
  radius: 4,
  fillColor: "#EE4266",
  color: "#000",
  weight: 0,
  opacity: 1,
  fillOpacity: 0.4
}

function pointToLayer(feature, latlng) {
  return L.circleMarker(latlng, geojsonMarkerOptions);
}
Enter fullscreen mode Exit fullscreen mode

En mi caso, el componente GeoJSON se queda de la siguiente manera:

<GeoJSON
  data={places2016}
  pointToLayer={pointToLayer}
/>
Enter fullscreen mode Exit fullscreen mode

Ya casi terminamos!

Como voy a representar tres geojsons diferentes, y quiero representarlos con diferentes colores, tengo que crear tres funciones diferentes de pointToLayer

<Map style={styles.map} center={props.center} zoom={props.zoom}>
  <TileLayer url={props.url} />
  <GeoJSON
    data={places2016}
    pointToLayer={pointToLayer2016}
  />
  <GeoJSON
    data={places2017}
    pointToLayer={pointToLayer2017}
  />
  <GeoJSON
    data={places2018}
    pointToLayer={pointToLayer2018}
  />
</Map>
Enter fullscreen mode Exit fullscreen mode

Este es el resultado final del componente:

Voilá, nuestro mapa estaría listo:

Finished map

Nos vemos en la próxima batalla!

🖖🏼

Discussion (0)