4E e 4I SIA: L'uso della libreria Leaflet e il plugin Leaflet Routing Machine
Il "web mapping"
In questa lezione affronteremo la differenza tra Leaflet (la libreria di base) e Leaflet Routing Machine (un plugin specializzato), seguita da un esempio pratico che le usa entrambe.
🌍 Lezione: Mappe Web con Leaflet
Pensa a Leaflet come a una scatola di LEGO. Da sola, ti fornisce tutti i mattoncini base (la mappa, i segnaposto, le forme), ma non ti dà un "castello" o una "macchina" già pronti.
1. Cos'è Leaflet (Il Motore Principale)
Leaflet è una libreria JavaScript leggera e open-source per creare mappe interattive. È il "motore" della mappa.
Come funziona? Il suo funzionamento si basa sul concetto di Layers (Livelli). Immagina di lavorare su fogli di lucido trasparenti impilati:
Il Contenitore (HTML): Per prima cosa, hai bisogno di un "telaio" nel tuo HTML in cui la mappa possa vivere. Questo è un semplice <div> con un ID, ad esempio <div id="map"></div>.
L'Oggetto Mappa (L.map): Quando inizializzi Leaflet (es. L.map('map')), stai creando la "base" su cui appoggerai i fogli lucidi. Gli dici dove centrarsi e con quale zoom iniziale.
Il Tile Layer (L.tileLayer): Questo è il primo e più importante foglio lucido. È lo sfondo della mappa (es. le strade, i palazzi, i fiumi). Leaflet non crea queste immagini; le "scarica" da un servizio esterno (come OpenStreetMap) sotto forma di tante piccole "mattonelle" (tiles) e le assembla.
I Vector Layers (I Dati): Questi sono gli altri fogli lucidi che metti sopra lo sfondo. Possono essere:
L.marker: Un segnaposto (come un pin).
L.polyline: Una linea (perfetta per un percorso!).
L.polygon: Un'area (come il confine di una città).
L.popup: Una finestrella che appare al clic.
In sintesi: Leaflet è la libreria che gestisce l'interazione (zoom, pan), organizza i livelli e disegna segnaposto e forme. Non sa come calcolare un percorso stradale.
2. Cos'è "Leaflet Machine" (Il Plugin Specializzato)
È molto probabile che tu ti riferisca a Leaflet Routing Machine. Questo non fa parte di Leaflet, ma è un plugin molto popolare.
Tornando alla nostra analogia LEGO: se Leaflet è la scatola di mattoncini, Leaflet Routing Machine è il manuale di istruzioni e i pezzi speciali per costruire una "macchina da corsa".
Cosa fa?
Si occupa di una cosa specifica: calcolare e disegnare percorsi stradali.
Come funziona?
Leaflet Routing Machine è un "intermediario". Quando gli dai un punto di partenza e uno di arrivo, fa due cose:
Chiede il percorso: Contatta un servizio di routing esterno (come OSRM, che è il predefinito e gratuito) e gli dice: "Ehi, come arrivo dal Colosseo al Duomo di Milano?".
Disegna il percorso: Il servizio gli risponde con un elenco di coordinate (la rotta) e le istruzioni di guida (es. "Svolta a destra tra 200m"). Leaflet Routing Machine prende queste coordinate e usa la funzione L.polyline di Leaflet per disegnare la linea blu sulla mappa e crea un pannello laterale con le istruzioni.
In sintesi: Leaflet Routing Machine usa Leaflet per disegnare sulla mappa, ma aggiunge la "logica" per interrogare un servizio esterno e ottenere indicazioni stradali.
🛠️ Esempio Pratico: Calcolare un Percorso
Creiamo una singola pagina HTML che carica Leaflet e Leaflet Routing Machine per mostrare il percorso stradale dal Colosseo (Roma) al Duomo di Milano.
Basta creare un file, chiamarlo mappa_percorso.html, incollare il codice qui sotto e aprirlo in un browser (devi essere connesso a Internet).
HTML
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Esempio Leaflet con Routing</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<link rel="stylesheet" href="https://unpkg.com/leaflet-routing-machine@3.2.12/dist/leaflet-routing-machine.css" />
<style>
/* Setup della pagina per occupare tutto lo spazio disponibile */
body { font-family: sans-serif; margin: 0; padding: 0; }
/* Il contenitore della mappa deve avere un'altezza definita */
#map { height: 100vh; width: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="https://unpkg.com/leaflet-routing-machine@3.2.12/dist/leaflet-routing-machine.js"></script>
<script>
// --- 1. Inizializzazione della Mappa ---
// Centriamo la visuale sull'Italia (latitudine 42.5, longitudine 12.5) con zoom 6
const map = L.map('map').setView([42.5, 12.5], 6);
// --- 2. Aggiunta dello sfondo (Tile Layer) ---
// Utilizziamo le mappe gratuite di OpenStreetMap
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
// --- 3. Configurazione del Calcolo Percorso (Routing) ---
const routingControl = L.Routing.control({
// Definiamo i punti di passaggio: Roma (Colosseo) e Milano (Duomo)
waypoints: [
L.latLng(41.8902, 12.4922),
L.latLng(45.4642, 9.1900)
],
routeWhileDragging: true, // Ricalcola il percorso se trascini i punti
show: true, // Mostra il pannello laterale con le istruzioni
language: 'it' // Imposta le istruzioni stradali in italiano
}).addTo(map);
// --- 4. Aggiunta di Marker personalizzati con Popup ---
// Marker per la partenza a Roma
L.marker([41.8902, 12.4922]).addTo(map)
.bindPopup('<b>Partenza:</b> Colosseo, Roma')
.openPopup();
// Marker per l'arrivo a Milano
L.marker([45.4642, 9.1900]).addTo(map)
.bindPopup('<b>Arrivo:</b> Duomo, Milano');
</script>
</body>
</html>
🚀 Cosa Vedrai
Aprendo questo file nel browser, vedrai:
Una mappa a schermo intero dell'Italia.
Una linea blu che mostra il percorso stradale esatto da Roma a Milano.
Due segnaposto (che abbiamo aggiunto manualmente per chiarezza).
Un pannello sulla sinistra con le istruzioni di guida dettagliate (es. "Prendi l'autostrada A1", "Esci a...").
Tutto questo è reso possibile dalla collaborazione tra Leaflet (che disegna) e Leaflet Routing Machine (che calcola).
Adesso proviamo a modificare questo esempio, magari per permettere all'utente di cliccare sulla mappa per scegliere la partenza e l'arrivo.
Invece di "imporre" il percorso (Roma -> Milano), lasceremo che sia l'utente a decidere.
Per fare questo, modificheremo la nostra logica JavaScript:
Inizializzeremo il "Routing Control" senza waypoint predefiniti.
Useremo l'evento map.on('click', ...) di Leaflet per "catturare" i clic dell'utente sulla mappa.
Gestiremo una logica semplice:
Il primo clic imposta la Partenza.
Il secondo clic imposta l'Arrivo e fa partire il calcolo del percorso.
Un terzo clic... ricomincia da capo, impostando una nuova partenza.
Useremo il metodo routingControl.setWaypoints([...]) per aggiornare dinamicamente il percorso.
🛠️ Esempio Pratico: Percorso Interattivo con Click
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Esempio Leaflet con Routing Interattivo</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<link rel="stylesheet" href="https://unpkg.com/leaflet-routing-machine@3.2.12/dist/leaflet-routing-machine.css" />
<style>
body { font-family: sans-serif; margin: 0; padding: 0; }
#map { height: 100vh; width: 100%; }
/* Stile per il pannello delle istruzioni stradali */
.leaflet-routing-container { background: white; padding: 10px; border-radius: 5px; }
/* Stile per il box di aiuto in alto al centro */
#helper {
position: absolute; top: 10px; left: 50%; transform: translateX(-50%);
z-index: 1000; background: white; padding: 10px 20px;
border-radius: 5px; font-weight: bold; box-shadow: 0 2px 5px rgba(0,0,0,0.2);
}
</style>
</head>
<body>
<div id="map"></div>
<div id="helper">Clicca sulla mappa per impostare la Partenza</div>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="https://unpkg.com/leaflet-routing-machine@3.2.12/dist/leaflet-routing-machine.js"></script>
<script>
// --- 1. Inizializzazione Mappa e Tile Layer ---
const map = L.map('map').setView([42.5, 12.5], 6); // Centrata sull'Italia
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
const helperText = document.getElementById('helper');
// --- 2. Inizializzazione Routing Machine (Senza waypoints iniziali) ---
const routingControl = L.Routing.control({
routeWhileDragging: true, // Ricalcola il percorso mentre si trascinano i punti
show: true, // Mostra il pannello con le indicazioni
language: 'it', // Lingua italiana
createMarker: function() { return null; } // Gestiamo i marker manualmente
}).addTo(map);
// --- 3. Logica dei Click e Variabili di Stato ---
let startPoint = null;
let endPoint = null;
let startMarker = null;
let endMarker = null;
map.on('click', function(e) {
const clickedLatLng = e.latlng;
if (!startPoint) {
// --- PRIMO CLICK: Imposta la Partenza ---
startPoint = clickedLatLng;
if (startMarker) map.removeLayer(startMarker);
if (endMarker) map.removeLayer(endMarker);
startMarker = L.marker(startPoint, { draggable: true })
.addTo(map)
.bindPopup('<b>Partenza</b><br>Trascina per spostare')
.openPopup();
helperText.textContent = "Ora clicca sulla mappa per impostare l'Arrivo";
routingControl.setWaypoints([]); // Pulisce eventuali percorsi precedenti
} else if (!endPoint) {
// --- SECONDO CLICK: Imposta l'Arrivo e Calcola il Percorso ---
endPoint = clickedLatLng;
endMarker = L.marker(endPoint, { draggable: true })
.addTo(map)
.bindPopup('<b>Arrivo</b><br>Trascina per spostare')
.openPopup();
helperText.textContent = "Percorso calcolato! Clicca di nuovo per ricominciare.";
// Attiva il calcolo del percorso
routingControl.setWaypoints([startPoint, endPoint]);
// Aggiorna il percorso se l'utente trascina i marker esistenti
startMarker.on('dragend', updateRoute);
endMarker.on('dragend', updateRoute);
} else {
// --- CLICK SUCCESSIVI: Reset e Nuova Partenza ---
startPoint = clickedLatLng;
endPoint = null;
if (startMarker) map.removeLayer(startMarker);
if (endMarker) map.removeLayer(endMarker);
startMarker = L.marker(startPoint, { draggable: true })
.addTo(map)
.bindPopup('<b>Partenza</b><br>Trascina per spostare')
.openPopup();
helperText.textContent = "Ora clicca sulla mappa per impostare l'Arrivo";
routingControl.setWaypoints([]);
}
});
// Funzione per aggiornare il percorso dopo il trascinamento (drag)
function updateRoute() {
startPoint = startMarker.getLatLng();
endPoint = endMarker.getLatLng();
routingControl.setWaypoints([startPoint, endPoint]);
}
</script>
</body>
</html>
💡 Come Usarlo
Apri il file mappa_interattiva.html nel tuo browser.
Primo click: Fai clic in un punto qualsiasi dell'Italia (es. Napoli). Apparirà un marker di "Partenza".
Secondo click: Fai clic su un altro punto (es. Venezia). Apparirà un marker di "Arrivo", e vedrai il pannello delle istruzioni e la linea blu del percorso che vengono calcolati automaticamente.
Trascina: Prova a trascinare uno dei due marker. Il percorso si aggiornerà in tempo reale.
Terzo click: Fai clic in un altro punto (es. Bari). La mappa si resetterà, i vecchi marker spariranno e Bari diventerà la tua nuova partenza. Il ciclo ricomincia.

Commenti
Posta un commento