Leer ficheros GeoJSON

Pasos a seguir para leer información en formato GeoJSON desde las nociones más básicas hasta un ejemplo real

Anartz Mugika Ledo🤗
8 min readOct 28, 2022

En este artículo aprenderemos sobre la extensión GeoJSON, que es, los tipos y una vez que tengamos todo dominado nos embarcaremos en un ejemplo real donde consumiremos una API real y pintaremos con esa información en nuestro mapa de una manera super sencilla.

Si tenéis curiosidad por los mapas y concretamente trabajar con Leaflet os dejo más artículos relacionados (que irá ampliando):

Requisitos

Para empezar con ello, lo primero que necesitaremos es cumplir estos requisitos:

Una vez que ya cumplimos estos requisitos sencillos, vamos a por el apartado de leer ficheros con GeoJSON.

Antes de nada, si lo deseáis,. podéis iniciar el proyecto para tenerlo en marcha e ir haciendo los cambios y así poder ver el resultado paso a paso.

Para iniciar el proyecto, debemos de ejecutar:

npm start

Una vez ejecutado, se debe de abrir una nueva pestaña en nuestro navegador con esta apariencia:

La ubicación es añadida ya por defecto, pero si queréis practicar con alguna de vuestra zona, deberéis de ir a la línea donde se inicializar “mymap” del fichero index.ts que se encuentra de src/main y cambiamos las coordenadas.

import { Map } from 'leaflet';
import { startMapTemplate } from '../assets/template/content';
import { tileLayerSelect } from '../config/functions';
startMapTemplate(document, 'Plantilla - Mapa con Typescript');const mymap = new Map('map').setView([43.3082977, -1.9837398], 10); <=========
// Sustituimos 43... (latitud) y -1.88... (longitud)
tileLayerSelect().addTo(mymap);

Aclarado esto, para completar el objetivo, iremos paso a paso y lo primero que vamos a hacer es crear la base, es decir, donde se van a mostrar los elementos que compondrán la leyenda. El objetivo será lo siguiente lo que podéis encontrar:

GeoJSON — ¿Qué es?

Básicamente se puede decir que es un JSON mejorado y adaptado para representar elementos geográficos sencillos en nuestros mapas que tiene ciertas características dependiendo de los elementos que queremos dibujar en el mapa.

Tenemos dos tipos:

  • Geometrías primitivas
  • Geometrías compuestas

Geometrías primitivas

Aquí encontraremos los elementos simples como los “Point”, “LineString” y “Polygon”.

  • Point: son los puntos geográficos, que se utilizarán para indicar una posición sea con un marcador simple, marcador circular o círculo. Solo será un punto. En general, en librerías como Leaflet si detecta este elemento añade un marcador básico aunque también podremos personalizarlo como veremos en el siguiente artículo que publicaré próximamente.
  • LineString: Será una línea constituida por la unión de varios puntos (2 ó más). Por ejemplo, puede aparecer este tipo de elemento cuando vamos a trazar una ruta de senderismo o similares. Solo un elemento.
  • Polygon: Como su nombre indica será cuando tenemos añadido un polígono. Aquí también se incluyen los polígonos con huecos de manera interna. Solo un elemento. Por poner unos ejemplos de polígonos:
  • Triángulo: 3
  • Cuadrilátero: 4
  • Pentágono: 5
  • Hexágono: 6
  • Heptágono: 7
  • Octógono: 8
  • Eneágono: 9

Geometrías compuestas

Será prácticamente lo que se ha visto en las simples pero aquí ya tendremos siempre mínimo dos elementos.

  • MultiPoint: son los puntos geográficos, que se utilizarán para indicar una posición sea con un marcador simple, marcador circular o círculo tal y como se ha visto con “Point” pero en este caso habrá más de un punto.
  • MultiLineString: Serán varias líneas constituidas por la unión de varios puntos (2 ó más). Por ejemplo, puede aparecer este tipo de elemento cuando vamos a trazar una ruta de senderismo o similares. Mínimo dos líneas.
  • Polygon: Como su nombre indica será cuando tenemos añadido un polígono. Aquí también se incluyen los polígonos con huecos de manera interna. Solo un elemento. Por poner unos ejemplos de polígonos:

Una vez que tenemos claro los tipos de geometría que encontramos en los ficheros GeoJSON vamos a centrarnos en el proyecto.

Datos a utilizar

Para trabajar con los datos de tipo GeoJSON tenemos un montón de fuentes disponibles en repositorios Opendata y muchos otros lugares.

Para encontrar datos os recomiendo que busquéis “geojson datasets” y ahí tendréis bastantes resultados disponibles para practicar.

Yo me centraré en los datos relacionados a los terremotos a nivel mundial de las últimas 24 horas ofrecidos por el gobierno de los EEUU:

Y dentro de este apartado obtenemos esa información en un mapa interactivo:

Esto es lo que se visualiza, nosotros vamos a hacer un pequeño clon con esa información:

Si vamos a las herramientas de desarrollo, podemos obtener la fuente de datos desde la URL remota:

Por lo tanto, ahora ya tenemos la URL que necesitamos para obtener la información:

https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.geojson

Ahora lo que tenemos que hacer es instalar axios para poder descargar esa información y tratarla en nuestro mapa:

npm install axios

Una vez realizada la instalación, comenzamos con el proceso para pintar y obtener el resultado que se ha especificado en el primer punto.

Leer ficheros GeoJSON

Vamos a comenzar extrayendo la información desde la fuente:

import axios from 'axios';
import { Map } from 'leaflet';
import { startMapTemplate } from '../assets/template/content';
import { tileLayerSelect } from '../config/functions';
startMapTemplate(document, 'Plantilla - Mapa con Typescript');const mymap = new Map('map').setView([43.3082977, -1.9837398], 10);tileLayerSelect().addTo(mymap);// 1.- URL fuente de datos
const URL = 'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.geojson';
// 2.- Descargar datos de la fuente de datos
axios.get(URL).then(({data}) => {
console.log(data);
});
  1. Añadimos la URL con al fuente de datos
  2. Añadimos la llamada a la API y visualizamos el resultado y a su vez importamos para hacer uso de axios.

Si vamos a las herramientas de desarrollador podemos observar en “Red” que ya está consumiendo desde esa fuente de datos:

Y si vamos a la consola podemos ver el resultado de lo que hemos obtenido desde esa fuente de datos:

Asignamos la información descargada en el elemento geoJSON (3) que importaremos del paquete leaflet y donde tenemos más información aquí:

import axios from 'axios';
// 3.- Importar
import { geoJSON, Map } from 'leaflet';
...
axios.get(URL).then(({ data }) => {
// 3.- Asignamos en elemento "geoJSON"
const geoJsonValue = geoJSON(data).addTo(mymap);
});

Vamos a ver los cambios:

¿Que extraño no? Si miramos en las herramientas de desarrollador se está descargando la información y añadiendo todo correctamente, ya que no se aprecian errores.

¿Cómo que no se ve nada? Es sencillo. Si os fijáis tenemos fijado esta posición en el mapa con el nivel de zoom que se visualiza. NO HEMOS DICHO PARA CENTRAR EN BASE DE LA INFORMACIÓN.

Como no se ha dado ningún terremoto en esta zona no tenemos ningún elemento añadido, pero si alejamos la cámara hasta alejar lo suficiente para ver diferentes continentes, podemos observar lo que tenemos en la siguiente imagen:

Para centrarlo en base a la información vamos a usar la función “fitBounds” (4) y añadimos el siguiente código:

...axios.get(URL).then(({ data }) => {  const geoJsonValue = geoJSON(data).addTo(mymap);  // (4) Para centrar en base a la información del GeoJSON
mymap.fitBounds([
[
geoJsonValue.getBounds().getNorthEast().lat,
geoJsonValue.getBounds().getNorthEast().lng,
],
[
geoJsonValue.getBounds().getSouthWest().lat,
geoJsonValue.getBounds().getSouthWest().lng,
],
]);
});

Recargamos y podemos ver que ya tenemos la información cargada, de manera super fácil!!

Así a simple vista hemos podido indicar donde se han dado terremotos, pero no su información. Lo interesante sería añadir por elemento una ventana emergente (pop up).

Añadir pop up en un elemento individual de un fichero GeoJSON

Siguiendo la documentación oficial, en las opciones tenemos una propiedad llamada “onEachFeature” que servirá para añadir información de lo que nosotros queremos como pueden ser los popups o tooltips.

Añadimos la siguiente función

function bindPopup(feature: any, layer: any) {
layer.bindPopup(
"<h1>" +
feature.properties.mag +
"</h1><p>name: " +
feature.properties.place +
"</p>"
);
}

Vamos a explicar punto por punto que es cada apartado.

  • feature; Elemento individual dentro de la propiedades “features”. Aquí en este caso tenemos “geometry”, “properties” (que generalmente es donde están los datos adicionales de ese punto) y otras opciones.
  • layer: Elemento individual de la lista “features” propiedad => geometry
  • geometry: Esto será para indicar si es un punto (Point), una línea (LineString) o cualquier otro elemento visto al principio del artículo.

Las propiedades que tiene cada elemento en este ejemplo son las siguientes. Nosotros estamos usando la magnitud (mag) y el lugar donde ha ocurrido (place), pero como se puede observar, hay un montón de datos super interesantes:

Ahora, tenemos que añadirlo como propiedad del elemento geoJSON donde estamos trabajando.

...
function bindPopup(feature: any, layer: any) {
layer.bindPopup(
"<h1>" +
feature.properties.mag +
"</h1><p>name: " +
feature.properties.place +
"</p>"
);
}
axios.get(URL).then(({ data }) => { const geoJsonValue = geoJSON(data, {
// Añadir apartado del popup
onEachFeature: bindPopup
}).addTo(mymap);
//
...
});

Ahora si hacemos click en cualquiera de los elementos del mapa, podremos ver que muestra la información correspondiente a ese incidente:

Llegados a este punto ya sabemos como leer un fichero GeoJSON de manera fácil y también como añadirle un popup individual para complementar la información.

Próximamente haré una continuación de este artículo con este ejemplo para ampliarlo y mejorarlo, personalizando el tipo de elemento sustituyendo el marcador por defecto por marcadores circulares y personalizados con diferentes colores para mostrar visualmente las intensidades de los terremotos. Espero que os resulte interesante y os suscribáis a la lista de correo.

Os dejo como siempre el código fuente de lo trabajado:

Sería interesante que en los comentarios añadáis vuestros comentarios con vuestros ejemplos, ¡¡seguro que podemos aprender de otros ejemplos!!

Presencia en redes sociales.

Podéis encontrarme en las siguientes redes.

--

--

Anartz Mugika Ledo🤗

[{#frontend:[#mobile:{#android, #kotlin, #ionic}}, {#web:{#angular, #qwik, #bootstrap}}],{#backend: [{#graphql, #nestjs,#express, #mongodb, #mysql}]}]