En esta entrada veremos cómo crear paso a paso un visor básico con la API Open Source Leaflet. Leaflet es una librería Javascript de código abierto para construir aplicaciones Web Mapping, desarrollada en primera instancia por Vladimir Agafonkin. A pesar de ser muy ligera, destaca por su sencillez, potencia y versatilidad, gracias en parte a su rico ecosistema de plugins. Es por ello que sitios como Flickr, Pinterest, Foursquare o Facebook -entre otros muchos- la utilizan en sus desarrollos.
En la página oficial de Leaflet, en la sección de descargas, encontraremos los detalles para obtener los archivos necesarios para trabajar con la librería. En este ejemplo nos descargaremos directamente una copia, aunque hay más opciones, como usar un CDN o utilizar un gestor de paquetes Javascript, como NPM. La copia recién descargada contiene varios archivos, aunque de éstos sólo necesitaremos leaflet.js, leaflet.css y la carpeta images. El primero contiene todo el código Javascript de la librería, mientras que el segundo es el archivo de estilos de la misma.
Antes de comenzar el proyecto crearemos una carpeta para alojarlo, con el nombre que queramos. Dentro vamos a añadir un par de carpetas más, una que llamaremos «js» (para el fichero leaflet.js) y otra «css» (para leaflet.css y la carpeta images), donde copiaremos los ficheros correspondientes. En la carpeta raíz del proyecto vamos a crear un documento HTML (index.html en este ejemplo) con nuestro editor favorito. Dicho documento deberá incluir en la cabecera la ruta relativa de los archivos leaflet.js y leaflet.css, para que puedan ser localizados cuando cargue la página. También hay que referenciar la ruta del script donde escribiremos el código del visor de mapas (en este caso se llama visor.js, pero puede ser cualquier nombre). Su aspecto inicial debería ser similar a este:
<!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, user-scalable=no"> <title>Mapa básico con Leaflet</title> <link rel="stylesheet" href="css/leaflet.css"/> <script src="js/leaflet.js"></script> </head> <body> <script src="js/visor.js"></script> </body> </html>
Ahora pasaremos a escribir el código del visor. Necesitaremos crear un fichero Javascript, de nombre visor.js (o el nombre que hayamos puesto en el html), que guardaremos en la carpeta «js» de nuestro proyecto. Lo primero que incluiremos será una nueva instancia del objeto map de Leaflet:
var mapa = new L.map('mi-mapa', { center: [20, 50], zoom: 2 });
Esto crea el marco donde aparecerán los mapas que carguemos. Debe incluir una referencia al ID del elemento HTML donde se anclará el mapa, que en este caso llamaremos «mi-mapa», por ejemplo. Para que sea efectivo, es necesario insertar también dicha referencia en nuestro fichero index.html, dentro de un elemento <div> que se situará entre las etiquetas <body>:
<body> <div id="mi-mapa"></div> <script src="js/visor.js"></script> </body>
El objeto map incluye una serie de opciones que podemos configurar. En este caso, hemos definido el centro de la vista del mapa en [20, 50], en coordenadas geográficas, y el nivel de zoom inicial en 2. También habrá que definir las dimensiones del marco que contendrá el mapa, por lo que es necesario definir el estilo del mismo. Para ello podemos añadir el siguiente código al final del fichero leaflet.css (o si lo preferís, crear una nueva hoja de estilo css):
#mi-mapa { width: 600px; height: 400px; }
Esta definición de estilo se inicia con una referencia a la id del elemento <div> que contiene nuestro mapa, y fija su altura y anchura en 400 y 600 píxeles respectivamente. Si probamos a ejecutar ahora la aplicación, veremos un marco vacío, con los controles de zoom únicamente. Es necesario añadir las capas a visualizar. En este ejemplo incluimos un par de capas, un callejero de OpenStreetMap y una capa de relieve de Stamen Maps. En ambos casos se trata de capas ráster, por lo que utilizaremos la clase TileLayer de Leaflet para añadir capas de este tipo:
var capaOSM = new L.tileLayer('http://tile.openstreetmap.org/{z}/{x}/{y}.png'); var capaRelieve = new L.tileLayer('http://tile.stamen.com/terrain/{z}/{x}/{y}.jpg'); capaRelieve.addTo(mapa); capaOSM.addTo(mapa);
Para instanciar correctamente una capa de tipo TileLayer se requiere de la URL del servicio de mapas correspondiente. Vemos una serie de parámetros entre llaves, que sirven para que la API pueda seleccionar el nivel de zoom y coordenadas de cada “tile” según sea necesario, ya que estos mapas se sirven mediante baldosas o teselas, en vez del mapa completo. La URL también incluye una referencia al formato de imagen de los tiles, que dependerá de cada proveedor (en este caso .PNG y .JPG). Para añadir las capas al mapa, tan sólo tenemos que emplear el método addTo( ) para cada una.
Si probamos ahora la aplicación, nos daremos cuenta de un problema: una de las capas se superpone a la otra y no deja ver lo que tiene debajo. Para solucionarlo necesitamos un mecanismo que permita desactivar una de las dos capas a voluntad, de manera que sólo se pueda mostrar una de ellas al mismo tiempo. Concretamente, utilizaremos un control de capas, que afortunadamente Leaflet integra de forma nativa. Primero borraremos una de las dos líneas con el método addTo( ) que hemos escrito justo antes, la que prefiramos, ya que no nos sirve de nada que se muestran ambas capas a la vez. Para implementar el control de capas, vamos a definir un grupo mediante un objeto en notación JSON, donde incluiremos el texto que debe mostrar cada capa y su nombre. Posteriormente añadiremos dicho grupo a un objeto de tipo L.control.layers:
var capasBase = { "Relieve": capaRelieve, "OpenStreetMap": capaOSM }; var selectorCapas = new L.control.layers(capasBase); selectorCapas.addTo(mapa);
Este tipo de control soporta también un grupo adicional de capas de tipo overlay. Mientras que en el grupo de capas base sólo se puede visualizar una en cada momento, las capas que se incluyan en el grupo overlay permitirán activar y desactivar su visualización de forma independiente, lo que es útil para mostrar elementos como marcadores, polígonos, rutas, etc…, ya que no interfieren entre sí como lo haría una capa base.
Si todo ha ido bien, cuando carguemos la aplicación deberemos ver un control de capas en la esquina superior derecha, donde podremos seleccionar que capa base queremos ver en cada momento. Finalmente, nuestro pequeño visor deberá tener un aspecto similar a este:
Por último, os animo a participar en nuestro curso de Desarrollo de Aplicaciones Web GIS Open Source con Open Layers y Leaflet, donde aprenderéis a desarrollar visores como éste, agregar todo tipo de controles, personalizar el estilo y mucho más.
Hola, muy bueno el articulo, por lo que me animo hacerte una pregunta, como puedo crear un visor, que al seleccionar un punto en el mapa, me permita mostrar un popup con la dirección exacta.Gracias
Hola Ariagna.
Lo que indicas se puede hacer mediante geocodificación inversa. Leaflet implementa un sistema de popups bastante sencillo de usar. Sólo quedaría obtener las coordenadas donde se generó el popup, y usarlas para hacer una geocodificación inversa (reverse geocoding). Este proceso consiste obtener la dirección más probable a partir de unas coordenadas. Existen diversos servicios que ofrecen geocodificación inversa y que puede usar Leaflet a través de plugins, como por ejemplo el Leaflet Control Geocoder (https://github.com/perliedman/leaflet-control-geocoder).
Ojo, el uso de algunos de estos servicios puede no ser totalmente gratuito, dependerá de cada proveedor. Una vez se obtiene la dirección, deberá incluirse como contenido en el popup.
Un saludo.
Hola buena tarde es un excelente articulo ya empece a replicarlo.
mi pregunta es la siguiente como pudo pasar la información de una capa de polígonos a un marcador que el usuario puso en el mapa, por ejemplo si mi usuario puso un teclado en un lago que en pop del marcador me aparezca el nombre del lago se puede hacer y si es tan amable de orientarme gracias!!
Hola Raymundo.
Quizá lo que necesitas es un popup. En Leaflet se puede vincular un popup a cualquier capa vectorial, mediante el método bindPopup. Cuando se abre, el popup obtiene la información del polígono que se ha seleccionado. Si en las propiedades del polígono figura el nombre del lago, en el popup podrás hacer que aparezca sin problemas.
Un saludo.
Hola Isaac, gracias por el tutorial.
Soy novato con leaflet.
Me he quedado anclado en los dos últimos javascripts. Hasta entonces todo estaba correcto.
Los he colocado en el html y no funciona.
Alguna recomendación?
Muchas gracias.
Isaac, lo solucioné añadiendo los dos javascript en «visor.js».
Claro, había que añadirlo en el archivo javascript.
Gracias.
una coansulta, si coloco varios poligos, pueddo selecionarlos solo algunos para sacar alguna indfromacion de ellos
Hola Yuri.
Depende de cómo quieras procesar esa información. Si se trata de una consulta simple de datos, usando el sistema de popup integrado de Leaflet podrás obtener la información de cada polígono que quieras ver.
En caso de querer hacer una selección de polígonos y luego procesar de algún modo esa información, deberías primero conseguir algún plugin para seleccionar geometrías (o hacerlo tú mismo).
Un saludo.
-hola muy buen tutorial, quiero saber como importar kml, o que me recomendarias para hacer una especie de IDE con leaflet y asp.net gracias
Hola Gus.
Para usar capas KML existen plugins que pueden hacer el desarrollo más fácil (por ejemplo este: https://github.com/windycom/leaflet-kml).
En cuanto a un IDE, es difícil hacer una recomendación concreta. Si te sientes cómodo desarrollando en asp.net, adelante, es una plataforma válida. En el caso de los servicios y bases de datos, solemos usar software open source. Para el servidor de datos geográficos, puedes usar Geoserver por ejemplo. Es gratuito y open source, y ofrece servicios WMS, WFS WCS, WPS… todo conforme a los estándares OGC. Además, se puede integrar muy bien con bases de datos PostGIS.
Un saludo.
Hola una consulta. Requiero marcar varios puntos sobre un mapa a partir de las coordenadas gps, delimitar el el área que comprende estos puntos, adicionalmente adicionar información a cada uno de estos puntos con etiquetas visibles. Cual seria la mejor opción para esta tarea? Agradezco su colaboración.
Hola Jorge.
Para mostrar puntos gps en el mapa puedes cargar una capa vectorial en formato GeoJSON con los puntos.
Si quieres mostrar etiquetas en cada punto, puedes usar por ejemplo la clase L.tooltip.
Hola Isaac! Una consulta, como puedo modificar la ubicación del selector de capas, ya que no tiene etiquetas en el HTML? Hay alguna manera de hacerlo igualmente desde el css? Muchas gracias!! Excelente guia
Hola Gustavo.
Internamente usa css para ubicarse, pero es más fácil si lo haces mediante programación, ya que en Leaflet hay ubicaciones predeterminadas para controles, donde quedan colocados perfectamente y con los márgenes correctos.
Esto es posible debido a que el control de capas integrado hereda de la clase L.Control. De esta manera, puedes usar los métodos de dicha clase (setPosition(), por ejemplo) para posicionarlo en distintas ubicaciones.
Hola, Isaac!
Gracias por el artículo. Una consulta, ha forma de que integre un visor de Cesium como una capa de mi Map? Saludos!
Isaac como puedo desarrollar una visor que me muestre dinamicamente puntos generados por GPS. Saludos
Eduardo desde Uruguay
Buenas tardes,
Le mandaremos información a su correo. Un saludo.
Hola, una consulta, como puedo visualizar la información de un raster utilizando leaflet, he instalado apache Tomcat y geoserver.
Gracias