Leaflet stile punti

Leaflet: come definire lo stile di un layer di punti

Rappresentare graficamente in modo appropriato un layer vettoriale su una mappa non è soltanto un fatto estetico, ma spesso implica anche una buona o cattiva resa dell’informazione geografica che vogliamo trasmettere agli utenti. In questo articolo vediamo come possiamo definire  lo stile di un layer di punti con Leaflet.

Quando con Leaflet leggiamo un layer vettoriale di punti, di default questi vengono rappresentati con il tipico marker a palettina. In questo semplice esempio, visualizziamo un file geoJSON  che rappresenta alcuni distributori di carburante nella Toscana, senza definire nessuno stile personalizzato:

e il risultato è il seguente:

marker punti

Definire un marker personalizzato

Se non vogliamo usare il marker di default, dobbiamo definire un nostro stile e per esempio usare come segnaposto una immagine (icona) in un formato che consenta la trasparenza (di solito PNG o SVG). Per farlo usiamo la classe L.icon di Leaflet con la quale indichiamo innanzitutto il percorso del file immagine da adoperare (iconUrl) e poi altre eventuali opzioni che servono per definirne altre proprietà.

L.icon( )

Sicuramente un’opzione che dovremo usare è iconAnchor con la quale si imposta la posizione dell’icona rispetto al punto geografico che deve segnare; in pratica bisogna indicare le coordinate in pixel del punto-immagine (valore di default è [0, 0]) che si vuole coincida col punto geografico. Per il nostro esempio, usiamo un’icona personalizzata (file: fuel_icon.png) che ha dimensioni 40×44 pixel e che definiamo così:

iconAnchorLa figura accanto, spiega quale pixel dell’immagine-icona abbiamo scelto come anchor al punto geografico.

Con l’opzione iconSize se vogliamo possiamo modificare le dimensioni con cui l’icona verrà rappresentata rispetto a quelle originali; normalmente questa si usa se l’immagine è in formato SVG per ingrandirla o ridurla a piacimento, altrimenti modificando le dimensioni originali si può rischiare di deformarla.

Se scegliamo che l’icona abbia anche un’ombra (come ce l’ha il marker di default), allora ci sono  le opzioni shadow… che ci permettono di definirla. Banalmente l’ombra è un file immagine a parte.

Fatto questo, per assegnare questa icona personalizzata ai punti del layer vettoriale, usiamo l’opzione pointToLayer della classe L.geoJson. Più precisamente si tratta di una funzione che, per ogni punto geografico del layer vettoriale, ritorna la sua rappresentazione grafica sulla mappa. Riprendendo il nostro esempio (distributori di carburante) ecco come si usa:

Come si vede, viene adoperata la classe L.marker per assegnare ai punti del layer, l’immagine prima definita con L.icon. Il risultato è il seguente:

marker custom

Usare come segnaposto i cerchietti

Se vogliamo rappresentare i punti sulla mappa con dei semplici cerchietti (o pallini) senza usare nessuna icona, usiamo ancora la funzione pointToLayer ma richiamando al posto di L.marker la classe L.circleMarker che appunto disegna dei cerchi di raggio (radius) specificato in pixel. Oltre al raggio, abbiamo le opzioni per definire: colore, bordo (spessore e colore), trasparenza, …, etc; attenzione alla differenza tra le opzioni che riguardano il riempimento (fill) ed il bordo del cerchietto.
Ecco l’esempio pratico:

marker cerchi

Stile in funzione di un attributo

Parlando di dati geografici generalmente  questi sono corredati da attributi (o proprietà) caratterizzanti ogni singolo elemento. Allora una loro rappresentazione grafica più funzionale può prevedere uno stile che dipenda da qualcuno di questi attributi, ovvero che cambi aspetto in funzione del valore di uno o più attributi.

Può cambiare: il tipo di simbolo, il colore, la grandezza, … etc; in altre parole si definiscono delle classi grafiche che raggruppano elementi  aventi uno stesso valore di proprietà (o una combinazione di più proprietà)

Riferendoci sempre al nostro esempio dei “distributori di carburante”, ogni punto ha un attributo denominato brand che riporta la “marca” del gestore: Esso, Agip, IP, Shell, … etc. Allora per esempio si può pensare ad uno stile, che rappresenti dei cerchietti di colore diverso a seconda di questa marca.

Partiamo dall’esempio precedente, nel quale con la funzione pointToLayer abbiamo disegnato in ogni punto un cerchietto, con la differenza che adesso il parametro circle_style lo facciamo dipendere dal valore che l’attributo brand assume per ogni elemento (feature) del layer. Più precisamente circle_style diventa una funzione che dipende dalle proprietà della feature, ecco come:

Notate il costrutto switch con cui, sulla base del valore che assume la proprietà brand si assegna un determinato colore alla variabile Fcolor, che poi viene indicata come colore di riempimento (FillColor); gli altri parametri del cerchietto sono invece costanti.

Quindi assegniamo questa funzione circle_style(feature) come paramentro di L.circleMarker:

il risultato è questo:

categ_style

Naturalmente chi guarda questa mappa non può capire cosa significano i diversi colori e quindi in qualche modo dovremo aggiungere una legenda. Ci sono diversi  modi per farlo,  per esempio rappresentare una tabella, in qualche parte dentro o fuori la mappa, dove accanto ad ogni colore si indichi la corrispondente marca (Esso, IP, ERG, … etc).

Per farlo usiamo la classe L.control di Leaflet che serve per posizionare un controllo generico dentro il riquadro mappa; la sua proprietà position serve appunto per stabilire dove posizionarlo con quattro possibilità; angolo Sx alto, angolo Dx alto, angolo Sx basso, angolo Dx basso. Nel nostro esempio abbiamo scelto l’ angolo Dx basso (bottomright).

Quindi per questo oggetto L.control istanziato e che chiamiamo legend, definiamo il metodo onAdd che descrive che azione si deve compiere quando l’oggetto viene aggiunto nella mappa; il codice completo è il seguente:

Senza scendere nei dettagli si vede che in HTML abbiamo disegnato una tabella dove ogni riga è composta da due celle (o colonne):

  • la prima cella è vuota ma è colorata con uno dei colori usati prima per definire il FillColor dei cerchietti (stesso codice HEX);
  • la seconda cella contiene il nome della marca di carburante che corrisponde a quel colore.

Poi tramite il metodo L.DomUtil.create (‘div’, ‘info legend’)  si crea l’elemento <div> della legenda (con dentro la tabella dei colori)  e questo è disegnato graficamente secondo lo stile CSS info così definito:

Il risultato è il seguente e per vedere l’esempio completo funzionante cliccate qui.

map legenda

 

 

condividi: