Heatmap e Leaflet

      Commenti disabilitati su Heatmap e Leaflet
Funzionamento dell’algoritmo per la  Heatmap

Le Heatmap (o Mappe di Concentrazione) sono uno degli strumenti più potenti per la visualizzazione di gruppi di dati puntuali molto densi. Le mappe di concentrazione sono di solito utilizzate per individuare facilmente i cluster (ovvero dei raggruppamenti) lì dove è presente un’alta concentrazione di dati o fenomeni. Una delle caratteristiche principali è la loro tematica in quanto il territorio è classificato normalmente attraverso sfumature di colore che vanno dall’azzurro (bassa concentrazione) al rosso (alta concentrazione), passando per i valori intermedi tra il verde e il giallo. La scala di valori è generalmente compresa tra 0 e 1 a seguito di un’operazione di normalizzazione dei valori reali che contraddistinguono la rappresentazione dei dati puntuali e ne rappresenta il gradiente su cui si basa altresì la legenda di colori.

Alla base della creazione corretta di un Heatmap bisogna ricordare il concetto che essa risulta essere una mappa rappresentante una distribuzione continua di punti a partire da una discreta. La Heatmap dunque risulta essere una mappa risultato dovuto all’operazione di Interpolazione dei punti. L’ottimizzazione di tale risultato dipende da parametri quali la risoluzione delle celle, il raggio di ricerca e il tipo di operazione per interpolare i punti.

  • La risoluzione utilizzata dall’applicativo Leaflet è pari ad 1 unità per pixel in modo da evitare l’effetto “pixelato”.
  • Il raggio di default è solitamente pari a 25.
  • L’algoritmo utilizzato per l’interpolazione è l’IDW – Inverse Distance Weighting.

Il raggio determina chiaramente l’aerea d’influenza che i singoli punti hanno sugli altri. In dettaglio, su di una densità di punti si creano tanti buffer circolari quanti i punti appartenenti al data set. Fissato il raggio i buffer creano tanti cerchi in sovrapposizione che ne determinano una minore o maggiore intensità di colori sull’area designata.

Figure 4. How buffers overlap within the heat map.

L’interpolazione segue l’algoritmo IDW, che si basa sul principio, attraverso il quale, dato un punto il suo valore è più simile ai valori dei punti più vicini rispetto a quelli più lontani. Spesso è utilizzato per determinare le quote di un punto di cui è ignota l’altitudine. In altre parole, il peso di un dato punto è inversamente proporzionale alla distanza reciproca con gli altri.

https://gisgeography.com/wp-content/uploads/2016/05/IDW-3Points.png

L’algoritmo varia al variare dell’esponente p presente nella formula:

idw formula

Dove:

zi = sono i singoli pesi dei punti che ricadono nel raggio stabilito per la mappa di calore

di = sono le distanze del singolo pixel dagli altri punti (parametro costante, essendo le distanze uguali per tutti)

zp = è il peso da associare al singolo punto

Essendo di una distanza costante la formula si riduce in

z= ziN

Dato il raggio e il tipo di interpolazione si useranno solo quei punti che ricadono all’interno del raggio di ricerca per determinare il l’intensità di calore sui singoli pixel della mappa raster.

IDW Search Radius

La superficie di densità che risulta da tale operazione è visualizzata usando un gradiente di colori che permette all’utente di identificare immediatamente le aree ad alto tasso di concentrazione per un dato fenomeno.

Leaflet e le Heatmaps

Leaflet permette agevolmente di creare una mappa di concentrazione proprio attraverso i suoi numerosi plugin. Molto efficace è il plugin Leaflet.heat , il quale attraverso l’impostazione di alcuni parametri, passati nelle option renderizza una mappa di calore secondo le necessità dell’utente.
Il plugin gestisce un array di punti in input e un oggetto Javascript avente come option i seguenti parametri :

  • minOpacity – la minima opacità alla quale il calore inizierà ad apparire
  • maxZoom – il livello di zoom rispetto al quale i punti raggiungono la massima intensità
  • max – Intensità massima di un punto, 1.0 di default
  • radius – raggio di ogni punto della heatmap, 25 di default
  • blur – il gradi sfumatura ai contorni , 15 di default
  • gradient – gla configurazione del gradiente di colore, es. {0.4: 'blue', 0.65: 'lime', 1: 'red'}

Ci riferiremo ad un array di punti basato su uno shapefile che ho liberamente scaricato dal sito degli opendata della Regione Campania. Il file .zip è scaricabile da questo link. Il Dataset contiene una serie di shapefile con 1.389 Luoghi della Cultura della città di Napoli. Gli shapefile sono organizzati in base alla classificazione dei Luoghi per macrotipologia che sono state riunite per semplificare l’esempio in un unico file geojson lavorato in QGIS.  Per cui nella costruzione del nostro index.html ci baseremo al dataset luoghi_cultura_napoli.geojson.

Analisi del codice

Importiamo innanzitutto le librerie nella sezione <head>:

<!DOCTYPE html>
<html>

<head>
  <title>Concentrazione dei Luoghi della cultura a Napoli</title>
  <meta charset=”UTF-8″>
  <link rel=”stylesheet” href=”http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css” />
  <script src=”http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js”></script>
  <script src=”http://code.jquery.com/jquery-2.1.0.min.js”></script>
  <script src=”http://leaflet.github.io/Leaflet.heat/dist/leaflet-heat.js”></script>
 <style>
        #map { width: 100%; height: 600px; }
       body { font: 16px/1.4 “Helvetica Neue”, Arial, sans-serif; }

      .ghbtns { position: relative; top: 4px; margin-left: 5px; }
      a { color: #0077ff; }
 </style>
</head>

Una volta dichiarata la sezione head passeremo ad analizzare il codice della sezione body, scritto in questo modo:

<body>
<div id=”map”></div>
<script src=”http://leaflet.github.io/Leaflet.heat/dist/leaflet-heat.js”></script>
<script>

//Map Object with setView e Zoom

var map = L.map(‘map’).setView([40.842, 14.24], 13);

//OSM Tiles

var tiles = L.tileLayer(‘http://{s}.tile.osm.org/{z}/{x}/{y}.png’, {
attribution: ‘© <a href=”http://osm.org/copyright”>OpenStreetMap</a> contributors’,
}).addTo(map);

// Get GeoJSON file from URL

$.getJSON(‘luoghi_cultura_napoli.geojson’,function (data) {

// Building POI array for HeatMap by for cycle

addressPoints=[];
for (i = 0; i <data.features.length; i++)
{ addressPoints.push([data.features[i].geometry.coordinates[1],data.features[i].geometry.coordinates[0],Math.random()])
}

L.heatLayer(addressPoints, {radius: 25}).addTo(map);

});

//end $.getJSON

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

Ciò che è interessante è la sezione all’interno dello <script> con il nostro codice in Leaflet. Possiamo osservare la costruzione dell’oggetto che gestirà il nostro geojson , attraverso il comando jQuery $.getJSON , il permetterà di richiamare il nostro file che rappresenta il dataset . All’interno della chiamata è stato inserito un ciclo for ch egestisce i singoli attributi all’interno del file, costruendo un array utile da dare in pasto all’oggetto L.heatLayer.
Infatti, l’array chiamato addressPoints è composto da tre elementi per ogni riga le due coordinate e il parametro riferito all’intensità, per il quale ho utilizzato una funzione random con valori tra 0 e 1.

Il risultato finale dovrebbe darvi qualcosa del genere :

Allarga la mappa

Riferimenti