easy-button: botones en mapas web de Leaflet

Leaflet es un librería JavaScript muy apreciada por su sencillez y ligereza que se emplear para crear mapas en la web. La «filosofía» de Leaflet consiste en presentar una librería ligera que contiene los elementos básicos para crear un mapa. Eso se complementa con muchos plugins que permiten añadir funciones al mapa. Es muy frecuente que necesites añadir botones en mapas web para que lancen alguna operación. Pues esto es muy sencillo utilizando el plugin easy-button.

Instalar el plugin easy-button

Para instalar el plugin podemos descargar los archivos de su página en GitHub, podemos utilizar NPM o lo que haremos en este caso, que es emplear un enlace CDN. El plugin dispone de un enlace CDN que nos permite utilizarlo sin necesidad de realizar ninguna descarga. En consecuencia, debemos incorporar a nuestro código los enlaces tal y como se indica en la documentación:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet-easybutton@2/src/easy-button.css">
<script src="https://cdn.jsdelivr.net/npm/leaflet-easybutton@2/src/easy-button.js"></script>

Algunos ejemplos de botones

El plugin easy-button tiene la siguiente estructura:

L.easyButton( '<span class="star">&starf;</span>', function(){
      
        Mi funcion;
    }).addTo(map);

Hacemos una instancia a la clase L.easyButton, a la que le proporcionamos una clase, en este ejemplo “star” y una función. Entre las llaves escribimos la función, que podrá ser cualquiera de los desarrollos que realicemos con Leaflet. Para finalizar, añadiremos el botón al mapa con el método addTo(map).

Un ejemplo muy sencillo es el que nos permite abrir una alerta en el mapa.

L.easyButton( '<span class="star">&starf;</span>', function(){
       alert('Has hecho clic en un botón del plugin easyButton');
    }).addTo(map);

Vemos en este ejemplo la estructura que describimos antes. Como función hemos añadido una alerta JavaScript que se abrirá al hacer clic sobre el botón.

El plugin easy-button está utilizando una clase que hemos llamado star a la que podemos asignarle estilos mediante CSS. Para hacer esto añadimos en el apartado de estilos lo siguiente:

.star{
      font-size: 1.5em;  
      color:red
    }

Simplemente hemos asignado un tamaño de fuente y un color al icono que se muestra en el botón:

Easy-button permite seleccionar el icono que queremos ver en el botón. En el ejemplo de la estrella hemos utilizado el icono &starf pero podemos elegir entre una amplia gama de iconos HTML que podemos ver en el siguiente enlace:

Vamos a escribir otro ejemplo en el que creamos un botón que nos inserta un popup o ventana emergente en el centro del mapa:

var helloPopup = L.popup().setContent('Hello World!');	
    L.easyButton('<span class="infinito">&infin;</span>', function(){
        helloPopup.setLatLng(map.getCenter());
        map.openPopup(helloPopup);
    }, 'abre un popup').addTo(map);

Aquí la función que se abre con la instancia a L.easyButton se encarga de abrir un popup. Primero hemos creado un objeto llamado helloPopup a partir de la clase L.popup(). Sobre ese objeto se aplican varios métodos referentes a esta clase:

  • setContent() indica el contenido del popup.
  • setLatLng(), indica las coordenadas donde se abrirá el popup. En esta ocasión lo hacemos en el centro del mapa utilizando getCenter().
  • openPopup() indica que el popup debe ser abierto sobre el mapa.

El plugin easy-button permite crear un texto que aparecerá al situar el ratón sobre el botón, es el texto que indicamos al final de la sentencia; ‘abre un popup’.

Al igual que hicimos antes, añadimos un estilo CSS para el botón. Observa que ahora hemos creado una clase “infinito” que utiliza el correspondiente icono HTML:&infin

A continuación, escribimos el código completo:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Easy-button</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css"/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet-easybutton@2/src/easy-button.css">
<style>
  	body {
    	  padding: 0;
    	  margin: 0;
    }
    html, body, #map {
        height: 100%;
        width: 100vw;
    }
    .star{
      font-size: 1.5em;
      color:red
    }
    .infinito{
      font-size: 1.5em;  
      color:blue
    }
</style>
</head>  
    <body>
 	<script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"></script>
 	<script src="https://cdn.jsdelivr.net/npm/leaflet-easybutton@2/src/easy-button.js"></script>

    <div id ="map"> </div>
    <script>
    var map = L.map('map', {center: [40.965, -5.664],zoom: 16});
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);	
    var helloPopup = L.popup().setContent('Hello World!');

    L.easyButton('<span class="infinito">&infin;</span>', function(){
        helloPopup.setLatLng(map.getCenter());
        map.openPopup(helloPopup);
    }, 'abre un popup').addTo(map);

    L.easyButton( '<span class="star">&starf;</span>', function(){
       alert('Has hecho clic en un botón del plugin easyButton');
    }).addTo(map);

    </script>
    </body>
</html>

Definir estados de los botones

Para finalizar este artículo de creación de botones en mapas web con el plugin easy-button, vamos a ver una propiedad del plugin que nos permite hacer botones más prácticos. Hemos visto cómo podemos crear un botón que abre una función, es decir, que despliega una acción sobre el mapa. Pero en la práctica necesitamos que realicen funciones on/off es decir que “enciendan” y “apagen” la aplicación. Esto lo podemos controlar con los “estados” del plugin easy-button.

Veamos un ejemplo:

<script>
    var map = L.map('map', {center: [40.965, -5.664],zoom: 16});
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);

        
var helloPopup = L.popup().setContent('Hello World!');

var toggle = L.easyButton({
  states: [{
    stateName: 'add-popup',
    icon:  '<span class="star">&starf;</span>',
    title: 'añadir popup',
    onClick: function(boton) {
     helloPopup.setLatLng(map.getCenter()).openOn(map);
      boton.state('remove-popup');
    }
  }, {
    stateName: 'remove-popup',
    icon:  '<span class="flecha">&larrpl;</span>',
    onClick: function(boton) {
      map.removeLayer(helloPopup);
      boton.state('add-popup');
    },
    title: 'eliminar popup'
  }]
});
toggle.addTo(map);

</script>

En este código sustituimos las instancias a L.easyButton que teníamos en el ejemplo anterior por el objeto toggle que es el que llama a la clase L.easyButton. La clave está en la opción states que es la que nos permite definir dos estados para el botón y en consecuencia dos iconos y dos funciones. En el primer estado que hemos llamado add-popup, utilizamos la clase “star” y la función que se encarga de añadir el popup. Además, activa el segundo estado el llamado “remove-popup”.

El segundo estado realiza la operación inversa. Utiliza la clase “flecha” y se encarga mediante el método removeLayer() de eliminar el popup del mapa. Mediante ‘title’ podemos definir el texto que aparece al ponernos con el ratón sobre el botón.

En la última línea lo que hacemos es añadir el objeto toggle al mapa: toggle.addTo(map);

Al abrir el mapa vemos el botón con el icono de la estrella. Si hacemos clic sobre el botón se abre el popup y el botón cambia:

Al actuar de nuevo sobre el botón se ocultará el popup y se volverá a mostrar el icono de inicio.

Para aprender a crear mapas web como estos, inscríbete ya en el curso online de web mapping interactivo con Leaflet, PostGIS y React.