Perchè una mappa cluster?
Le mappe ricche di informazioni sono uno strumento prezioso per mostrare relazioni importanti, identificare tendenze del business o illustrare opportunità. Tuttavia, il posizionamento di migliaia o milioni di marker su una mappa può portare rapidamente a un sovraccarico visivo o impedirne l’analisi.
Quando una mappa ha troppi punti per esprimere un significato chiaro, le informazioni devono essere necessariamente semplificate. La riduzione della quantità di punti sulla mappa può essere ottenuta raggruppando i punti in base a determinati criteri e visualizzando diversi colori e dimensioni, icone, regole di posizionamento e altro.
Le mappe cluster aiutano quindi, a rappresentare densi pacchetti di dati puntuali usando un singolo punto. Ogni cluster è etichettato con il numero di punti con cui sono stati raggruppati.
Le visualizzazioni cluster sono ideali per mappe interattive dove l’utente può scendere nel dettaglio fino a vedere i singoli punti contenuti nel cluster, indagando e zoomando sulla porzione di territorio di quel cluster.
Facendo così, questo tipo di mappe aiutano a ridurre la confusione dovuta alla presenza di un alto numero di punti che sembrerebbero, altrimenti, sovrapposti in questa piccola porzione geografica d’interesse.
Plugin Leaflet.markerCluster
LeafletJS è la potente libreria javascript di cui ci siamo già interessati sia per darne brevi cenni di introduzione sia per anche per studiare una maniera alternativa per visualizzare una grossa mole di dati attraverso l’utilizzo delle heatmaps.
Attraverso l’utilizzo dei plugin creati dalla community Leaflet permette di risolvere i più svariati problemi per una visualizzazione interattiva sempre ottimale e impeccabile. Chiaramente, anche per questo tipo mappe la community ha dato il suo contributo, rilasciando Leaflet.markerCluster.
Analizzando il codice le parti essenziali sono quelle riguardano l’importazione della libreria riguardante il plugin e quella inerente alla sezione <script> dove viene sviluppata la liga javascript per la mappa. Importiamo quindi il plugin con il suo file js e i suoi fogli di stile css.
<link rel="stylesheet" href="https://leaflet.github.io/Leaflet.markercluster/dist/MarkerCluster.css" />
<link rel="stylesheet" href="https://leaflet.github.io/Leaflet.markercluster/dist/MarkerCluster.Default.css" />
<script src="https://leaflet.github.io/Leaflet.markercluster/dist/leaflet.markercluster-src.js"></script>
Nella sezione <script> invece avremo:
<script>
var map = L.map('map').setView([40.837881, 14.2473229], 10);
var OpenStreetMap_BlackAndWhite = L.tileLayer('http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);
var markers = L.markerClusterGroup();
$.getJSON('./luoghi_cultura_napoli.geojson',function (data) {
L.geoJson(data, {
pointToLayer: function (feature,latlng) {
if (feature.properties.imageUrl){
fotografia='<img style="width: 100%; height: 100%;" src="'+feature.properties.imageUrl+'"/>';
} else fotografia='';
html="<h2 style='text-align: center;'>"+feature.properties.nome+"</h2><p style='text-align: center;'><em>"+feature.properties.indirizzo+" "+feature.properties.quartiere+" "+feature.properties.comune+" "+feature.properties.provincia+" <br /></em></p><p style='text-align: center;'><em>"+fotografia+"</em></p><h4 style='text-align: justify;'><em>"+feature.properties.tipologia+"<em></h4><p style='text-align: justify;'><em>"+feature.properties.storia+"</em></p><h4 style='text-align: justify;'><em><a target='_blank' href='"+feature.properties.dettaglio+"' >Più info</a></em></h4><p style='text-align: justify;'> </p>"
var marker = L.marker(latlng,{icon: L.icon({iconUrl:'icons/'+feature.properties.tipologia+'.png'})});
marker.bindPopup(html,{maxHeight:250});
markers.addLayer(marker);
}
});
map.addLayer(markers);
});
//end $.getJSON
</script>
Dallo script si evince che è stato dichiarata una variabile var markers = L.markerClusterGroup(); ovvero una variabile che sarà man mano riempita, aggiungendo ad essa tutti i markers che costituiranno i vari aggregati di punti.
Ho richiamato il file json attraverso la chiamata $.getJSON che tratta i dati dello stesso ed elabora l’oggetto di tipo L.geoJson . All’interno della sua funzione dell’attributo pointTolayer mi gestisco come devono essere visualizzati i dati all’interno del popup nel momento in cui il cluster si riduce a singolo punto.
Ho inoltre stilizzato il punto con icone personalizzate, conformi alla tipologia dichiarata tra gli attributi del json. Le icone sono lette da una cartella che potrete trovare all’interno del progetto scaricabile a questo link.
Da questo, il singolo marker viene costruito nel seguente modo,
var marker = L.marker(latlng,{icon: L.icon({iconUrl:'icons/'+feature.properties.tipologia+'.png'})});
Tale oggetto viene aggiunto a quello riferito al gruppo di markers, che, ricordiamo, è un contenitore di punti:
markers.addLayer(marker);
In chiusura l’intero gruppo di punti viene legato alla mappa con
map.addLayer(markers);
Il risultato finale è visibile cliccando sull’immagine della mappa:
Riferimenti web:
https://asmaloney.com/2015/06/code/clustering-markers-on-leaflet-maps/