Archivio del mese di gennaio, 2011

24 gennaio, 2011 | di

La materia è quella della tutela della privacy in ambito lavorativo: in sostanza, si tratta di stabilire quanto e a quali condizioni si possa spingere l’autonomia organizzativa del datore di lavoro quando vengono coinvolti i diritti primari del lavoratore.

Sempre più spesso l’esigenza di ottimizzare il lavoro aziendale spinge l’imprenditore a far uso di tutte quelle tecnologie che consentono di monitorare in tempo reale la dislocazione dei propri mezzi e dei dipendenti sul territorio. D’altro canto tali esigenze non possono violare i diritti inviolabili del lavoratore, il quale, nell’espletamento degli incarichi affidati, ha il pieno diritto a non veder violata la propria privacy.
In tal senso, nel presente articolo ci è sembrato utile e opportuno, non solo illustrare il caso concreto sottoposto all’Autorià Garante per la tutela dei dati personali, ma anche inserire in calce un piccolo vademecum degli adempimenti da rispettare.

Ci sia consentita un’ultima notazione di carattere generale (per altro di estrema attualità): al di là del rispetto formale della normativa – che deve essere un adempimento ineludibile, necessario e preliminare in ipotesi di tal genere – è sempre importante coinvolgere fattivamente i lavoratori nell’attività produttiva dell’azienda. Tale coinvolgimento può essere raggiunto solo attraverso una reale e adeguata comunicazione delle esigenze e delle strategie aziendali.
Casi, come quello di seguito descritto, costituiscono, a volte e al di là del rispetto formale della normativa, l’indice di un malessere lavorativo che le norme, da sole, non possono eliminare.

Il caso trae origine da una segnalazione effettuata da un dipendente di una azienda telefonica al Garante per la Privacy, in merito all’installazione, a bordo di alcuni autoveicoli in dotazione al personale della stessa, di un sistema di localizzazione satellitare a tecnologia gps.

In particolar modo il dipendente evidenziava il fatto che tale installazione “sarebbe avvenuta in assenza di preventiva informativa ai lavoratori e senza spiegarne le funzioni né lo scopo del suo utilizzo. Peraltro, soltanto dopo diversi giorni la società avrebbe messo a conoscenza i dipendenti dell’avvenuta installazione dei dispositivi in esame, giustificandone l’utilizzo solo per scopi produttivi”.

L’azienda – che in relazione alla segnalazione effettuata aveva presentato le proprie controdeduzioni all’Authority circa la correttezza del proprio operato – aveva commissionato ad una società esterna di installare dei dispositivi che avrebbero consentito:

  • di localizzare i veicoli in dotazione in tempo reale  su mappa cartografica (con possibilità, tra le altre, di ricerca dei mezzi più vicini ad un determinato indirizzo);
  • di verificare il percorso effettuato (con possibilità anche di controllare la velocità sostenuta, la percorrenza chilometrica del mezzo, i tempi di guida e le soste effettuate);
  • di controllare gli “eventi” verificatisi lungo il percorso (soste o spostamenti in orari non previsti, arrivo in aree predeterminate, ecc.), con eventuale ricezione di una comunicazione di avviso via sms;
  • di comunicare costantemente con il conducente;
  • di gestire i c.d. “punti di interesse” (indirizzi riferiti alla clientela, ai magazzini, agli impianti, ecc.), con possibilità di verificare mediante report sintetici le soste ivi effettuate e i relativi tempi di fermata;
  • di gestire la manutenzione ordinaria e straordinaria del veicolo.

Il caso in oggetto presenta diversi aspetti rilevanti sotto il profilo della materia giuslavoristica, commerciale e di tutela dei dati personali.

In questa sede riteniamo di soprassedere dalle, pur interessanti, considerazioni concernenti il diritto dell’imprenditore di gestire la propria impresa come meglio ritiene opportuno, e ciò  anche con riferimento alla materiale organizzazione del lavoro dei propri dipendenti (artt. 2082, 2086, 2104  c.c.). Tale diritto, comunque, deve essere pur sempre contemperato con il rispetto dell’art. 4 della Legge 300/1970 (c.d. Statuto dei Lavoratori) il quale prevede che:

È vietato l’uso di impianti audiovisivi e di altre apparecchiature per finalità di controllo a distanza dei lavoratori.
Gli impianti e le apparecchiature di controllo che siano richiesti da esigenze organizzative e produttive ovvero dalla sicurezza del lavoro, ma dai quali derivi al possibilità di controllo a distanza dell’attività dei lavoratori, possono essere installati soltanto previo accordo con le rappresentanze sindacali aziendali, oppure, in mancanza di queste, con la commissione interna. In difetto di accordo, su istanza del datore di lavoro, provvede l’ispettorato del lavoro, dettando ove occorra, le modalità per l’uso di tali impianti
”.

Nel caso di specie distinguiamo, quindi:

  1. Aspetti relativi all’organizzazione produttiva dell’impresa;
  2. Aspetti relativi all’attività di controllo del lavoro espletato dai dipendenti;
  3. Aspetti relativi al diritto dei lavoratori a non essere lesi nella propria dignità, libertà e riservatezza.

Questi elementi sono stati sempre oggetto di un ampio dibattito legislativo e dottrinale.
Varia, numerosa e copiosa, nel corso del tempo, è stata la produzione giurisprudenziale circa la valutazione della liceità o meno del comportamento del datore di lavoro con riferimento al controllo aziendale relativo: all’installazione di apparecchi audiovisivi sui posti di lavoro, al monitoraggio delle connessioni internet sui pc aziendali,  all’installazione di apparecchi di rilevazione delle telefonate ingiustificate, alla localizzazione dei propri dipendenti.

In generale possiamo dire che l’orientamento della Corte di Cassazione, cui sono giunti in ultimo grado i vari ricorsi, è stato quello di distinguere tra controlli offensivi e controlli difensivi.
Offensivo è il controllo atto ad una sorveglianza del dipendente che lede i diritti primari dell’individuo;  lecito, invece, sarebbe il c.d. controllo difensivo. All’interno di quest’ultima categoria la giurisprudenza ha distinto – con varie ed oscillanti pronunce -tra:

  • controlli diretti ad accertare possibili comportamenti illeciti dei lavoratori in relazione all’esatto adempimento delle obbligazioni lavorative;
  • controlli che riguardano la tutela di beni estranei al rapporto lavorativo.

Tuttavia il caso in questione si muove su una linea di confine tra l’ottimizzazione del lavoro ed il controllo dei lavoratori.
Infatti, come sopra evidenziato, i dispositivi gps in questione non solo erano montati sui veicoli aziendali e non sulla persona dei lavoratori, ma, inoltre, le finalità di tale installazione era quella di una migliore e più efficiente organizzazione del lavoro.

Per completezza espositiva, riportiamo le conclusioni del Garante (il cui provvedimento – doc. web n. 1763071 – è reperibile qui), il quale ha censurato il comportamento dell’azienda solo in relazione al non corretto rispetto dell’iter procedimentale atto alla installazione dei suddetti dispositivi gps, ritenendo, invece legittime le finalità del montaggio di tali apparecchiature sui veicoli aziendali.
Tale precisazione è dovuta a fronte di titoli delle rassegne giornalistiche e dei blog più o meno specializzati, del tenore: “bloccata la localizzazione dei dipendenti con GPS”.

Vogliamo, allora, fornire una breve sintesi degli adempimenti da conoscere e rispettare in casi analoghi a quello esaminato:


1. Effettuare una istanza al Garante (ufficio territoriale competente) di verifica e di autorizzazione al trattamento dei dati.
L’art. 17 D.Lgs 196/2003, infatti  prevede:
Trattamento che presenta rischi specifici
1. Il trattamento dei dati diversi da quelli sensibili e giudiziari che presenta rischi specifici per i diritti e le libertà fondamentali, nonché per la dignità dell’interessato, in relazione alla natura dei dati o alle modalità del trattamento o agli effetti che può determinare, è ammesso nel rispetto di misure ed accorgimenti a garanzia dell’interessato, ove prescritti.
2. Le misure e gli accorgimenti di cui al comma 1 sono prescritti dal Garante in applicazione dei principi sanciti dal presente codice, nell’ambito di una verifica preliminare all’inizio del trattamento, effettuata anche in relazione a determinate categorie di titolari o di trattamenti, anche a seguito di un interpello del titolare.
In tal senso è necessario corredare la richiesta con tutti gli elementi che caratterizzano il trattamento. Da non sottovalutare la determinazione dei tempi di conservazione dei dati acquisiti per il tramite dei dispositivi, commisurandoli, ove necessario, alle effettive necessità di conservazione in rapporto alle specifiche finalità concretamente perseguite. E’ opportuno segnalare che, qualora si tratti di dispositivi gps installati su mezzi aziendali, oltre alle specifiche e tecniche esigenze temporali di conservazione dei dati, vi sono da valutare i tempi per la notifica da parte dell’Autorità delle infrazioni. In tal senso ricordiamo che La multa stradale deve essere notificata al trasgressore (o presunto tale dall’Autorità) entro 90 giorni (in caso di residenza in Italia)

2. Notificare al Garante il trattamento di dati personali cui intende procedere.
In particolar modo con riferimento agli adempimenti previsti dagli artt. 37 e ss del titolo VI del Decreto legislativo 30 giugno 2003, n. 196. L’art. 37 cit. infatti prevede che il titolare notifica al Garante il trattamento di dati personali cui intende procedere, solo se il trattamento riguarda dati genetici, biometrici o dati che indicano la posizione geografica di persone od oggetti mediante una rete di comunicazione elettronica.

3. Ottenuta l’autorizzazione, procedere alla stipula di un accordo con le rappresentanze sindacale Aziendali ovvero, in caso di assenza di queste ottenere l’autorizzazione dell’Ispettorato del lavoro.

4. Effettuare una corretta e completa informativa ai lavoratori nella quale devono essere riportate le finalità del trattamento dei dati localizzazione;

5. Il consenso dei lavoratori al detto trattamento, seppur auspicabile, non risulta necessario.
Infatti, secondo quanto previsto dall’art. 24, comma 1, lettera g) del Decreto legislativo 30 giugno 2003, n. 196 il quale prevede che  Il consenso non è richiesto, oltre che nei casi previsti nella Parte II, quando il trattamento  è necessario, nei casi individuati dal Garante sulla base dei principi sanciti dalla legge, per perseguire un legittimo interesse del titolare o di un terzo destinatario dei dati, anche in riferimento all’attività di gruppi bancari e di società controllate o collegate, qualora non prevalgano i diritti e le libertà fondamentali, la dignità o un legittimo interesse dell’interessato (c.d bilanciamento degli interessi di cui parlavamo nel corpo del presente articolo).

6. Designare gli incaricati del trattamento.
Ovvero i soggetti che, in ragione delle mansioni svolte, risultino effettivamente legittimati ad accedere alle informazioni acquisite per il tramite dei dispositivi di localizzazione satellitare

7. Adottare tutte le necessarie misure di sicurezza previste dal Codice della Privacy.
E ciò con particolare riferimento agli artt. da 33 ( Capo II – Misure minime di sicurezza) a 37  (Titolo VI – Adempimenti) ed all’Allegato B, D.Lgs. 196/2003 (disciplinare tencico in materia di misure minime di sicurezza).


Link:

Provvedimento del Garante per la Protezione dei Dati Personali del 07.10.2010
Decreto legislativo 30 giugno 2003, n. 196

17 gennaio, 2011 | di

Scopo del presente post è presentare un formidabile linguaggio di scripting, in cui io e Giovanni Allegri ci siamo imbattuti da un po’ di tempo a questa parte, che presenta delle potenzialità davvero eccezionali nel processamento di dati geospaziali. Il pretesto occasionale che ha riacceso il nostro sopito interesse nei confronti di JEQL é un recente post del blog Lin.ear Th.inking, Visualizing geodetic information with JEQL, in cui l’autore Martin Davis (aka “Dr JTS”, l’attuale designer e lead developer della fantastica libreria JTS …e non solo!) introduce delle nuove funzioni geodetiche di calcolo sulle geometrie all’interno di JTS, illustrandone l’utilizzo mediante un’applicazione in JEQL che ripercorreremo nel seguito.

Cos’è JEQL?

JEQL è un Query Language sviluppato in Java, dove la “E” può assumere i seguenti significati:

  • Extended, poiché implementa un numero sempre crescente di estensioni che lo rende più potente nel processamento dei dati rispetto alle tante versioni e dialetti SQL esistenti;
  • Embeddable, in quanto il motore di JEQL può essere integrato all’interno di altre applicazioni, in modo da essere utilizzato come query language per modelli di dati tabellari;
  • ETL, essendo l’Extract/Transform/Load il caso d’uso ideale di JEQL;
  • Efficient, dato che garantisce velocità di sviluppo ed esecuzione.

JEQL è dunque un linguaggio di scripting che consente il processamento di strutture di dati tabellari, compresi quelli geografici vettoriali. Fin qui nulla di nuovo, probabilmente penseranno i lettori esperti dei possenti RDBMS con estensione spaziale (PostgreSQL + PostGIS, Oracle Spatial, MySQL, ecc.) o del più leggero e, al tempo stesso, molto versatile SpatiaLite. Analogamente a quest’ultimo, JEQL non richiede l’installazione di un server database e ciò, assieme al fatto che è un linguaggio di scripting, rappresenta un grosso vantaggio in termini di portabilità. Si pensi ad esempio alla replicazione della configurazione di un DBMS a distanza di parecchio tempo oppure alla condivisione di uno script con un nostro collega. Inoltre, anche la velocità di sviluppo e di esecuzione rappresentano dei non trascurabili punti di forza. Naturalmente, esistono anche dei task non coperti da JEQL per i quali un RDBMS è insuperabile.
Quali tipi di dati è in grado di utilizzare? Oltre ai classici tipi Java (interi, stringhe, double) e le date, JEQL supporta anche le geometrie JTS e un vasto repertorio in continua crescita di funzioni spaziali, costruttori di predicati e funzioni di aggregazione, che lo rendono uno strumento particolarmente adatto per il processamento di dataset spaziali. Inoltre, è in grado di accedere in lettura e scrittura a diversi formati di dati (CSV, DBF, SHP, KML) e database compatibili con JDBC (Java Data Base Connectivity).
L’installazione di JEQL è molto semplice: nei sistemi operativi Windows, basta scompattare il pacchetto di installazione (è appena stata rilasciata la versione 0.9) in una cartella con percorso non contenente spazi ([JEQL_HOME]) ed aggiungere nella variabile PATH di sistema il percorso [JEQL_HOME]\bin. Manca, tuttavia, uno script shell o qualcosa di analogo per Linux, che tuttavia non dovrebbe essere difficile da produrre.
L’apprendimento del linguaggio JEQL è abbastanza rapido, soprattutto per chi possiede già dei rudimenti di SQL, ed è facilitato dall’interprete che guida l’utente nell’individuazione e nella correzione degli errori. Il pacchetto di installazione è inoltre corredato da una lista di unit test, ovvero gli stessi esempi basilari utilizzati in fase di collaudo del codice. La documentazione rappresenta invece una delle poche note dolenti, essendo ancora un work in progress, nonostante la presenza di alcuni illuminanti esempi applicativi, diversi post su Lin.ear Th.inking e una mailing list dedicata, oltre alla indiscutibile cortesia e competenza dello sviluppatore.
Attualmente JEQL è rilasciato con doppia licenza: freeware e “commerciale”. Quest’ultima per consentirne l’integrazione all’interno di software commerciali (…e in quelli open source?).

Un esempio applicativo: worldAirRoutes.jql

Nel seguito, si cercherà di fornire un saggio delle potenzialità di JEQL, proponendoci le stesse finalità del post citato in precedenza, ovvero disegnare le rotte aeree a scala globale secondo linee ortodromiche, piuttosto che linee rette, con tutti gli accorgimenti del caso al fine di ottenere una buona resa grafica. Ci cimenteremo passo dopo passo con le fasi di importazione e normalizzazione dei dati di interesse fino al raggiungimento dello scopo. I dati utilizzati nell’applicazione sono:

In particolare, i primi due sono parte degli open data del progetto OpenFlights, rilasciati con Open Database License (Odbl), mentre lo shapefile semplificato dei world borders (a proposito della loro qualità, si consiglia la lettura di questo post e successivi) è rilasciato da thematicmapping.org con licenza Creative Commons CC-SA.
Dopo aver installato JEQL 0.9, creiamo una cartella, vi collochiamo i dati appena scaricati (scompattando naturalmente lo zip file) e vi definiamo inoltre un semplice file di testo (worldAirRoutes.jql) nel quale andremo a scrivere il nostro codice.
Il primo passo dell’applicazione consiste nell’importazione dei dati relativi agli aeroporti (airport.dat), tenendo presente che i file .dat in esame sono in formato CSV:

// Read data from CSV
CSVReader airports file: "airports.dat";
numAirports = select count(*) from airports;
Print "Number of airports to clean: " + val(numAirports);
Print airports limit: 10;

Salviamo lo script, apriamo il prompt dei comandi e collochiamoci nella directory che lo contiene. Per eseguirlo occorre digitare jeql worldAirRoutes.jql e premere il tasto Invio. Successivamente, nel prompt dei comandi comparirà qualcosa del genere:

Number of airports to clean: 6344
col1:String, col2:String, col3:String, col4:String, col5:String, col6:String, col7:String, col8:String, col9:String, col10:String, col11:String
1 Goroka Goroka Papua New Guinea GKA AYGA -6.081689 145.391881 5282 10 U
2 Madang Madang Papua New Guinea MAG AYMD -5.207083 145.7887 20 10 U
3 Mount Hagen Mount Hagen Papua New Guinea HGU AYMH -5.826789 144.295861 5388 10 U
...

La prima cosa che scopriamo è che le colonne della tabella “airports” sono identificate come “col1, col2 … colN”, sebbene il file CSV sia sprovvisto delle relative intestazioni dei campi (per la descrizione dei quali si rimanda a questa pagina), e che i campi sono considerati tutti di tipo String. Procediamo quindi con la normalizzazione dei dati degli aeroporti, selezionando i dati di nostro interesse:

// Select airports data with valid IATA airport code
airports2 = select
  col2 as name,
  col3 as city,
  col4 as country,
  col5 as code,
  col7 as lat,
  col8 as lon
  from airports
  where RegEx.matches(col5,'[A-Z]{3}');

E’ interessante notare che:

  • per definire gli alias dei campi di una tabella è utilizzata la parola chiave as, così come avviene solitamente in molte versioni di SQL, tuttavia si tenga presente che in JEQL il suo uso è a discrezione dell’utente;

Occorre, inoltre, verificare la presenza di eventuali codici IATA duplicati, in modo da essere certi dell’univocità del campo “code”, al fine di utilizzarlo poi come chiave esterna nelle operazioni di join con la tabella delle rotte aeree (routes.dat), come si vedrà nel seguito.

// Find duplicate IATA airport codes in airports data
duplicateCodes = select *
  from (select code, count(code) as numOccurrences
    from airports2
    group by code) as duplicates
  where numOccurrences > 1;
Print duplicateCodes;

A fronte di tale verifica, si riscontra un unico codice duplicato (“TCG”). Avvalendoci dell’ausilio della banca dati ufficiale è possibile risolvere tale ambiguità, scartando l’aeroporto di Tocache (Cina) al quale è stato erroneamente attribuito questo codice. A tal fine, la clausola where della prima select diventa:

  where RegEx.matches(col5,'[A-Z]{3}')
  and col3!="Tocache";

E’ dunque possibile commentare il codice relativo alla ricerca dei duplicati (“//” commenta una singola riga, mentre “/* … */” tutto il codice tra essi compreso – non a caso, come nel linguaggio Java) e verificare la bontà dei risultati fin qui ottenuti, visualizzando eventualmente i primi dieci record della tabella “airports2”.

// Check intermediate results
numAirports2 = select count(*) from airports2;
Print "Number of airports without duplicates: " + val(numAirports2);

Omettendo per brevità la visualizzazione del contenuto delle tabelle, otteniamo:

Number of airports without duplicates: 5023

Successivamente, si procede all’importazione e normalizzazione dei dati relativi alle rotte aeree (routes.dat). In particolare, selezioniamo i codici IATA degli aeroporti di origine e destinazione relativi a ciascuna rotta aerea, e li combiniamo in un’unica stringa in modo da poter escludere le rotte duplicate mediante l’operazione di raggruppamento (group by). Da queste stringhe è poi possibile recuperare nuovamente i codici dai quali sono stati ottenuti. Inoltre, definiamo una chiave primaria “rid” tramite la funzione rownum() che restituisce il numero di riga.

// Read data from CSV
CSVReader routes file: "routes.dat";
numRoutes = select count(*) from routes;
Print "Number of routes to clean: " + val(numRoutes);
	
// Select routes data removing duplicates
routes2 = select
  rownum() as rid,
  String.substring(routeCode, 0, 3) as fromCode,
  String.substring(routeCode, 3, 6) as toCode
  from (select
    //col3 as fromCode,
    //col5 as toCode,
    col3+col5 as routeCode
    from routes
    order by routeCode asc) as routesWithDuplicates
  group by routeCode;
	
// Check intermediate results
numRoutes2 = select count(*) from routes2;
Print "Number of routes without duplicates: " + val(numRoutes2);

ottenendo:

Number of routes to clean: 64114
Number of routes without duplicates: 36004

Il task successivo consiste nell’associare ad ogni rotta aerea le coordinate dell’aeroporto di partenza e di quello di destinazione, scartando le coordinate con valore null e validando quelle che non lo sono, facendo ancora una volta ricorso alle espressioni regolari.

// Extract origin airport data
fromAirport = select
  rid,
  fromCode,
  name as fromName,
  city as fromCity,
  country as fromCountry,
  lat as fromLat,
  lon as fromLon
  from routes2
  left outer join airports2
  on routes2.fromCode == airports2.code;
	
// Extract destination airport data
toAirport = select
  rid,
  toCode,
  name as toName,
  city as toCity,
  country as toCountry,
  lat as toLat,
  lon as toLon
  from routes2
  left outer join airports2
  on routes2.toCode == airports2.code;
	
// Join the last two tables (removing records with null coords)
troute = select fromAirport.*, toAirport.* except rid
  from fromAirport
  join toAirport
  on fromAirport.rid==toAirport.rid
  where not Val.isNull(fromLat) and not Val.isNull(fromLon) and not Val.isNull(toLat) and not Val.isNull(toLon);
	
// Check if coords are valid
troute2 = select *
  from troute
  where RegEx.matches(fromLat,'-?((([0-9]|[1-8][0-9])(\.[0-9]*)?)|(90))')
  and RegEx.matches(fromLon,'-?((([0-9]|[1-9][0-9]|1[0-7][0-9])(\.[0-9]*)?)|(180))')
  and RegEx.matches(toLat,'-?((([0-9]|[1-8][0-9])(\.[0-9]*)?)|(90))')
  and RegEx.matches(toLon,'-?((([0-9]|[1-9][0-9]|1[0-7][0-9])(\.[0-9]*)?)|(180))');
	
// Check intermediate result
numRoutes3 = select count(*) from troute2;
Print "Number of routes without duplicates and with valid coords: " + val(numRoutes3);

che ci restituisce:

Number of routes without duplicates and with valid coords: 35475

Un altro aspetto degno di nota è l’utilizzo della parola chiave except nella select della tabella “troute”. Si tratta di un’estensione solitamente assente nei vari linguaggi SQL che ci consente di selezionare tutti i campi di una particolare tabella ad eccezione di un campo.
Infine, selezioniamo i dati da cui poter derivare le geometrie delle rotte aeree e rappresentarle graficamente (da qui in poi, il codice è quello del Dr JTS con qualche piccolo adattamento):

// Convert coords from string to double
trte = select fromCity, toCity,
  Val.toDouble(fromLon) fromLon, Val.toDouble(fromLat) fromLat,
  Val.toDouble(toLon) toLon, Val.toDouble(toLat) toLat
  from troute2;
	
// Split geodetic arcs and calculate lengths
tlines = select fromCity, toCity, line, len
  with {
    line = Geodetic.split180(Geodetic.arc(fromLon, fromLat, toLon, toLat, 2));
    len = Geom.length(line);
  }
  from trte order by len desc;
	
// Interpolate line color and fix line width
tplot = select line,
  Color.interpolate("ffffff", "00aacc", "0000ff", len / 50.0 ) lineColor,
  0.2 lineWidth
  from tlines;
	
// Import shapefile data
ShapefileReader tworld file: "TM_WORLD_BORDERS_SIMPL-0.3.shp";
	
// Select geometries and define line and fill colors
tworldLine = select GEOMETRY, "222222" lineColor from tworld;
tworldFill = select GEOMETRY, "333333" fillColor from tworld;
	
// Plot routes with world landmasses
width = 1800;
Plot width: width height: width / 2
  extent: LINESTRING(-180 -90, 180 90)
  data: tworldFill
  data: tplot
  data: tworldLine
  file: "routes.png";
	
// Plot routes without world landmasses
Plot width: width height: width / 2
  extent: LINESTRING(-180 -90, 180 90)
  data: tplot
  file: "routes_only.png";

Qui è possibile effettuare il download dell’intero script. Infine, si mostrano le due immagini risultanti in cui sono rappresentate le rotte aeree rispettivamente con e senza i world borders. In particolare, le rotte sono disegnate in ordine di lunghezza decrescente, utilizzando un colore interpolato in base alla lunghezza, per cui spiccano le rotte più brevi con colore più chiaro. Anche nella seconda immagine, è possibile rilevare con buona approssimazione i limiti di molte terre emerse.

Come giustamente afferma Martin Davis, dalla densità delle rotte aeree che si percepisce nelle immagini si evince come agli europei piaccia molto volare. Ma neanche quelli delle East Coast scherzano! ;-)

Conclusioni

L’esempio applicativo appena mostrato esprime già molte delle potenzialità offerte da JEQL, e i comandi attualmente disponibili sono molto numerosi (basta digitare jeql -man per scoprirlo!). JEQL offre inoltre anche la possibilità di estendere le sue funzionalità tramite un’interfaccia di programmazione (API), non ancora documentata, tramite la quale creare nuovi comandi e funzioni da poter utilizzare all’interno dei nostri script. Non nascondiamo la speranza, in parte malcelata dallo stesso Martin Davis, che un domani si possa usufruire di una doppia licenza open source/commerciale, che permetta di contribuire alla crescita della libreria con nuovi plugin e una migliore documentazione di tutte le caratteristiche offerte.

Ringraziamenti

Desidero ringraziare Giovanni Allegri, non solo per il proficuo scambio di idee avvenuto dietro le quinte, ma anche per aver sollecitato il rilascio della nuova release (0.9) di JEQL, senza la quale non sarebbe stato possibile riprodurre l’applicazione, e naturalmente Martin Davis, il padre di questo formidabile linguaggio, per aver ispirato questo post.

14 gennaio, 2011 | di

All’uscita del primo bell’episodio di Geospatial Revolution Project qualcosa mi aveva lasciato perplesso, ma non capivo cosa. Dopo qualche ora e qualche email (un ringraziamento particolare a Sergio Calabrese) ho realizzato che gli “mancava la parola”. Un prodotto di divulgazione così ben fatto, che merita la diffusione nelle scuole, sarebbe stato ancora più efficace se corredato dai sottotitoli in lingua originale. Nei giorni successivi molti utenti hanno scritto alla Pennsylvania State University per sollecitare la pubblicazione dei sottotitoli, ed dopo poche settimane erano presenti sul canale ufficiale di YouTube. Ma l’appetito viene mangiando.

La presenza dei sottotitoli infatti ci ha fatto venire subito la voglia di tradurli in italiano. Abbiamo scritto ai responsabili del progetto per chiedere “ufficialmente” di farlo e dopo qualche ora abbiamo ricevuto un’email dai toni molto gentili e con in allegato il file .xml con i sottotitoli in inglese. Lo abbiamo tradotto ed oggi finalmente è possibile “leggerlo” in italiano (anche qui sotto).


Un’ultima annotazione  forse un po’ autocelebrativa (mi scuso): fa un certo effetto essere in questo elenco, che inizia con la “A” di ASPRS Foundation e finisce con la “W” di Where 2.0.

9 gennaio, 2011 | di

Python (http://python.org) è un linguaggio di programmazione di alto livello, adatto ai più svariati obiettivi di programmazione. Viene usato per applicazioni web e desktop, giochi, programmazione scientifica, utility e anche per porzioni di sistemi operativi.
Anche chi ha la necessità di sviluppare delle applicazioni in grado di leggere, scrivere, analizzare ed elaborare dati ed informazioni spaziali, troverà in Python un compagno di viaggio piacevole, eclettico e ricco di pregi. Chi lavora in questo contesto e segue il mondo della programmazione, sa che si tratta di un linguaggio che sta diventando tra i più diffusi, sia nel mondo proprietario che in quello open-source, con a disposizione numerose librerie ad hoc.
Anche per questo, penso sia arrivato il momento (anzi mi sento in grande ritardo) di scrivere un post che fornisca gli strumenti per iniziare a “sporcarsi le mani”.
In linea teorica è possibile scrivere da zero codice Python che consenta di manipolare dati spaziali. Per fortuna esiste – tra le tante librerie disponibili –  il binding Python di GDAL/OGR; per iniziare è molto più comodo appoggiarsi sulle spalle di questo gigante.
Due annotazioni prima di passare agli aspetti pratici:

  • questo post consentirà di configurare Python e GDAL/OGR in ambiente Windows. Confido in qualche collega della redazione per scrivere le istruzioni utili per altri sistemi operativi
  • verrà descritta una delle tante modalità possibili per configurare l’ambiente

Procedura

Installare GDAL per Python su Windows è un processo semplice, che può essere portato fino in fondo, seguendo la seguente procedura:

  • Scaricare l’installer di Python dal sito ufficiale – http://www.python.org/download/ – ed installarlo. E’ possibile scaricare diverse release; noi abbiamo effettuato i nostri test con gli installer della 2.6.x
  • Installare GDAL/OGR per Windows
    • Scaricarlo da http://download.osgeo.org/gdal/win32/. Abbiamo utilizzato il file “gdalwin32exe160.zip” che si trova nella cartella “1.6”.
    • Decomprimere questo file in una cartella del vostro PC. L’abbiamo estratta in C:\ ed abbiamo quindi creato la cartella C:\gdalwin32-1.6.
    • Aggiungere la cartella di GDAL che contiene gli eseguibili (“C:\gdalwin32-1.6\bin” nel nostro caso) alla variabile di ambiente  “Path”.
      • Aprire il “Pannello di controllo” di Windows
      • Fare click su Sistema (se usate la visualizzazione per categorie, “Prestazioni e manutenzione” e poi “Sistema”).
      • Fare click su Avanzate
      • Fare click su “Variabili d’ambiente”.
      • Cercare la voce “Path” tra le “Variabili di sistema” e cliccare su Modifica.
      • Fare click sulla cella “Valore variabile”, andare in fondo alla riga, aggiungere un “;” ed inserire il percorso completo della cartella “bin” della vostra installazione di GDAL (C:\gdalwin32-1.6\bin nel nostro caso).
      • Fare Click su OK.
        gdal-bin Windows Path
    • Aggiungere “GDAL_DATA” come nuova variabile d’ambiente.
      • Fare click su “Nuovo” nella finestra “Variabili d’ambiente”.
      • Inserire “GDAL_DATA” nel campo “Nome variabile”.
      • Inserire il percorso completo della cartella data di GDAL nel campo “Valore variabile” (nel nostro caso “C:\gdalwin32-1.6\data”).
      • Fare click su “OK”. Aggiungeremo più avanti altre variabili d’ambiente, quindi potete tenere aperta questa finestra di dialogo.
  • Installare PROJ.4 per Windows. E’ un pacchetto necessario per potere gestire le proiezioni ed i sistemi di coordinate.
    • Scaricare PROJ.4 da http://download.osgeo.org/proj/. Il file binario per Windows – proj446_win32_bin.zip – non è aggiornatissimo, ma non è un problema.
    • Decomprimere questo file in una cartella del vostro PC, ad esempio in “C:\proj”.
    • Aggiungere la cartella “bin” di PROJ.4 (“C:\proj\bin” nel nostro caso) alla variabile di ambiente “Path”. Per farlo dovete seguire gli stessi passi visti sopra per la cartella “bin” di GDAL, ed aggiungere stavolta “C:\proj\bin”.
    • Aggiungere “PROJ_LIB” come nuova variabile d’ambiente. Dovete seguire le stesse istruzioni usate per la variabile “GDAL_DATA”, ma il nome della variabile è stavolta “PROJ_LIB”, ed il valore è il percorso completo della cartella “nad” contenuta in  PROJ.4 (C:\proj\nad nel nostro caso).
    • Copiare il file “proj.dll” dalla cartella “bin” di PROJ.4 alla cartella bin di GDAL. Nel nostro caso da “C:\proj\bin\” a “C:\gdalwin32-1.6\bin\”.
  • Installare il binding per Python di GDAL
    • Scaricare la versione appropriata alla vostra release di Python da http://pypi.python.org/simple/GDAL/.  Il file più aggiornato, compatibile con la versione 2.6.X di Python, è “GDAL-1.6.1.win32-py2.6.exe”.
    • Fare doppio click sul file, e completare la procedura di installazione
  • Riavviare il sistema.

Al riavvio avrete a disposizione un sistema in cui sarà possibile scrivere codice SPAZIALE (nel senso di bel codice ;-)  ).

Ciao mondo

Il codice sottostante lo potrete usare come test “Ciao Mondo”, e verificare la procedura seguita.

# importazione dei moduli
import sys
try:
  from osgeo import ogr
except:
  import ogr
	
# apertura di uno shapefile in lettura
driver = ogr.GetDriverByName('ESRI Shapefile')
fn = 'C:/nomefile.shp'
dataSource = driver.Open(fn, 0)
	
# verifica dell'esistenza del file
if dataSource is None:
  print 'Il file ' + fn + ' non esiste'
  sys.exit(1)
	
# accesso al layer
layer = dataSource.GetLayer()
	
# conteggio delle feature
numFeatures = layer.GetFeatureCount()
print 'Numero di feature: ' + str(numFeatures)
	
# estensione del layer
extent = layer.GetExtent()
print 'Estensione:', extent
print 'Coordinate vertice in alto a sinistra:', extent[0], extent[3]
print 'Coordinate vertice in basso a destra:', extent[1], extent[2]

L’output sarà qualcosa di simile a quanto riportato sotto:

Numero di feature: 33
Estensione: (280151.67957063887, 294843.14350770513, 4210159.3865045626, 4220843.5284850718)
Coordinate vertice in alto a sinistra: 280151.679571 4220843.52849
Coordinate vertice in basso a destra: 294843.143508 4210159.3865

Buone letture

La procedura descritta in questo post è quasi una traduzione dell’eccellente documento scritto da Chris Garrard: “Installing GDAL manually”. Il dott. Garrard cura un corso denominato “Geoprocessing with Python using Open Source GIS“, di cui trovate online il materiale didattico (slide, esercizi e codice); è stato per me illuminante per fare i primi passi e consiglio a tutti i novizi di leggerlo: ASSOLUTAMENTE DA NON PERDERE (si, sto urlando).
Per chi non ha mai scritto codice Python, e non ne ha alcuna conoscenza, la pietra miliare è (per me) “Pensare da informatico“.

Buoni propositi

Il desiderio mio (e credo dei colleghi della redazione) è quello di non lasciare questo post da solo. Nel 2011 vorrei mettergli accanto dei fratellini; non saranno magari dei ricchi tutorial, ma la coppia GIS & Python sarà uno dei temi che terremo sotto osservazione e di cui daremo nota nel blog e/o soltanto nei canali Twitter e Facebook.

Buona scrittura :-D


In questi giorni il tema generale dell’installazione delle librerie GDAL su Windows è caldissimo. Sono in preparazione nuovi installer, e probabilmente nei prossimi mesi aggiorneremo questo post con una procedura più semplice e diretta.


TANTO non rappresenta una testata giornalistica ai sensi della legge n. 62 del 7.03.2001, in quanto non viene aggiornato con una precisa e determinata periodicita'. Pertanto, in alcun modo puo' considerarsi un prodotto editoriale.