¿Dónde se encuentran las imágenes de Leaflet?

Leaflet: Desvelando los Secretos de un Visor de Mapas 2D

05/11/2022

Valoración: 4.73 (2448 votos)

En el vasto universo de la visualización cartográfica, donde la interactividad y la eficiencia son claves, las librerías OpenSource han emergido como herramientas indispensables para desarrolladores y entusiastas. Tras explorar las capacidades tridimensionales de CesiumJS y la versatilidad de OpenLayers, es hora de adentrarnos en Leaflet, una joya de la programación de mapas 2D que destaca por su ligereza, facilidad de uso y una sorprendente calidad visual.

¿Dónde se encuentran las imágenes de Leaflet?
images: la carpeta con las imágenes por defecto que utiliza Leaflet. Se debe localizar al mismo nivel que el archivo CSS. Nota: aunque lo comentaremos otra vez más adelante, es muy importante incluir las hojas de estilo antes que la librería de JavaScript. La otra posibilidad es la tirar de NPM, instalando las dependencias usando:

Leaflet se presenta como una alternativa robusta y eficiente para aquellos que buscan representar información geográfica en dos dimensiones. Su diseño minimalista y su enfoque en el rendimiento lo convierten en una opción predilecta para proyectos web que requieren visores de mapas rápidos y fluidos. Pero, ¿qué hace a Leaflet tan especial y cómo podemos sacarle el máximo partido? Una de las preguntas más comunes al empezar es sobre la gestión de sus recursos visuales, especialmente sus imágenes por defecto. Abordemos esto de inmediato.

Índice de Contenido

¿Dónde se encuentran las imágenes de Leaflet?

Una de las peculiaridades y a la vez una de las facilidades de Leaflet, especialmente cuando se trabaja con la descarga local de la librería, es la ubicación de sus recursos visuales. Las imágenes por defecto que utiliza Leaflet (como los iconos de los marcadores, los controles de zoom, etc.) se encuentran en una carpeta específica denominada images. Es crucial que esta carpeta esté localizada al mismo nivel que el archivo CSS principal de Leaflet, leaflet.css.

Cuando descargas la librería Leaflet (a fecha de este artículo, la versión 1.7.1), encontrarás una estructura de archivos que típicamente incluye:

  • leaflet.js: El código JavaScript minificado de la librería.
  • leaflet-src.js: El código JavaScript sin minificar, útil para depuración.
  • leaflet.css: La hoja de estilos que define la apariencia del mapa y sus elementos.
  • images/: La carpeta que contiene todos los iconos e imágenes por defecto.

La importancia de esta ubicación radica en cómo el archivo CSS referencia estas imágenes. Si la carpeta images no está en la ruta esperada por el CSS, los iconos y otros elementos visuales no se cargarán correctamente, resultando en un mapa con marcadores ausentes o controles de zoom desalineados. Esta es una de las primeras consideraciones a tener en cuenta al desplegar un visor Leaflet de forma local, asegurando una experiencia visual impecable desde el principio.

Leaflet en el Ecosistema de Visores OpenSource: Una Comparativa

Para entender mejor el lugar de Leaflet, es útil compararlo con otras librerías populares como CesiumJS y OpenLayers, que también hemos explorado en esta serie:

CaracterísticaLeafletOpenLayersCesiumJS
Tipo de Visualización2D (con extensiones 3D isométricas)2D (con extensiones 3D isométricas)3D Nativo
LicenciaBSD-2BSD-2Apache 2.0
Ligereza/RendimientoMuy ligero y rápidoRobusto, buenas prestacionesPotente, pero más exigente
Facilidad de UsoMuy fácil y accesibleModerada, curva de aprendizajeMás compleja, curva pronunciada
Calidad SimbologíaExcelente por defectoBuena, requiere personalizaciónDepende de los modelos 3D
Entorno de Desarrollo OficialNo oficial (se usan externos como CodeSandbox)CodeSandbox (recomendado)Sandcastle (propio)
Extensiones 3DWRLD3D (no OpenSource, freemium), OSMBuildingsVarias, para 3D isométricoNativa, para modelos 3D y terrenos

Leaflet brilla por su sencillez y su capacidad para generar mapas 2D de alta calidad visual con un mínimo esfuerzo. Aunque su naturaleza principal es 2D, la comunidad ha desarrollado extensiones como WRLD3D (anteriormente eegeo) y OSMBuildings, que permiten añadir una percepción de profundidad o incluso visualizaciones isométricas, acercándose a experiencias más inmersivas sin la complejidad de un motor 3D completo.

Utilizando la Librería Leaflet: Opciones de Implementación

Al igual que con otras librerías JavaScript, existen varias formas de integrar Leaflet en tus proyectos. Cada una ofrece ventajas dependiendo de tus necesidades:

1. Descargarla y/o Instalarla Localmente

La opción más directa es descargar la versión estable de Leaflet desde su sitio web oficial. Como mencionamos, la versión 1.7.1 es la que hemos estado utilizando. Una vez descargada, simplemente debes enlazar los archivos leaflet.js y leaflet.css en tu documento HTML. Es fundamental recordar que la hoja de estilos leaflet.css debe ser incluida antes que el script leaflet.js para evitar problemas de renderizado.

<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Mi Primer Mapa Leaflet</title> <link rel="stylesheet" href="path/to/leaflet.css"/> <script src="path/to/leaflet.js"></script> </head> <body> <div id="map" style="height: 100vh; width: 100%;"></div> <script> // Tu código Leaflet aquí </script> </body> </html>

Para aquellos que prefieren el ecosistema de Node.js, Leaflet también puede ser instalado vía NPM con un simple comando:

npm i leaflet

2. Entornos Externos de Programación en Vivo

A diferencia de Cesium (con su Sandcastle) u OpenLayers (que se integra con CodeSandbox), Leaflet no cuenta con un entorno de desarrollo en vivo oficial o fuertemente recomendado. Sin embargo, esto no es un impedimento. Puedes utilizar plataformas como CodeSandbox, JSFiddle, o cualquier otro IDE en línea de tu preferencia para experimentar y desarrollar con Leaflet. Simplemente, tendrás que importar los archivos de la librería manualmente a través de CDN o subiendo los archivos locales si la plataforma lo permite.

3. Consumir la Librería vía URL (CDN)

Para una integración rápida y sin complicaciones, la opción más popular es utilizar una Red de Entrega de Contenidos (CDN). Esto te permite cargar Leaflet directamente desde un servidor externo, sin necesidad de descargas o instalaciones locales. CDN como unpkg, cdnjs o jsDelivr son excelentes opciones. Para este tipo de tutoriales, cdnjs es particularmente conveniente por la facilidad de sus URLs:

  • https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.js
  • https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css

Esta es la vía que recomendamos para la mayoría de los casos de prueba y desarrollo rápido, ya que simplifica enormemente el proceso de configuración inicial.

Construyendo tu Primer Visor de Mapas con Leaflet

Ahora que conocemos las bases, es momento de poner manos a la obra y crear un visor de mapas funcional con Leaflet. Vamos a simular un entorno de desarrollo donde puedas copiar y pegar el código directamente.

1. Estructura HTML y Estilos CSS

Necesitamos un contenedor en nuestro HTML donde Leaflet pueda renderizar el mapa. Le daremos un ID para referenciarlo desde JavaScript y algunos estilos básicos para que ocupe el espacio deseado.

<style> .leafletContainer { height: 100%; width: 100%; } </style> <div id="leafletContainer" class="leafletContainer"></div>

2. Inicialización del Mapa en JavaScript

El corazón de nuestro visor reside en el código JavaScript. Aquí, crearemos una instancia del mapa de Leaflet y le añadiremos un mapa base para que sea visible. Es importante recordar que Leaflet, al igual que OpenLayers, requiere una capa base (como OpenStreetMap) y una vista inicial (coordenadas y zoom) para mostrar algo más que un lienzo gris.

// Esta función se llamará una vez para inicializar los componentes vm.initLiveComponent = function () { let viewer = L.map('leafletContainer'); // Añadir una capa base de OpenStreetMap L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: false, // Opcional: para quitar la atribución por defecto }).addTo(viewer); // Definir la vista inicial (coordenadas y nivel de zoom) // ¡Atención! Leaflet usa Latitud, Longitud. viewer.setView([-3, 40], 5); // Esto apunta a Kenia si no se corrige el orden };

Si ejecutas este código, notarás que el mapa se enfoca en una zona cercana a Mombasa, en Kenia, a pesar de que nuestras coordenadas [-3, 40] podrían sugerir España si estuviéramos acostumbrados al orden Longitud, Latitud. Esta es una diferencia crucial en Leaflet: las coordenadas se introducen como latitud y longitud, al revés que en Cesium u OpenLayers.

3. Corrigiendo el Orden de las Coordenadas

Para solucionar el problema del orden de las coordenadas, Leaflet ofrece un método muy útil: L.GeoJSON.coordsToLatLng(). Este método está diseñado para trabajar con objetos GeoJSON y parsea inteligentemente las coordenadas, invirtiendo el orden si es necesario para que Leaflet las interprete correctamente.

// Esta función se llamará una vez para inicializar los componentes vm.initLiveComponent = function () { let viewer = L.map('leafletContainer'); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: false, }).addTo(viewer); // Usamos GeoJSON.coordsToLatLng para manejar el orden correcto viewer.setView(L.GeoJSON.coordsToLatLng([-3, 40]), 5); // Ahora sí apunta a España // Importante para mapas dentro de contenedores dinámicos setTimeout(() => { viewer.invalidateSize(); }, 100); };

Además, hemos incluido un setTimeout con la función viewer.invalidateSize(). Esto es una buena práctica, especialmente cuando el mapa se renderiza dentro de un contenedor cuyo tamaño puede cambiar (como en los gadgets de un dashboard). Asegura que el mapa se ajuste correctamente al tamaño de su contenedor, evitando problemas de visualización o áreas grises.

Posibles Configuraciones del Visor del Mapa

Leaflet es altamente configurable. El objeto mapa ofrece una gran cantidad de opciones para personalizar su comportamiento, desde el sistema de coordenadas hasta las interacciones del usuario. Podemos categorizar estas opciones en propiedades generales, controles e interacciones.

Propiedades Generales Comunes:

  • crs: El sistema de coordenadas de referencia. Leaflet soporta los más comunes: EPSG:4326 (el estándar para GPS, cubre todo el planeta), EPSG:3857 (Pseudo-Mercator, popular en mapas web, polos recortados), y EPSG:3395 (usado por algunos proveedores de mapas base).
  • center: Las coordenadas iniciales (latitud, longitud) del centro del mapa. Una alternativa a setView().
  • zoom: El nivel de zoom inicial. Complementa a center.
  • minZoom: Limita el nivel mínimo de zoom que el usuario puede alcanzar.
  • maxZoom: Limita el nivel máximo de zoom.
  • layers: Un array que permite precargar capas al inicializar el mapa.
  • maxBounds: Limita el área visible del mapa a unas coordenadas específicas, ideal para enfocar la vista en un país o región.
  • renderer: El método de renderizado, pudiendo elegir entre Canvas o SVG, lo que puede influir en el rendimiento y la compatibilidad.

Controles del Mapa:

Leaflet incluye controles básicos que se pueden activar o desactivar:

  • attributionControl: Para mostrar u ocultar la información de atribución de los datos del mapa (ej. OpenStreetMap). Es una buena práctica mantenerlo visible.
  • zoomControl: Permite mostrar u ocultar los botones de control de zoom (+/-).

Interacciones del Usuario:

Estas opciones controlan cómo el usuario interactúa con el mapa:

  • closePopupOnClick: Define si los popups se cierran automáticamente al hacer clic en cualquier parte del mapa.
  • doubleClickZoom: Habilita o deshabilita la función de hacer zoom con doble clic.
  • dragging: Controla si el mapa se puede desplazar arrastrándolo con el ratón o el dedo.

Aunque Leaflet no incluye herramientas de dibujado por defecto en su núcleo, existe una API de dibujado bien documentada en GitHub que se puede integrar para añadir funcionalidades como dibujar polígonos, líneas o puntos directamente en el mapa.

Cargar una Capa Vectorial en Leaflet

Un visor de mapas cobra vida cuando se le añaden datos. Vamos a cargar una capa vectorial en formato GeoJSON, siguiendo el ejemplo de puntos de interés que hemos utilizado en entradas anteriores.

const myJSON = { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "id": "Work" }, "geometry": { "type": "Point", "coordinates": [ -3.641436696052551, 40.529066557739924 ] } }, { "type": "Feature", "properties": { "id": "Lunch" }, "geometry": { "type": "Point", "coordinates": [ -3.6394304037094116, 40.53058739857294 ] } }, { "type": "Feature", "properties": { "id": "Beer" }, "geometry": { "type": "Point", "coordinates": [ -3.639392852783203, 40.530179669832364 ] } } ] };

Añadir esta capa a nuestro mapa Leaflet es sorprendentemente sencillo gracias al método L.geoJson(). Este método no solo interpreta el GeoJSON, sino que también maneja automáticamente el orden de las coordenadas, lo que lo hace muy conveniente.

// Dentro de vm.initLiveComponent = function () { ... // ... (código de inicialización del mapa y capa base) ... const myJSON = { /* ... GeoJSON de puntos ... */ }; let layer = L.geoJson(myJSON).addTo(viewer); setTimeout(() => { viewer.invalidateSize(); viewer.fitBounds(layer.getBounds()); // Zoom a la extensión de la capa }, 100); // };

Hemos añadido la línea viewer.fitBounds(layer.getBounds()) dentro del setTimeout. Esto hace que el mapa se ajuste automáticamente para mostrar toda la extensión de nuestra capa de puntos. Es una excelente forma de asegurar que los datos sean visibles para el usuario desde el primer momento. La inclusión en un setTimeout se debe a que Leaflet no trabaja con promesas de forma nativa para la carga de capas, por lo que un pequeño retardo asegura que la capa se haya renderizado antes de intentar calcular sus límites.

Efecto de Parpadeo en Capas

A diferencia de otras librerías donde podríamos simplemente ocultar y mostrar una capa, en Leaflet el concepto es ligeramente distinto. Para lograr un efecto de "parpadeo" (aparición y desaparición), la práctica común es eliminar la capa existente y volver a añadirla. Esto se debe a que Leaflet gestiona las capas de una forma que hace más eficiente su eliminación y recreación que un simple cambio de visibilidad.

// Dentro de vm.initLiveComponent = function () { ... // ... (código anterior de inicialización y carga de capa) ... setTimeout(() => { setInterval(() => { if (layer) { viewer.removeLayer(layer); // Eliminar la capa layer = null; // Establecer a null para indicar que no está presente } else { layer = L.geoJson(myJSON).addTo(viewer); // Volver a añadir la capa } }, 1000); // Repetir cada 1 segundo }, 100); // };

Este fragmento de código crea un intervalo que cada segundo verifica si la capa existe. Si existe, la elimina; si no, la vuelve a crear y añadir al visor. Es una demostración de cómo, aunque el enfoque sea diferente, se pueden lograr efectos visuales similares en Leaflet.

Código Completo para Probar

Para facilitar tu experimentación, aquí tienes el código completo que puedes copiar y pegar en tu entorno de desarrollo, asegurándote de que las URLs de Leaflet CSS y JS estén correctas o que los archivos locales estén en su lugar.

HTML/CSS

<!-- Write your HTML <div></div> and CSS <style></style> here --> <!--Focus here and F11 to full screen editor--> <style> .leafletContainer { height: 100%; width: 100%; } </style> <div id="leafletContainer" class="leafletContainer"></div>

JavaScript

//Write your controller (JS code) code here //Focus here and F11 to full screen editor //This function will be call once to init components vm.initLiveComponent = function () { window.viewer = L.map('leafletContainer'); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: false, }).addTo(viewer); viewer.setView(L.GeoJSON.coordsToLatLng([-3, 40]), 5); const myJSON = { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "id": "Work" }, "geometry": { "type": "Point", "coordinates": [ -3.641436696052551, 40.529066557739924 ] } }, { "type": "Feature", "properties": { "id": "Lunch" }, "geometry": { "type": "Point", "coordinates": [ -3.6394304037094116, 40.53058739857294 ] } }, { "type": "Feature", "properties": { "id": "Beer" }, "geometry": { "type": "Point", "coordinates": [ -3.639392852783203, 40.530179669832364 ] } } ] }; let layer = L.geoJson(myJSON).addTo(viewer); setTimeout(() => { viewer.invalidateSize(); viewer.fitBounds(layer.getBounds()); }, 100); setTimeout(() => { setInterval(() => { if (layer) { viewer.removeLayer(layer); layer = null; } else { layer = L.geoJson(myJSON).addTo(viewer); } }, 1000); }, 100); }; //This function will be call when data change. On first execution oldData will be null vm.drawLiveComponent = function (newData, oldData) { }; //This function will be call on element resize vm.resizeEvent = function () { } //This function will be call when element is destroyed vm.destroyLiveComponent = function () { }; //This function will be call when receiving a value from vm.sendValue(idGadgetTarget,data) vm.receiveValue = function (data) { };

Preguntas Frecuentes sobre Leaflet (FAQ)

¿Por qué mis iconos de marcadores no aparecen en mi mapa Leaflet?

Esto suele ocurrir si estás utilizando una descarga local de Leaflet y la carpeta images, que contiene los iconos por defecto, no se encuentra al mismo nivel que el archivo leaflet.css. Asegúrate de que la estructura de directorios sea correcta o, si usas CDN, verifica que la hoja de estilos se haya cargado correctamente.

¿Cuál es la diferencia en el orden de las coordenadas en Leaflet en comparación con otras librerías?

Leaflet utiliza el formato (latitud, longitud) para sus coordenadas, mientras que otras librerías como CesiumJS o OpenLayers a menudo emplean (longitud, latitud). Para evitar confusiones y errores de ubicación, puedes utilizar el método L.GeoJSON.coordsToLatLng() de Leaflet, que se encarga de parsear las coordenadas correctamente.

¿Cómo puedo asegurar que mi mapa Leaflet se ajuste al tamaño de su contenedor, especialmente si este cambia?

Utiliza la función viewer.invalidateSize(). Es ideal llamarla después de que el contenedor del mapa haya cambiado de tamaño (por ejemplo, al redimensionar una ventana o un gadget), o con un pequeño retraso (setTimeout) si el mapa se carga en un contenedor que puede tardar un momento en establecer su tamaño definitivo.

¿Es Leaflet adecuado para visualizar mapas en 3D?

Leaflet está diseñado principalmente para mapas 2D. Sin embargo, existen extensiones y plugins de terceros, como WRLD3D o OSMBuildings, que pueden añadir una capa de visualización isométrica o modelado 3D básico sobre tu mapa 2D, proporcionando una sensación de profundidad sin la complejidad de un motor 3D completo.

¿Cómo puedo limitar el área visible de mi mapa Leaflet a una región específica?

Puedes usar la opción maxBounds al inicializar el mapa. Esta propiedad te permite definir un recuadro de coordenadas geográficas (latitud y longitud) dentro del cual el mapa podrá desplazarse. Cualquier intento de mover el mapa fuera de estos límites será restringido.

¿Por qué mi mapa Leaflet se ve completamente gris al iniciar?

Si tu mapa Leaflet se muestra gris, lo más probable es que falte una capa base o que no hayas definido una vista inicial. Asegúrate de añadir un L.tileLayer() (como OpenStreetMap) y de establecer una vista inicial con viewer.setView(latitud, longitud, zoom).

Conclusión

Leaflet se consolida como una opción formidable para cualquier desarrollador que busque una solución eficaz y estéticamente agradable para la visualización de mapas 2D en la web. Su simplicidad, combinada con su robustez y la activa comunidad que lo respalda, lo hacen accesible tanto para principiantes como para desarrolladores experimentados. Desde la correcta ubicación de sus imágenes por defecto hasta la carga de datos vectoriales y la gestión de sus múltiples configuraciones, Leaflet demuestra que la potencia no siempre reside en la complejidad, sino en la elegancia de su diseño y su capacidad para ofrecer resultados visuales impactantes con un esfuerzo mínimo. Esperamos que esta guía te haya proporcionado las herramientas y el conocimiento necesarios para comenzar a construir tus propios visores de mapas interactivos con Leaflet y explorar un mundo de posibilidades geográficas.

Si quieres conocer otros artículos parecidos a Leaflet: Desvelando los Secretos de un Visor de Mapas 2D puedes visitar la categoría Librerías.

Subir