OpenLayers es una API JavaScript para Web Mapping extraordinariamente potente, que además es Open Source y, por supuesto, completamente gratuita. Esto la diferencia de otras grandes librerías de mapas como las de Google Maps o ESRI, ya que éstas requieren del pago de ciertos servicios si se desea utilizar todo su potencial.
Con la API OpenLayers es posible crear controles personalizados de forma sencilla, lo que resultará muy útil para nuestros proyectos. En esta entrada del blog, voy a describir paso a paso como incorporar un control para cambiar la proyección del mapa. De forma nativa, OpenLayers soporta dos proyecciones: EPSG:3857 y EPSG:4326 (aunque es posible añadir muchas más). Ambas son parte del datum WGS84, de ámbito mundial, aunque la primera es una variante proyectada, mientras que la segunda utiliza coordenadas geográficas.
La idea es crear un botón en la esquina superior izquierda del mapa que permita alternar la proyección. El primer paso será crear un documento HTML en el que se cargará la API OpenLayers, mediante un CDN por simplicidad. En el documento habrá que crear un elemento <div> para contener al objeto Mapa, así como una sección <script> donde alojaremos el código.
<!DOCTYPE html> <html> <head> <title>Control personalizado</title> <link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css"> <script src="https://openlayers.org/en/v4.6.5/build/ol.js"></script> <style> body { margin: 0 } #mapa { width: 100vw; height: 100vh; } </style> </head> <body> <div id="mapa"></div> <script> var miMapa = new ol.Map({ layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], target: 'mapa', view: new ol.View({ center: [0, 0], zoom: 2 }) }); </script> </body> </html>
Con este documento, ya es posible visualizar un marco con un mapa funcional. Utilizando la sintaxis básica de creación de una mapa con OpenLayers, se ha instanciado un nuevo objeto Mapa dentro de la variable miMapa. Sólo se representará una capa, OpenStreetMap, mediante Tiles. Dado que no se especifica ninguna proyección, OpenLayers usará EPSG:3857 por defecto. Se han incluido algunas reglas CSS en la sección <style>, para eliminar el margen por defecto de 8 píxeles del cuerpo del documento, así como para indicar que queremos que el mapa ocupe toda el área disponible.
El siguiente paso será la creación del botón que representará a nuestro control. Para ello, vamos a generar un elemento <button>, al que añadiremos una función listener. Esta función se encargará de registrar los eventos en los que se presiona el botón (eventos “click”), para ejecutar la operación de cambio de proyección en respuesta a tal evento.
var boton = document.createElement('button'); boton.innerHTML = 'P'; boton.addEventListener('click', function () { var proyeccion = miMapa.getView().getProjection().getCode(); if (proyeccion == 'EPSG:3857') { proyeccion = 'EPSG:4326'; } else { proyeccion = 'EPSG:3857'; } var nuevaView = new ol.View({ center: [0, 0], zoom: 2, projection: proyeccion }); miMapa.setView(nuevaView); });
En la línea 35 se crea el elemento <button>, que almacenaremos en la variable boton. En la siguiente línea se indica que el contenido del botón sea texto simple, la letra “P”. También es posible incluir una imagen en vez de texto, lo que daría un aspecto aún mejor a nuestro control.
El siguiente bloque de código -a partir de la línea 37- se encarga de añadir el listener al botón. Consistirá en una función que evaluará la proyección actual del mapa y la cambiará por la proyección alternativa. Para ello, primero recupera la proyección del mapa a través de su View y obtiene el código identificador de la misma, que es lo que nos interesa. El bloque if else se encarga de decidir cuál será la nueva proyección basándose en la actual, de modo que si tenemos la EPSG:3587, se cambiará a EPSG:4326 y viceversa. En la última sección, se define una nueva View con la proyección que se aplicará y, finalmente, se incorpora al mapa.
El botón que acabamos de definir debe estar contenido dentro de un elemento <div>, al que asignaremos algunas clases CSS especiales de OpenLayers que permiten aplicar el estilo propio de la librería.
var elementoDiv = document.createElement('div'); elementoDiv.className = 'boton-cambiar-proyeccion ol-unselectable ol-control'; elementoDiv.appendChild(boton);
Como se puede ver en la línea 52, se han asignado tres clases al elemento <div> que hemos almacenado en la variable elementoDiv. Las dos últimas corresponden a clases propias de OpenLayers, que dan al botón el mismo aspecto que el resto de controles. Por otra parte, la clase CSS “boton-cambiar-proyeccion” la utilizaremos para poder aplicar un cierto estilo solamente a nuestro botón, sin afectar a los demás componentes. Para ello habrá que definir dicha clase en la sección <style> en la cabecera del documento HTML, incluyendo la siguiente declaración de estilo CSS:
.boton-cambiar-proyeccion { top: 70px; left: 0.5em }
Simplemente le indica al control que se mantenga a 0.5 em (el em es una unidad de medida basada en el tamaño de fuente) de distancia del borde izquierdo y a 70 píxeles del borde superior.
Ya solamente queda añadir el control al mapa, para lo que tenemos dos posibilidades. Se puede añadir directamente al cuerpo del documento HTML (o a algún otro elemento del documento), lo que lo convertiría en un elemento más, que llevaría a cabo la funcionalidad requerida. Otra opción, más conveniente, es añadirlo a través de la clase ol.control.Control de OpenLayers. De esta última manera, nuestro control personalizado formará parte del conjunto de controles del mapa. Esto presenta algunas ventajas, como la gestión automática de la propagación de eventos o la posibilidad de listar, incluir o eliminar los controles con métodos propios de la API.
var NuevoControl = new ol.control.Control({ element: elementoDiv }); miMapa.addControl(NuevoControl);
Utilizando la clase ol.control.Control, sólo es necesario indicar qué elemento HTML contiene nuestro control. Como último paso, solo queda visualizar el mapa y comprobar que funciona correctamente.
Si os ha resultado interesante esta entrada, os recomiendo nuestro curso de Desarrollo de Aplicaciones Web GIS Open Source con Open Layers y Leaflet, donde aprenderéis a realizar este tipo de desarrollos, tanto con OpenLayers como con Leaflet, otra librería de renombre en el mundo de Web GIS.
Formación de calidad impartida por profesionales
Deja tu comentario