Mapeando tus movimientos con React y Leaflet
Explorando nuevas zonas
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
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
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';
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'
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:
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';
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’;
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
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'
}
}
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);
}
En mi caso, el componente GeoJSON se queda de la siguiente manera
<GeoJSON
data={places2016}
pointToLayer={pointToLayer}
/>
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>
Este es el resultado final del componente:
Voilá, nuestro mapa estaría listo
Nos vemos en la próxima batalla!
🖖🏼