Crear mapas con JavaScript y OpenLayers

En este artículo conoceremos las posibilidades que ofrece la librería OpenLayers para crear mapas interactivos con JavaScript y HTML5.

https://openlayers.org/ “A high-performance, feature-packed library for all your mapping needs.”

En éste artículo, he preparado un ejercicio práctico que hace uso de la librería. Haz click en la siguiente imagen para ver el resultado final en una ventana nueva:

Ejercicio Openlayers
Ejercicio Openlayers, haz click en la imagen para ver el resultado final del tutorial

¿Quieres aprender a hacer este ejercicio? Saltar directamente al tutorial

A través de nuestros smartphones, hemos normalizado el uso de productos digitales como Google Maps o Apple Maps.

Estos productos han pasado a formar parte de nuestro dia a dia, sin pararnos a pensar demasiado en la enorme complejidad técnica que conllevan.

Explicar cómo funciona toda la infraestructura y conjunto de capas tecnológicas que intervienen en ese proceso, escaparia al ámbito de éste artículo.

Sin embargo, sí que vamos ver cómo crear una aplicación web que muestre datos sobre un mapamundi con la librería OpenLayers.

Antes de entrar en materia, es importante familiarizarse con algunos conceptos clave en el desarrollo de estas funcionalidades.

Estándares, protocolos y formatos.

A lo largo de los últimos años, se han definido un conjunto de protocolos y formatos, que han terminado por convertirse en un estándar abierto.

Actualmente estos estándares actúan como base para el desarrollo y comunicación entre APIs

Uno de los ejemplos que mejor ilustra este tipo de tecnologías, es el proyecto OpenStreetMap. Se trata de un servicio gratuito para la creación y distribución de datos geográficos en todo el mundo.

Mediante el protocolo “Web Map Service” (o WMS), plataformas como OpenStreetMap, responden a peticiones de clientes. Entregando datos referenciados geográficamente, en forma de imágenes digitales.

Estas imágenes, pueden llegar en distintos formatos, tales como PNG, GIF, JPEG o incluso como gráficos vectoriales SVG.

OpenLayers nos va ayudar a manejar estas peticiones, y a mostrar en pantalla el resultado obtenido.

Habiendo definido un poco el marco tecnológico en el que opera esta librería, podemos pasar a ver más en detalle sus características y funcionamiento.

Su repositorio en Github, está activamente mantenido por un equipo de 308 desarrolladores desde hace más de tres años, y acumula casi 8600 estrellas.

Captura de pantalla del repositorio
Captura de pantalla del repositorio a finales de 2021

Se deduce entonces, de que se trata de una librería con mucha notoriedad y altamente fiable.

Por supuesto, está disponible para ser instalada mediante el comando “npm install ol –save”. El cual nos va a permitir importar múltiples clases, convenientemente organizadas en varios directorios.

Tal y como su nombre sugiere, OpenLayers ofrece la posibilidad de renderizar recursos obtenidos de servicios web, y organizarlos en capas superpuestas.

Existen capas de muchos tipos, sin embargo, para simplificar este vistazo a la librería, vamos a destacar las dos más comunes “TiledLayers” y “VectorLayers”.

Se tratan de dos capas que, por un lado, sirven para cargar imágenes en forma de “losetas” geoposicionadas. Y por el otro, renderizar gráficos vectoriales sobre puntos del mapa.

¿Cómo crear mapas con OpenLayers y su API?

Para empezar a trabajar con su API, creamos una instancia de la clase Map. Ésta admite un objeto con las tres propiedades básicas que vamos a describir a continuación. 

“Target” hace referencia al id del contenedor dónde queremos construir el mapa en nuestro DOM.

La propiedad “view”, espera una instancia de la clase con su mismo nombre. La cual nos va a permitir controlar propiedades del visor del mapa como el zoom o las coordenadas de latitud y longitud del punto central.

Y finalmente, “layers”, que espera una array de objetos instanciados de clases que OpenLayers nos ofrece para cada tipo de capa, como por ejemplo, “TileLayer”.

Construir un mapa que con “losetas” obtenidas de OpenStreetMap, es tan sencillo como ejecutar el siguiente código.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.9.0/css/ol.css" type="text/css">
    <style>
      .map {
        height: 400px;
        width: 100%;
      }
    </style>
    <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.9.0/build/ol.js"></script>
    <title>OpenLayers example</title>
  </head>
  <body>
    <h2>My Map</h2>
    <div id="map" class="map"></div>
    <script type="text/javascript">
      var map = new ol.Map({
        target: 'map',
        layers: [
          new ol.layer.Tile({
            source: new ol.source.OSM()
          })
        ],
        view: new ol.View({
          center: ol.proj.fromLonLat([37.41, 8.82]),
          zoom: 4
        })
      });
    </script>
  </body>
</html>

En el apartado documentación de la página oficial de OpenLayers, podemos estudiar más detenidamente todos los métodos y propiedades de las clases.

A pesar de que la documentación es muy detallada, es ampliamente recomendable perderse por el apartado de ejemplos, donde se puede ver acción muchas de las capacidades de la librería.

Estos son algunos de los ejemplos que podemos encontrar como referéncia para crear mapas con JavaScript y OpenLayers.

mapa de seísmos
Mapa de seísmos
Gráficos vectoriales geolocalizados sobre el mapa con JavaScript y OpenLayers
Gráficos vectoriales geolocalizados sobre el mapa con JavaScript y OpenLayers
Representación de un recurso WMS
Ejemplo de petición a un recurso WMS

Es evidente que OpenLayers es una herramienta muy potente, desarrollar cualquier aplicación web que requiera representar mapas dinámicos, sería prácticamente inviable sin librerías como ésta.

¿Cómo crear mapas con JavaScript y OpenLayers?

Para ilustrar un poco las capacidades de la librería, crearemos una pequeña aplicación web que muestre distintas capas de información sobre el mapa de Catalunya, con datos extraídos de la web oficial de l’Institut Cartogràfic i Geològic de Catalunya.

El sitio nos ofrece un conjunto de recursos abiertos preparados para ser llamados directamente desde nuestra aplicación.

En este caso, vamos a recuperar y a mostrar datos relativos al devastador incendio que hubo en 2019, en la región de Ribera de Erbe, donde unas 5.046 hectáreas fueron arrasadas.

Empezaremos por preparar un simple layout HTML con unos sencillos estilos CSS.

<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>OpenLayers</title>
</head>
  <body>
    <div id="map" class="map-wrapper"></div>
  </body>
</html>

Solo se requiere de una div con id, y con una clase CSS que la acomode al alto y ancho de la pantalla.

@import "ol/ol.css";
body {
  margin: 0;
  padding: 0;
}
.map-wrapper {
  height: 100vh;
  width: 100%;
}

Ahora sí, el comportamiento con JavaScript

A continuación, definiremos el comportamiento mediante Javascript, empezando por cargar un conjunto de clases de la librería OpenLayers.

import "./SCSS/index.scss";
import { Map, View } from "ol";
import { Tile } from "ol/layer";
import { OSM, TileWMS } from "ol/source";
import { fromLonLat } from "ol/proj";
import GUI from "lil-gui";

Crearemos distintas capas instanciando la clase “Tile”, y en cada una de estas, definiremos su propiedad “source”.

Inicialmente cargaremos una que contiene el recurso de “Open Street Map”.

“Open Layers” viene con una clase convenientemente preparada para evitarnos tener que buscar los parámetros de configuración de ese recurso.

const tileLayerOSM = new Tile({
  source: new OSM(),
});

Sin embargo, para las capas obtenidas del Institut Cartogràfic i Geològic de Catalunya, vamos a instanciar la clase “TileWMS”, y vamos a definir las propiedades projection, url y params.

Adicionalmente a la capa de OSM, vamos a superponer tres capas más, una que muestre información topográfica de toda Catalunya, otra con imágenes de satélite, para ver la vegetación de la región en 2019, y finalmente una capa con la porción afectada por el incendio.

const tileLayerTopoCat = new Tile({
  source: new TileWMS({
    projection: "EPSG:25831",
    url: "https://geoserveis.icgc.cat/icc_mapesmultibase/utm/wms/service?",
    params: {
      LAYERS: "topo",
    },
  }),
});
const tileLayerSummer2019Cat = new Tile({
  source: new TileWMS({
    projection: "EPSG:25831",
    url: "https://geoserveis.icgc.cat/icgc_sentinel2/wms/service?",
    params: {
      LAYERS: "sen2rgb_mosaic_estiu_2019",
    },
  }),
});
const tileLayerFire2019Cat = new Tile({
  source: new TileWMS({
    projection: "EPSG:25831",
    url: "https://geoserveis.icgc.cat/servei/catalunya/incendis/wms/service?",
    params: {
      LAYERS: "20190701-RiberaEbre-orto15cm-rgb",
    },
  }),
});

Ya con el conjunto de capas preparado, podemos crear un objeto con la clase “Map”, éste espera tres propiedades básicas, “target” con el id de la div contenedora, “layers” como una array de las capas creadas anteriormente, y view, una instancia de la clase “View”, para controlar en qué punto del mapa empezar y el zoom de inicio.

const map = new Map({
  target: "map",
  layers: [
    tileLayerOSM,
    tileLayerTopoCat,
    tileLayerSummer2019Cat,
    tileLayerFire2019Cat,
  ],
  view: new View({
    center: fromLonLat([0.600712, 41.280345]),
    zoom: 12,
  }),
});

Finalmente utilizaremos la librería “lil-gui”, de la cual hablamos en su ocasión, para generar una rápida interfaz de usuario, que permita activar y desactivar capas, y definir el porcentaje de opacidad de la capa de incendio.

Mi experiencia con OpenLayers.

Personalmente, descubrí OpenLayers trabajando en la creación de una aplicación de representación de datos, relativos al índice de la calidad del aire, en regiones de España.

Recuerdo que durante la fase de planteamiento del proyecto, me sentí abrumado por la aparente complejidad que suponía representar este tipo de datos sobre un mapa interactivo. 

Sin embargo, conforme iba estudiando las posibilidades que ofrecía la librería, me iba dando cuenta de que estaba todo perfectamente relacionado, OpenLayers resolvía a medida, prácticamente todas las necesidades para crear mapas con JavaScript y OpenLayers, sin que tuviera que reinventar la rueda.

Creo que ésta experiencia, cuenta más que cualquier análisis personal que pueda aportar.

Este ha sido un pequeño vistazo a la librería OpenLayers. A continuación os dejo enlaces a más recursos, así como el ejercicio subido al repositorio de Github de “Librerías Js”.

Nos vemos pronto, un abrazo desarrolladores!

Deja un comentario