Dove sono gli alberi monumentali d’Italia?

L’elaborazione di un dataset e una richiesta al ministero

A fine 2017 il Ministero delle politiche agricole alimentari e forestali ha dato notizia della creazione e della pubblicazione del primo elenco degli Alberi Monumentali d’Italia.

L’elenco, diviso per Regioni, si compone di 2407 alberi che si contraddistinguono per l’elevato valore biologico ed ecologico (età, dimensioni, morfologia, rarità della specie, habitat per alcune specie animali), per l’importanza storica, culturale e religiosa che rivestono in determinati contesti territoriali.

È un dataset interessante, indispensabile per fare conoscere un patrimonio di grande valore, probabilmente poco noto.
Qui si vogliono evidenziare però due problemi: è pubblicato in modalità che non consentono di farne immediatamente un’analisi e non è associato a un licenza che ne consenta il riuso.
Questo post per chiedere al ministero di risolverli entrambi e per dare visibilità al dataset.

Quando sono venuto a conoscenza di questo catalogo (diverse settimane fa), ho avuto voglia di scoprire quali fossero gli alberi monumentali a me più vicini, ma con il passare del tempo l’obiettivo è diventato quello di avere una visione di insieme, nel contesto nazionale.
Per farlo ho creato — a partire dai dati del ministero — delle risorse in vari formati (CSV e GeoJSON), contenenti l’elenco degli alberi il cui iter amministrativo è completo (c’è un iter da seguire per finire in questo elenco).

Farlo (bene) non è stato semplice, ma soprattutto non è stato immediato. Ecco il percorso seguito.

Obiettivo propedeutico: estrarre un’unica tabella per tutti gli alberi italiani

Sul sito del ministero (salvo che non mi sia perso qualcosa), non c’è un file di insieme. I dati sono pubblicati in due raggruppamenti di file: uno per gli “alberi il cui iter amministrativo di iscrizione è completo” e l’altro per quelli ancora da perfezionare. Ho concentrato la mia attenzione sul primo.
 Questo contiene un elenco di 21 fogli di calcolo in formato Open Document (.ods): 19 regioni e le 2 province autonome di Bolzano e Trento.

La prima cosa (necessaria) è stata analizzarli un po’: emerge subito come siano file predisposti per essere letti a video e/o stampati e non per essere letti da un calcolatore e sottoposti a qualche analisi.

Struttura dei file originali

Tutti i file hanno almeno 4 righe di intestazione (vedi 1 nell'immagine di sotto); non va bene per dati da sottoporre ad analisi.

Inoltre sono presenti celle unite (ad esempio 2 e 3 nell'immagine di sotto) e una riga vuota, utilizzata soltanto per creare un rettangolo di separazione colorato in verde, tra intestazione e dati (4 nell'immagine di sotto). 
Un'altra "regola" da seguire nella pubblicazione di fogli elettronici, nel caso di dati pubblicati per essere analizzati, è proprio quella di non avere mai unione di celle.

Nel file .ods della Sicilia, ci sono delle colonne nascoste (P,Q,R e S).

I nomi delle colonne contengono caratteri da rimuovere. Ad esempio quello che contiene i valori dell’altezza — ALTEZZA (m) - contiene 22 spaziature tra ALTEZZA e (m); andrebbero ridotte a una. 
Infatti è (il puntino solo per dare evidenza dello spazio):

ALTEZZA······················(m)

Contenuti dei file originali

Due campi sono particolarmente problematici, quelli che contengono la longitudine e la latitudine di ogni albero: LONGITUDINE su GIS e LATITUDINE su GIS.

Per due ragioni principali:

  1. non contengono valori espressi in formato numerico;
  2. ci sono svariate modalità in cui sono sono espresse, dovute probabilmente a errori di battitura.

Un esempio della prima è quello della coppia 37°37'12,21" e 15°10'24,99". Alcuni sistemi informativi geografici sono in grado di importare coppie di coordinate espresse in questo modo (non in forma numerica), ma è bene che i caratteri usati per indicare gradi, minuti e secondi siano usati in modo omogeneo e corretto. Così come è bene che la scelta di eventuali spaziature sia omogenea.

A seguire alcuni esempi, che potranno sembrare corretti. Ma “il diavolo è nei dettagli”, qui riportati nella colonna nota:

Nel campo N. SCHEDA ci sono dei duplicati. Potrebbe non essere un errore, ma mi sembra utile segnalarlo: si tratta delle schede 01/D927/SV/07, 01/G157/AN/11, 04/G508/KR/18 e 06/A258/RI/12.

Ci sono diversi casi di spaziature inutili a fine cella. Nella colonna LOCALITÀ abbiamo ad esempio Villa comunale e Castiglione (con uno spazio in più dopo l'ultima vocale). Questo rende più difficile l'incrocio di questi dati con altri: laddove c'è uno spazio in più, sarà (più) difficile fare una correlazione diretta con nomi di luoghi scritti correttamente.

In ultimo una nota su un aspetto più botanico, legata alla classificazione (potrebbe essere scorretta, perché non sono un esperto di dominio).
Per ogni albero è indicato il nome scientifico — in modalità non omogenea — e non esiste una colonna valorizzata con uno degli identificatori internazionali possibili per una specie arborea
Il “Pinus nigra J.F.Arnold” (una delle specie presenti) corrisponde ad esempio all’identificatore 58042 del “Taxonomy Database by the National Center for Biotechnology Information”, o all’identificatore kew-2562349 del “The Plant List”.
Un campo con degli identificatori standard e internazionali (non sono sicuro che quelli di sopra lo siano, valgano come esempi), non solo è meno “sensibile” a errori di battitura, ma soprattutto consentirebbe di incrociare facilmente questo dataset con numerosi altri e di derivare decine di altre informazioni correlate, come ad esempio una foto di un albero di una data specie.
È uno dei principi fondanti dei Linked Open Data.

Gli strumenti utilizzati

Per creare il dataset derivato dai dati originali dati originali, ho creato uno script bash. Non sono soddisfatto di questo in termini di leggibilità e eleganza, è molto migliorabile; mi sono dedicato soprattutto a raggiungere l'obiettivo di avere un file di insieme un po' più usabile.

Nello script sono state utilizzate queste utility:

I file estratti

A partire dai 21 file di origine, sono stati creati due file:

Come contenitore di questo file e dello script che li ha generati, è stato scelto questo repository.

Alcune note sullo script

Evviva le espressioni regolari

La parte più critica è stata quella di gestire le varie difformità di trascrizione delle coppie di coordinate. Ma per fortuna esistono le espressioni regolari.

Usandole sono riuscito a estrarre in ordine corretto e uniforme, da stringhe scritte in vario modo (come quelle di sotto), soltanto le porzioni interessanti (indicate con colori diversi) — ovvero la parte numerica di gradi, minuti e secondi — e scartare tutto il resto.

L’espressione regolare usata è testabile qui, sul comodissimo regex101.

Convertire i file ODS in batch

Mi ha colpito dover “soffrire” un po’ per trovare rapidamente una modalità per farlo, che fosse semplice e non richiedesse l’installazione di centinaia di Mb di installazione di software.

Si può fare con unoconv o con OpenOffice/LibreOffice headless (senza interfaccia). Ma è richiesta l’installazione di quasi 200 Mb di pacchetti software.

Ho chiesto allora una mano sul web alla ricerca di alternative e ho scoperto la bella galassia di pyexcel: dei moduli Python per “fare cose” con dati tabellari pubblicati in vari formati. Ne esiste pure una versione “a riga di comando”, con cui è possibile convertire file da ods a csv.

Il comando di base è:

pyexcel transcode --sheet-index 0 "fileInput.ods" "fileOutput.csv

--sheet-index 0 per definire che la conversione deve essere fatta sul primo foglio del file di input.

Associare il codice comunale ISTAT a ogni albero

Un codice che è comodo associare a ogni albero è quello ISTAT del comune in cui ricade. Consente di fare conteggi aggregando e di mettere in relazione questi dati con altri. 
 Questa associazione in termini “spaziali” è definita POINT IN POLYGON: dato un punto di coordinate note, si determina qual è il poligono comunale "toccato" dal punto, si estrae l'attributo poligonale di interesse e si associa al punto.

Si può fare in tanti modi; qui a seguire due di esempio (nello script è stata usata la seconda).

Con GDAL/OGR

Con OGR è possibile fare query SQL di natura geografica/spaziale, utilizzando il dialetto sqlite.

Impostando un file sorgente virtuale in formato XML, con definito qual è il file con la posizione degli alberi e quello con i limiti dei comuni

<OGRVRTDataSource>
<OGRVRTLayer name="alberiMonumentali" relativeToVRT="1">
<SrcDataSource>./alberiMonumentali.geojson</SrcDataSource>
</OGRVRTLayer>
<OGRVRTLayer name="comuni" relativeToVRT="1">
<SrcDataSource>./risorse/comuni.shp</SrcDataSource>
</OGRVRTLayer>
</OGRVRTDataSource>

si userà ogr2ogr, l'utility di conversione file di GDAL/OGR, applicando una query SQL spaziale:

ogr2ogr -f CSV alberiMonumentali_tmp.csv input.vrt -dialect sqlite -sql "select A.id,A.comune, B.PRO_COM_T from alberimonumentali AS A, comuni AS B WHERE ST_Intersects(A.geometry,B.geometry)"

La funzione “chiave” è ST_Intersects(A.geometry,B.geometry) che verifica se i punti "toccano" i comuni, e se sì estrae il codice comunale ISTAT. È un'operazione che dura diversi secondi.

Mapshaper

È un’utility “geografica” straordinaria, purtroppo non troppo nota. Consente di modificare Shapefile, GeoJSON, TopoJSON, CSV e altri formati e supporta diversi task essenziali come la semplificazione di forme (è la caratteristica per cui è più noto), la modifica di attributi, il clipping, il dissolve, il filtraggio e anche il join spaziale (che è ciò che serve qui).

Il comando ha questa struttura di base

mapshaper alberiMonumentali.geojson -join ./risorse/comuni.shp fields=PRO_COM_T -o alberiMonumentaliISTAT.csv

Per punti:

  • si definisce il layer a cui si vogliono associare dati (in questo caso quello degli alberi);
  • si definisce l’operatore, qui join;
  • si definisce il layer che contiene le informazione da associare al layer di destinazione (qui i limiti comunali);
  • si definisce quale campo del file sorgente si vuole passare a quello di destinazione (qui il codice PRO_COM_T);
  • si definisce il file di output.

Mapsharper è molto rapido e “stampa” in output alcune informazioni:

[join] Joined 875 data records
[join] 8/2065 target records received no data
[join] 7085/7960source records could not be joined

Si tratta:

  • del numero di record del file sorgente coinvolti. Qui sopra sono 875, perché ci sono alberi monumentali in 875 comuni italiani;
  • del numero di record del file di destinazione a cui non è stato possibile associare informazioni. Qui 8, quindi 8 comuni non “toccano” il layer dei comuni;
  • del numero di record del file sorgente non coinvolti. 7085 comuni su 7960 non hanno un albero monumentale nel loro territorio.

Buone letture

Qui alcune letture, dedicate a come è bene pubblicare dati tabellari:

Note finali

  • Alcuni record — circa 15 — hanno delle problematicità sulle coordinate, che non sono state risolte in questa versione dello script (e alcuni potrebbero non esserlo mai). Quindi non sono presenti nel dataset finale (sono quelli del file alberiMonumentaliErroriCoordinate.csv);
  • ad alcuni record — meno di 10 — non è stato possibile associare il codice ISTAT, perché ricadono poco fuori i limiti poligonali usati (sono quelli generalizzati di ISTAT, scaricabili da qui). In una versione successiva dello script, si potrebbe aggiungere una “tolleranza” rispetto al poligono più vicino;
  • ho dato per scontato che il sistema di coordinate scelto in origine fosse con datum World Geodetic System 1984. È probabile che sia così, ma non è certo. Se così non fosse, la posizione che ho estratto non sarebbe corretta;
  • nei file finali è stata aggiunta una colonna, per dare conto del file di origine (Sicilia, Lombardia, ecc.);
  • i contenuti della colonna CRITERI DI MONUMENTALITA' sono stati modificati. In origine è una colonna multivalore - è un array - i cui valori non sono separati però in modo uniforme. In questa versione dello script sono stati separati con un |;
  • i file CSV creati dal mio script hanno come separatore la , e come encoding dei caratteri l'UTF-8;
  • i file che ho derivato, purtroppo non sono dati aperti e non sono quindi riutilizzabili. Finché il ministero non associa ai dati che pubblica una licenza adeguata, quelli creati dal mio script rimangono essenzialmente poco più di un mio “sfogo creativo”.

Questi alberi sono dei “monumenti vegetali”. Questo dataset si presta a tante applicazioni “derivate”, a riusi molto creativi e interessanti per il racconto e la conoscenza del nostro territorio, per la valorizzazione dei beni ambientali e culturali che lo caratterizzano. Per questo si rinnova la richiesta al ministero di pubblicare — oltre ai file pensati per la stampa e la lettura a video — anche un unico file con l’elenco di tutti gli alberi (con almeno le coordinate “normalizzate” e con rimosse intestazioni inutili e celle unite) e associargli una licenza che ne consenta il riuso.