Creare mappe interattive usando la libreria Leaflet

leaflet-logo

Leaflet è una nuova libreria JavaScript open-source specializzata per la creazione di mappe interattive. E’ stata sviluppata da Vladimir Agafonkin e sta guadagnando popolarità molto velocemente.

Includere la libreria Leaflet nella pagina web

Prima di cominciare a scrivere il codice specifico per generare la mappa, abbiamo bisogno di fare alcune operazioni direttamente sulla pagina web su cui vogliamo rappresentare la mappa. Per prima cosa includiamo la libreria Leaflet.js insiema al file CSS corrispondente nella sezionedella pagina HTML.

Se vuoi usare un servizio CDN (la pagina web caricherà direttamente la libreria da un servizio remoto senza la necessità di scaricarla sul proprio computer), alla aggiungi le seguenti righe:

<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
<script type="text/javascript" src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js">
</script>

invece se hai già la libreria sul tuo computer o web server allora puoi includerla direttamente nel file HTML scrivendo il loro path relativo (relativo al file .html). Per esempio, se la libreria è contenuta all’interno della directory plugins, dovremo scrivere:

<link rel="stylesheet" href="plugins/leaflet.css" />
<script type="text/javascript" src="plugins/leaflet.js"></script>

Il passo successivo è quello di annidare la mappa che vogliamo generare all’interno di un contenitore
<div>. Questo contenitore andrà posizionato nel punto preciso all’interno del contenuto già presente nella pagina web, in cui desideriamo appaia la mappa.  Quindi, nella sezionedella pagina HTML aggiungeremo le righe seguenti.

<div class="map-wrap">
  <div id="map"></div>
</div>

Dato che abbiamo appena definito la mappa e il suo contenitore, adesso sarà necessario impostare alcuni attributi come per esempio la loro dimensione. Questo viene normalmente fatto impostando i diversi attributi (altezza, lunghezza, colore, spessore dei bordi, ecc.) come stili CSS. Aggiungiamo questi stili all’interno della sezionedella pagina HTIML.

<style>
.map-wrap {         
   border: 3px solid #000;         
   width: 400px;         
   height: 400px;   
}   
#map {         
   width: 400px;         
   height: 400px;   
}
</style>

I tileset

In internet sono disponibili diversi formati di tile. In questo articolo tratteremo quelli che ritengo i più comuni tra di loro.

  • openStreetMap (OSM)
  • MapQuest-OSM tiles
  • MapQuest Open Aerial tiles
  • Google Map

Utilizzando le tile di OpenStreetmap (OSM)

Ora finalmente è giunto il momento di cominciare a scrivere del codice in JavaScript. Come esempio geografico ho scelto di utilizzare le tile del centro di Roma, ma puoi benissimo utilizzare qualsiasi altra porzione del mondo. Le regole che applicheremo qui possono essere usate indipendentemente per qualsiasi tipo di mappa e di luogo geografico.

Cominciamo definendo l’oggetto map.

var map = new L.Map('map');

Per questo primo esempi, partiremo utilizzando le tile di OpenStreetMap (OSM). Infatti, al momento attuale sono le più comunemente utilizzate, dato che sono anche gratuite e appartengono ad un progetto Open. Per utilizzarle, è necessario solo aggiungere il loro URL:

var url = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';

Adesso aggiungiamo anche i termini di uso. Generalmente quando utilizziamo le mappe è buona norma rappresentare in un bordo un piccolo testo che ne descriva le credenzialità. Nel caso delle OpenStreetMap possiamo aggiunge la seguente variabile:

var attrib = 'Map data (c)OpenStreetMap contributors';

ed infine è necessario definire il Tile layer, cioè lo strato base su cui verrà rappresentata la mappa utilizzando proprio le tile.

var osm = new L.TileLayer(url, {minZoom: 8, maxZoom: 16, attribution: attrib});

All’interno degli argomenti passati, possiamo vedere che abbiamo specificato i valori di massimo e minimo zoom che vogliamo applicare alla mappa. Infatti, la rappresentazione dei dati o dei marker sulla nostra mappa ha generalmente significato solo per un certo livello di ingrandimento. Dando all’utente la possibilità di allargare o di restringere eccessivamente la mappa, la nostra rappresentazione fatta di simboli su specifiche aree geografiche potrebbe perder di significato e diventare illeggibile.

Una volta definito il tile layer è il momento di disegnarlo sulla mappa. A questo livello aggiungiamo sia la latitudine che la longitudine del posto che vogliamo rappresentare (Roma) e come secondo argomento il livello di zoom con cui vogliamo vedere la mappa rappresentata inizialmente (16).

map.setView(new L.LatLng(41.88,12.47),16);
map.addLayer(osm);

Adesso che abbiamo finito di definire la mappa sottostante, possiamo cominciare a definire il punto su di essa che vogliamo evidenziare. Questo lo possiamo fare posizionando un marker in un punto specifico della mappa (anche il marker viene definito con un valore di latitudine e uno di longitudine). Inoltre spesso è necessario a questo marker un testo identificativo, perciò aggiungeremo un popup al marker..

L.marker([41.88,12.47]).addTo(map).bindPopup("I’m here!").openPopup();

Ok. Dopo tutto questo lavoro è il momento di caricare la pagina sul browser e vedere quello che abbiamo combinato!!!

leaflet-map01

Nell’angolo in alto a sinistra c’è un controllo con i simboli +/- con cui l’utente è in grado di regolare il livello di zoom della mappa. La stessa cosa la può ottenere ruotando la rotella del mouse. Invece tenendo premuto il mouse e contemporaneamente muovendo il mouse è possibile spostare la mappa.

leaflet-map03
leaflet-map02
writeanarticle01_it

Utilizzare le tile di MapQuest-OSM

Se invece sono le tile fornite da MapQuest-OSM quelle che vogliamo utilizzare, è sufficiente solo modificare l’url precedente con questo nuovo:

var url = 'http://otile4.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png';
leaflet-map06

Utilizzare le tile satellitari di MapQuest (Open Aerial)

MapQuest fornisce oltre alla mappe che abbiamo appena visto anche le tile fotografiche prese dal satellite. Sfortunatamente solo alcuni livelli di zoo sono disponibili per l’Italia. Mentre per gli USA sono presenti le tile a tutti i livelli di zoom. Quindi a titolo dimostrativo, solo per questo specifico caso, ho deciso di utilizzare New York city come esempio geografico.

map.setView(new L.LatLng(40.72,-74.00),12);

e nell’url precedente sostituiamo osm con sat:

var url = 'http://otile4.mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.png';
leaflet-sat

Utilizzare le tile di Google Map

Se invece sono le tile di Google Map quelle a cui sei più interessato, dovrai sostituire il codice JavaScript usato in precedenza con quello che segue:

var map = new L.Map('map');
var googleLayer = new L.Google('ROADMAP');
map.setView(new L.LatLng(41.88, 12.47),16);
map.addLayer(googleLayer);
L.marker([41.88,12.47]).addTo(map).bindPopup("I’m here!").openPopup();

Non dimenticarti di aggiungere le seguenti impostazioni CSS alla pagina web, altrimenti non vedrai alcun marker nè alcun popup rappresentati nella mappa.

.leaflet-map-pane {
   z-index: 2 !important;
}
.leaflet-google-layer{
   z-index: 1 !important;
}
leaflet-google-map

Markers, cerchi e poligoni

Oltre ai marker e ai popup, puoi benissimo aggiungere altre tipologie di oggetti come per esempio linee, poligoni o cerchi. Per esempio, potresti considerare il caso di aggiungere un cerchio alla mappa in modo da evidenziare un’area circostante un marker. Per esempio questo può essere utile per visualizzare dati statistici, come per esempio le zone di influenza di un determinato marker.

L.circle([41.88,12.47],100, {
   color : 'darkgreen',
   fillColor: 'green',
   fillOpacity: 0.3
}).addTo(map);
leaflet-map04

Un altro caso, invece, potrebbe essere quello di evidenziare specifiche aree geografiche (che spesso non sono circolari) e quindi sarà necessario utilizzare un poligono per delimitarle. Quello che dovremo fare sarà definire un array con i vertici del poligono, definirne il colore con cui vogliamo rappresentarlo e il livello di trasparenza.

L.polygon([[41.89,12.46],[41.86,12.46],[41.86,12.48],[41.87,12.47]],
{ 
  color : 'darkgreen',
  fillColor: 'green',
  fillOpacity: 0.3
}).addTo(map);
leaflet-map05

Lavoriamo ulteriormente con i popups

Abbiamo già visto come assegnare un popup ad un marker, ma certamente, non avrai percepito quante siano le possibilità che questi popup ci offrono. Infatti, il testo che passiamo come argomento della funzione bindPopup() non è una semplice stringa di testo, bensì codice HTML. Realizzato ciò, introducendo dei tag HTML è possibile migliorare notevolmente l’aspetto dei popup e soprattutto tutto questo ci permette di personalizzarli come più ci aggrada.

Per esempio, è possibile aggiungere un’immagine insieme al testo (qui puoi scaricare l’iconda dalla galleria OpenIcon e rinominarla icon.png). Sostituisci il codice che riguardava il marker con queste nuove righe.

L.marker([41.88,12.47]).addTo(map).bindPopup("<img alt="" src="icon.png" /><b>HI!!</b>
This is me!");
L.marker([41.882,12.47]).addTo(map).bindPopup("<i>Someone else</i>");
L.marker([41.881,12.471]).addTo(map).bindPopup("<i>Someone else</i>");
L.marker([41.879,12.469]).addTo(map).bindPopup("<i>Someone else</i>");

Caricando nuovamente la pagina, vedremo che la mappa presenta ora 4 diversi marker. Solamente cliccando su quello corretto, apparirà il popup con l’immagine all’interno. Ricordati che la mappa è in grado di visualizzare un popup alla volta!

leaflet-osm-01

Ma questo non è tutto! E’ possibile modificare ulteriormente l’aspetto dei popup agendo questa volta a livello degli stili CSS. Per esempio, aggiungiamo alla nostra pagina web le seguenti impostazioni CSS.

.leaflet-popup-content-wrapper {
   background: #000;
   border: solid 3px orange;
   color: orange;
   font-size: 14;
}

Otterrai un popup abbastanza diverso da quello consueto.

leaflet-osm-02

Utilizzare marker personalizzati

Purtroppo, la libreria Leaflet fornisce al suo interno un solo tipo di marker (quello blu). Se desideri o hai bisogno di utilizzare altre tipologie di marker o lo stesso ma con colori diversi, dovrai necessariamente crearteli da solo. Per realizzare un’icona personalizzata è necessario generare due diverse immagini, una per il marker e una per l’ombra che questo proietta sulla mappa.

Per questo esempio ho utilizzato l’icona (con le foglie verdi) presente sul tutorial del sito ufficiale. (Ecco i link per scaricare l’icon con le foglie verdi, rosse, gialle e l’ombra).

var greenIcon = L.icon({
   iconUrl: 'leaf-green.png',
   shadowUrl: 'leaf-shadow.png',
   iconSize:     [38, 95], //size of the icon
   shadowSize:   [50, 64], //size of the shadow
   iconAnchor:   [22, 94], //point of the icon which will correspond to marker's location
   shadowAnchor: [4, 62],  //the same for the shadow
   popupAnchor:  [-3, -76] //point from which the popup should open relative to the iconAnchor
});

Una volta definito un nuovo insieme di marker, sarà possibile scegliere tra le diverse icone e assegnarle individualmente a ciascun marker in modo da contraddistinguerli tra di loro all’interno della mappa. In questo semplice caso, ho utilizzato un solo marker, quello verde.

L.marker([41.88,12.47],{icon:greenIcon}).addTo(map);
leaflet-osm-03

Con questo ultimo esempio, abbiamo terminato la lettura dell’articolo introduttivo sulle mappe interattive. Ci vediamo al prossimo articolo. Ciao![:en]

4 commenti su “Creare mappe interattive usando la libreria Leaflet

  1. derrico

    Ciao,

    sto seguendo un progetto che prevede l’utilizzo di OSM e leaflet per creare delle mappe interattive per gli utenti da usare sia su mobile che su desktop.
    Ora il mio problema è che sto provando ad usare anche alcune mappe in modalità offline; mi spiego meglio:

    tramite Maperative ho scaricato delle tiles a diversi livelli di zoom per alcune località, in modo da poter dare all’utente tramite un layer control di poter scegliere se vedere la mappa online o quelle proposte in modalità offline (che comunque riguardano sempre delle città e quindi piccole porzioni di mappa). Bene, ora dopo aver preso la cartella tiles di Maperative ed averla copiata nella directory dove risiede la mia index.html, ho scritto il seguente codice:

    var newLayer = L.tileLayer(‘file:///C:/Users/derrico/Desktop/offline/tiles/{z}/{x}/{y}.png’, {
    attribution: ‘prova di tiles locali’,
    maxzoom: 11,
    minzoom: 10,
    tms: false
    }).addTo(map);

    Adesso quello che mi sarei aspettato è poter vedere la mappa creata con i tiles presenti nella cartella specificata, invece, quello che ottengo è solamente il div grigio vuoto con i soli comandi di zoom e di layer control ai lati.
    Il codice mi sembra giusto (anche dopo averlo confrontato con tanti esempi online) quindi non riesco a capire il problema.

    Quale potrebbe essere!!!?

    Grazie.

  2. Pingback: L.map In Leaflet – everockitworld

Lascia un commento