Pon un mapa del globo terráqueo en tu web

1
434

En este tutorial veremos varias alternativas para poner un mapa del globo terráqueo en nuestra web y añadir marcadores y otros elementos a nuestro gusto.

Índice de contenidos.

Introducción

Hace poco he tenido que investigar cómo mostrar un mapa del globo en una aplicación web y creo que es lo suficientemente interesante como para compartirlo aquí. La idea es dar una pequeña explicación de qué es lo que se está buscando, qué herramientas hay, comentar ligeramente cómo funcionan y las diferentes alternativas que tenemos.

Destacar que yo soy desarrollador backend, por lo que mis conocimientos de front y en especial de Javascript son bastante limitados. Pero mientras se entienda la idea estoy seguro que alguien con más conocimientos que lea esto será capaz de implementarlo de una mejor manera.

¿Qué pinta tiene un mapa del globo?

Estoy seguro que muchos habremos trabajado en algún momento con mapas. Algo del estilo de lo que vemos habitualmente en Google Maps. Pero ese mapa es plano. El mismo que podemos tener  en la pared y nos acercamos para verlo en detalle, pero al alejarnos seguimos estando ante una visión rectangular del planeta.

Mapamundi plano

Lo que buscamos nosotros es algo distinto. Empezar con una visión de todo el globo, como si estuviéramos viendo el planeta desde el espacio. Y a partir de ahí ya acercarnos a donde queramos. El efecto es mucho más llamativo así y las animaciones cuando cambias de un punto a otro se ven mucho mejor.

Además tiene una ventaja en la representación del terreno. Esto es solo un dato curioso, así que si tienes interés solo en lo técnico puedes ir a la siguiente sección.

El mapamundi plano que conocemos todos, y el más usado, sigue el modelo de Mercator. Sin entrar en detalles de cómo está hecho, las imposibilidad de transportar la superficie de una esfera (y encima irregular como la Tierra) a un plano de dos dimensiones causa que haya deformaciones. En concreto en este modelo cuanto más nos acerquemos a los polos más grandes parecen los terrenos.

El ejemplo que se suele poner es Groenlandia, que según el mapa en el que se mire puede llegar a parecer casi del tamaño de África pero en realidad cabría 15 veces en él y España tiene casi la misma longitud de este a oeste. Aunque también hay otros casos curiosos como que Brasil no es tan pequeño como parece y no se aleja tanto de la extensión de Rusia. Incluso hay una web que permite comparar los tamaños reales de los países entre sí ajustando su tamaño según los arrastramos por el mapa.

Como decía os lo cuento por curiosidad pura y dura y no tiene nada que ver con lo que vamos a hacer aquí, pero no deja de ser interesante y una de las cosas que permite los mapas como los que vamos a usar nosotros es que no se produce esta distorsión.

La Tierra desde el espacio

Pero volvamos a lo que nos ocupa…

¿No podemos usar Google Earth para esto?

Empecemos por lo obvio. Si queremos mostrar algo como lo que tenemos al abrir Google Earth, ¿por qué no lo intentamos usar? De hecho lo primero que busqué fue una API, pues suponía que habría algo similar a lo que ofrece Google Maps. Aunque pudiera ser de pago al menos sería un punto de partida o podría hacer una prueba de concepto. Pero no es así. En efecto, Google Earth tuvo en su momento una API pero la deprecaron a finales de 2015 porque estaba desarrollada sobre una tecnología que tenía fallos de seguridad. Desde entonces no la han vuelto a desarrollar. Tienen algunas herramientas con las que se integra y que se pueden usar de forma gratuita si no se hace con fines lucrativos y se puede tratar con ellos el usarlo para un negocio. Pero son para tareas como la analítica de datos o la generación de animaciones y vídeos, lo que se aleja mucho de nuestro objetivo. Lo más parecido es Google Earth Enterprise, que nos permite tener una versión liberada de Google Earth en nuestro servidor, pero tampoco es lo que buscamos.

En un futuro habrá que tener en cuenta en este aspecto a Google Maps. En verano del pasado 2018 cambiaron la versión de escritorio para que al quitar zoom llegásemos al mapa esférico en lugar de al tradicional. Lamentáblemente desde entonces aún no han migrado al resto de plataformas, por lo que por el momento no nos sirve como solución. No obstante bastante gente se lo ha pedido ya e imagino que en algún momento lo acabarán implementando de forma genérica.

Pero por el momento no nos queda otra que buscar una forma distinta de lograrlo.

Las alternativas que tenemos

Haciendo una búsqueda un poco exhaustiva me he encontrado con varias herramientas que pueden sernos de utilidad, aunque aquí solo voy a comparar las tres que me han parecido más interesantes.

CesiumJS

La primera opción con la que os encontréis seguramente será CesiumJS. Una herramienta web open source y gratuita que permite mostrar un mapa del globo terráqueo y hacer un montón de cosas con él. La cantidad de opciones es apabullante: desde ponerle simplemente un par de marcadores hasta crear modelos 3D o moverlos por el mapa. Además tienen bastantes ejemplos en su web con el código fuente que usan, lo que junto a la documentación que tiene hace que a priori no parezca excesivamente complicado desarrollar con él.

El único problema, por llamarlo de alguna forma, que tiene es que parte de las opciones no son enteramente gratuitas. Por debajo se conecta al servidor de Cesium Ion, que es donde se hacen cálculos y se guardan assets como los modelos 3D. Además tiene privados una parte de los mapas que se pueden visualizar sobre el globo. Sin embargo, aún así tendremos a nuestra disposición los mapas de Mapbox, OpenStreetMap y ESRI, que tienen una calidad bastante buena.

Sobre la licencia, tiene 3 tipos de cuentas. La Community es gratuita y nos permite trabajar con ella siempre que sea para uso personal y no para un negocio. Además tiene algunos límites, pero nada especialmente serio de primeras. Luego hay dos cuentas para uso comercial, que básicamente se diferencian en el precio y en el límite de almacenamiento y peticiones.

En principio, si solamente queremos ver el globo y añadir marcadores, los mapas de Mapbox van muy bien y no necesitaríamos contratar Cesium Ion. Pero creo que está bien comentarlo por si a alguien le pudiese ser de utilidad.

Vamos a ver un ejemplo muy sencillo de su uso.

El código es realmente sencillo:

  1. Importamos los ficheros js y css de Cesium.
  2. Ponemos un css para que el mapa ocupe toda la pantalla.
  3. Creamos el div donde vamos a tener nuestro mapa.
  4. Creamos el script que vamos a usar.
    1. Definimos el token de acceso a Cesium Ion, que se puede no hacer y usar el de por defecto.
    2. Inicializamos el viewer asociándolo al nombre del div que creamos antes. Los parámetros booleanos son simplemente para quitar muchos componentes de la interfaz que vienen por defecto y yo quería que apareciese lo más simple posible. Se inicializa el proveedor del mapa, en este caso se inicializar el de Mapbox para usar el mapa mapbox.comic (luego veréis que el estilo visual es un poco raro, también tienen mapas normales). Toda esta llamada podría ponerse con valores por defecto y quedar simplemente en new Cesium.Viewer(‘cesiumContainer’) y seguiría funcionando.
    3. Añadimos un punto en el mapa indicando las coordenadas y las propiedades que queremos.
    4. Cambiamos la posición de la cámara para que empiece apuntando a una zona desde la que se ve mejor el punto que hemos añadido.

Si lo abrimos en nuestro navegador nos quedará algo como esto:

Resultado del código de CesiumJS

Tenemos un mapa completo al que le he dejado los widgets de buscar una ciudad y ayuda. En el mapa además está el punto que hemos creado y la cámara aparece donde le hemos dicho. Además si pinchamos en el punto se acerca automáticamente. Obviad que la combinación de colores no es la mejor del mundo, pero por algo me dedico al backend.

Como veréis ha sido muy fácil inicializarlo y añadir un punto donde hemos querido. Y se podría haber hecho incluso con menos código de haber querido dejarle la interfaz que trae por defecto.

WebGL Earth

Otra alternativa completamente gratuita que permite mostrar un mapa básico y hacer cosas simples con él es WebGL Earth. Por debajo utiliza precisamente Cesium para renderizarlo todo, por lo que visualmente no se diferencia mucho de él. Lo único destacable en este aspecto es que el comportamiento por defecto difiere en que no le añade la interfaz que a mí a priori me parece innecesaria.

Es bastante fácil de usar, pero ello se debe en parte a que es muy limitado. Así como Cesium tiene muchísimas opciones y seguramente no se llegue a necesitar ni la mitad para algo medianamente complejo, WebGL Earth peca de lo contrario. Solamente nos deja visualizar el mapa, añadir nuevas capas y visualizar marcas o polígonos. Da bastante juego solo con esto y es muy sencillo de usar, pero puede que se quede corto si se quiere algo complejo.

Vamos a ver también un ejemplo de cómo utilizar WebGL Earth para lograr algo muy similar a lo que teníamos con Cesium.

El procedimiento es muy similar al que teníamos en Cesium:

  1. Cargamos el js de la herramienta.
  2. Ponemos un css para que el mapa ocupe toda la pantalla.
  3. Creamos el div donde vamos a tener nuestro mapa.
  4. Y por último el script.
    1. Creamos el mapa con las opciones por defecto que queremos y lo asociamos al div que ya tenemos. En este caso las opciones de la vista se inicializan aquí, junto con otras opciones visuales.
    2. Añadimos la capa con el mismo mapa de Mapbox que usamos en el ejemplo anterior.
    3. Añadimos un marcador con un pop up. WebGL Earth no tiene la funcionalidad de añadir puntos como lo hace Cesium, así que esta es la aproximación más similar que he encontrado. Se podría cambiar el icono para que fuese un círculo y quitar el popup, pero considero que para el ejemplo es suficiente así.

Si abrimos el código anterior en el navegador nos encontraremos con esto, aunque inicialmente el popup está cerrado hasta que no hacemos click en el marcador.

Resultado del código de WebGL Earth

El resultado es muy similar a lo que hemos conseguido con Cesium, por lo que para casos básicos podría ser suficiente.

Open Globus

La tercera de las opciones es Open Globus, una herramienta muy similar a las anteriores. Es gratuita, completamente open source y la API es bastante extensa. Además tiene varios ejemplos de las distintas opciones que permite implementar.

Lo que sí es que con esta herramienta me he encontrado dos problemas. El primero es que, al menos en los ejemplos que he podido hacer, el zoom no está demasiado bien afinado, se mueve excesivamente rápido y cuando la vista se aleja un poco la Tierra desaparece y en ocasiones es necesario recargar la página. El segundo es que no todos los ejemplos que tienen funcionan como se presupone se puede ver como falla al cargar algunos recursos, o al menos no lo hacen en mi navegador. Es posible que sea solo un tema de configuración. Desde luego si funciona como debe es una alternativa muy fuerte a Cesium.

Aún con esos problemas tiene funcionalidades muy interesantes, como por ejemplo añadir una capa de vídeo sobre el mapa. Recomiendo echarle un vistazo aunque solo sea por curiosear.

Veamos con un ejemplo cómo se utiliza.

No os sorprenderá a estas alturas que sea bastante similar a los anteriores.

  1. Cargamos los recursos de Open Globus.
  2. Ponemos estilo al div que tendrá el mapa para que ocupe toda la pantalla.
  3. Definimos el div donde estará el mapa.
  4. Creamos el script.
    1. Inicializamos la capa con el mapa de Mapbox que hemos estado usando hasta ahora.
    2. Inicializamos el globo con ese mapa y lo asociamos al div que hemos creado. Lo único especial es que le he pasado qué controles específicos quería para no tener algunos que aparecían por defecto y no me interesaban. Desactivar el sol es para que no haya partes de noche, que a mí me resultaba un poco molesto.
    3. Creamos un vector con el marcador en la posición que queremos y lo añadimos al mapa. La imagen la tengo descargada y en la misma carpeta que el html.
    4. Ajustamos la cámara para que se inicialice en una posición desde la que se vea mejor el marcador. En teoría también debería ser posible solo con latitud y longitud del objetivo, pero esta opción me ha funcionado mejor.

El resultado, una vez más, es muy similar a lo que teníamos hasta ahora.

Resultado del código de Open Globus

La cámara tiene un ajuste ligeramente distinto y se ve más cercana desde el principio, también por variar un poco. Una de las cosas más llamativas es que uno de los controles que trae por defecto permite manejar el mapa con el teclado, lo cual viene muy bien. Sin embargo, como he dicho antes aunque la API está bien documentada los ejemplos no tanto y a veces puede llegar a costar encontrar lo que necesitamos.

Comparativa

Por terminar de ver las 3 opciones, aquí dejo una comparativa de lo que yo he podido ver.

Precio Opciones Facilidad de uso Problemas
CesiumJS De pago si queremos usar algunos mapas o guardar nuestros modelos en su servidor Bastantes opciones, algunas muy enfocadas al modelado 3D y que necesitan el servidor Muy fácil Limitado si no pagamos, pero bastante bueno igualmente.
WebGL Earth Gratuita Muy limitada Muy fácil Funcionalidad limitada
Open Globus Gratuita Muchas opciones, aunque no del todo bien documentadas Fácil, aunque un poco engorroso Algunos problemas con el zoom y ciertas funcionalidades.

En lo personal utilizaría una u otra en función de lo que necesitase para cada caso. Si nos vale simplemente con mostrar un mapa normal y añadir algunos marcadores o polígonos creo que WebGL es la más sencilla de usar. Si necesitamos algo más complejo entonces ya me plantearía usar una de las otras dos, analizando un poco más a fondo la API de cada una para ver cuál se ajusta mejor a lo que queremos. CesiumJS está más orientado a modelado 3D mientras que Open Globus parece tener más facilidad para trabajar con capas. Aunque quizá priorizaría CesiumJS porque parece un poco más estable.

¿Y eso de las capas? ¿Cómo las usamos aquí?

Ya hemos mencionado arriba algo sobre capas, pero creo conveniente pararnos aquí un poco.

Los mapas funcionan con capas, pero son un poco especiales con respecto a lo que podríamos tener en mente inicialmente. Están compuestas por una serie de tiles (o teselas) que se organizan de forma matricial. El conjunto de todas las tiles relacionadas se conoce como tileset.

Básicamente un tileset es el conjunto de datos necesarios para representar información geoespacial en un mapa, repartidos en una matriz de tiles que puede tener varios niveles de zoom. Estas tiles además pueden ser de tipo raster o vector. Es la misma distinción que se hace con las imágenes tradicionales. Las primeras son un mapa de bits donde la imagen se representa por la matriz de píxeles del color que corresponda. Suelen ser más detalladas y es la visión tradicional que se tiene de la imágenes. Por otro lado las segundas están definidas de forma matemática mediante vectores y suelen usarse por ejemplo para logos. Tienen la ventaja de no tener una pérdida de calidad apreciable al ampliar o reducir la imagen, se puede cambiar el estilo visual fácilmente y al ser de menor tamaño la descarga es más rápida.

Será más rápido si lo vemos en un ejemplo. A continuación os enseño la misma imagen, a la izquierda en formato de mapa de bits y a la derecha en formato vectorial. Podéis apreciar que el nivel de detalle es mayor en el mapa de bits porque cuanto mayor sea la resolución a más detalle se puede llegar a trabajar. En cambio en la versión vectorial se pierden los cambios fluidos de tonalidades y algunos detalles como los altavoces. Aunque es cierto que es una imagen vectorizada rápidamente por una herramienta que lo hace automáticamente solamente para este ejemplo, pero podría ser de mayor calidad.

Comparación tipos de imagen de lejos

Pero si ampliamos la imagen podemos ver que en efecto el mapa de bits pierde calidad cuando se pueden empezar a ver los píxeles individualmente mientras que no ocurre con los vectores porque se recalcula y adapta a la escala en la que se muestra.

Comparación tipos de imagen de cerca

Ahora sí, con independencia del tipo de tile con el que tratemos todas se usan de la misma forma. Cada tile contiene unas coordenadas específicas sobre el mapa. A medida que la vista se va moviendo alrededor del mapa la herramienta que lo renderiza pide las correspondientes coordenadas a lo que ve el usuario. ¿Cómo lo hace y de dónde las obtiene?  A la hora de definir un tileset se especifica una url parametrizada del estilo de http://server.url.com/tilsetId/{z}/{x}/{y}.jpg, en la que luego se sustituye por los valores concretos de la parte de mapa que se está mostrando. Veréis que además de latitud y longitud también suele incluirse la altura (eje z) para adaptarse al nivel de zoom aplicado en cada momento.

Pero aparte de la url hay otra serie de parámetros que se suelen configurar cuando se añade un nuevo tileset a un mapa. Entre ellos tenemos por ejemplo las coordenadas que lo limitan (pues por lo general no ocupan todo el globo), los niveles de zoom que admite o el porcentaje de opacidad.

Por lo general la forma de usar un nuevo tileset suele ser mediante una función que acepta la url base junto a un juego de parámetros opcionales. Sin embargo, también es posible hacerlo mediante un fichero TileJSON. Esto no es más que un estándar abierto para la representación de tilesets y sus metadatos. En muchos casos se aceptan ambos formatos.

Aquí vemos un ejemplo de un TileJSON de TileServer:

¿Qué proveedor de tilesets usar?

Ahora imagino que podréis tener dudas sobre qué proveedor de tilesets utilizar. Yo he estado haciendo algunas pruebas, principalmente porque al principio creía que había un problema de tiempos con algunas de las herramientas y resultó solo ser el proveedor. Los tres que he comparado han sido Mapbox, ESRI y OpenStreetMap; más que nada porque son los más usados y al venir por defecto en CesiumJS es muy sencillo cambiar de uno a otro en sus ejemplos.

La conclusión a la que he llegado es que entre los tres Mapbox es superior al menos en términos de velocidad. ESRI queda segundo y OpenStreetMap parece tener bastantes problemas en este sentido. Mapbox tiene mapas vectoriales, pero en los ejemplos anteriores hemos usado tiles raster y aunque no era instantáneo la velocidad era bastante buena. Así que se queda como mejor opción en lo que a tiempos se refiere. Es cierto también que los mapas OSM son más detallados y tiene algunos toques visuales que no tienen los demás. Pero aún así a mí personalmente no me compensa la diferencia en tiempo de carga.

Además hay herramientas como MapTiler que también tienen sus propios mapas y permiten también tener los tuyos propios. Mención especial a que en su entorno de pruebas podéis ver de primera mano la diferencia entre los tipos de tiles y cómo en las vectoriales se puede, por ejemplo, cambiar el idioma de los textos.

Pero no es la única manera de poner información en un mapa

Vale, ya hemos visto qué es una capa y cómo está definida mediante un tileset. Pero quiero que tengáis una cosa en cuenta antes de poneros a meter capas como locos. Lo de añadirlas es relativamente sencillo y casi todas las APIs parecen permitirlo. El problema no es tanto ese, como crear la capa en sí. Tened en cuenta que también hay que tener las imágenes (sean del tipo que sean) para cada una de las tiles, preferiblemente con varios niveles de zoom, configurarlas y subirlas a un servidor preparado para ello. Es cierto que se puede superponer una sola imagen o incluso en una imagen representar todo el globo, pero el resultado no es igual y sigue siendo un poco complejo. Y, sobre todo, no se puede cambiar de un momento para otro, pues son recursos estáticos que están alojados en un servidor.

En su lugar, si lo que queremos es mostrar en el mapa una serie de datos en tiempo real tenemos otra alternativa. Añadir programáticamente (depende de la herramienta concreta) marcadores, textos, imágenes e incluso modelos 3D es una opción perfectamente válida. A priori es sencillo, da mucha más flexibilidad y no limita a usar solo datos estáticos. Así que personalmente antes de meterme en líos creando capas nuevas recomiendo pensar qué es lo que necesitamos realmente y cómo podemos lograrlo de la manera más simple.

Conclusiones

Como habéis visto, usar mapas del globo es bastante llamativo, hay herramientas para lograrlo y no es en exceso complicado. Tiene limitaciones, por supuesto, como que no están pensados para el cálculo y representación de rutas. Pero si lo que queremos es mostrar puntos de interés que están por todo el mundo es una manera bastante interesante de hacerlo, sobre todo si están repartidos de tal manera que se fuerza el viajar entre sitios alejados. Desde aquí os animo a que intentéis usarlos, aunque sea por probar algo nuevo.

Imágenes

1 Comentario

  1. Aún siendo algo diferente a lo propuesto en el tutorial; creo que puede ser interesante como añadido a él…

    Estoy en una empresa de ticketing de vuelos; y para representar el volumen de trayectos y presentarlos via web nos basamos en esto:

    https://giojs.org/

    Para representar el numero de ventas de billetes de vuelo; nos basamos en esto:

    http://students.washington.edu/aodhan/webgl_globe.html

    En fin, más maneras de representar información… que es lo que se trata.

Dejar respuesta

Please enter your comment!
Please enter your name here