da PostGIS a Spatialite

Avevo necessità di esportare un DB PostGIS (PostgreSQL con estensione spaziale) in spatialite.

Cercando in rete ho trovato questa pagina: le librerie GDAL/OGR sono in grado di fare la conversione richiesta. In particolare il terzo esempio riportato alla pagina indicata fa proprio al caso nostro.

$ ogr2ogr –config PG_LIST_ALL_TABLES YES –config PG_SKIP_VIEWS NO -f “SQLite” nome_db.sqlite -progress PG:”dbname=’nome_db_postgis’ active_schema=public schemas=public host=’nome_host’ port=’5432′ user=’nome_utente’ password=’pwd_segreta’ ” -lco LAUNDER=yes -dsco SPATIALITE=yes -lco SPATIAL_INDEX=no

Ma provando a caricare il DB in QGIS si ottiene un errore:

“nome del layer” (GEOMETRY non è un layer valido e non può essere caricato)

Ho chiesto il lista gfoss.it e il papà di spatialite, Alessandro Furieri, mi ha gentilmente controllato l’output di ogr2ogr. La sua illuminante risposta e conclusione è riportata qui. Ma provo a riassumere i passaggi che, con le sue indicazioni, ho seguito per ripulire le sporcizie che erano rimaste.

Il database che viene creato presenta alcune incongruenze (alcune dovute ad errori preesistenti del DB Postgis come il settaggio dello SRID che non deve essere uguale a -1 ma deve essere esplicitamente dichiarato). Poi errori di interpretazione delle colonne geometriche nel passaggio da postgis a spatialite.

In sostanza, una volta creato il DB spatialite ho seguito questi passaggi (indicati da Sandro):

$ spatialite nome_db.sqlite

– si presenta il prompt di spatialite: a questo punto impostare alcune semplici configurazioni per l’output dei comandi:

spatialite> .nullvalue NULL

spatialite> .headers on

spatialite> .mode column

In questo modo otteniamo che vengano visualizzati come NULL in valori senza valore (bel gioco di parole :-)), che si vedano gli headers delle tabelle quando si lanciano query di select e che i valori vengano visualizzati secondo una impostazione tabellare.

A questo punto bisogna forzare lo SRID (nel nostro caso si tratta del codice EPSG=3003, Gauss Boaga Fuso Ovest) nella tabella geometry_columns:

spatialite> update geometry_columns SET srid = 3003;

Poi sistemiamo il type geometrico aggiornando alcuni valori sghembi che erano rimasti; in particolare si tratta di alcune tabelle con dati poligonali in cui il tipo geometrico era rimasto con valore GEOMETRY.

spatialite> update geometry_columns SET type=’POLYGON’ WHERE type = ‘GEOMETRY’;

– Infine aggiorniamo correttamente lo SRID su tutte le geometrie creando i trigger necessari al buon funzionamento di spatialite.

spatialite> UPDATE acqua SET GEOMETRY = SetSrid(GEOMETRY, 3003);

Questo va fatto tabella per tabella (nel caso riportato la tabella “acqua”).

A questo punto il caricamento con QGIS va liscio!

PostreSQL | trigger

Un trigger definisce una funzione che agisce prima o dopo un’altra azione su una tabella.

In sostanza un trigger richiama una determinata funzione (che deve essere creata a priori) che esegue operazioni sui valori di una tabella.

Nel caso particolare di questo esempio disponiamo di una tabella chiamata “valori” che contiene 5 colonne:

valore1, valore2, valore3, valore4 e somma (tutti di tipo integer).

I valori delle prime 4 colonne vengono inserite dall’utente; vogliamo fare in modo che la quinta colonna (somma) venga popolata dalla funzione richiamata dal trigger una volta che i primi 4 valori sono inseriti. Procediamo:

– definiamo la funzione:

nome_db=> CREATE OR REPLACE FUNCTION somma_valori() RETURNS trigger AS $somma_valori$ DECLARE new_somma integer;
BEGIN IF (TG_OP=’INSERT’) THEN UPDATE valori SET somma=valore1+valore2+valore3+valore4; END IF; RETURN NEW; END; $somma_valori$ language plpgsql;

– definiamo ora il trigger che richiama la funzione ad ogni INSERT che avviene nella tabella;

nome_db=> CREATE TRIGGER tr_somma_valori AFTER INSERT ON valori FOR EACH ROW EXECUTE PROCEDURE somma_valori();

In questo modo ogni volta che vengono inseriti i primi 4 valori vedremo popolarsi automagicamente anche il quinto.

libreoffice | installazione su debian

Oggi ho provato ad installare LibreOffice. La suite per ufficio nata dopo che Oracle è entrata in possesso di OpenOffice.

Il progetto fa capo alla “The Document Foundation“. Per farla con un’equazione si potrebbe dire che:

The Document Foundation : LibreOffice = Mozilla Foundation : Firefox (citando la pagina delle FAQ che spiega molto bene questi termini)

Ad oggi sono disponibili per il download vari formati (tutti alla versione Beta del programma):

– Windows;

– Linux 32 bit;

– Linux 64 bit;

– Mac OS X;

– sorgenti.

Ho provato a scaricare la versione per Linux a 32 bit per installarla su Debian testing. I file scaricati sono .rpm (quindi non ci sono pacchettizzati per Debian) ma seguendo questa semplice ed efficace guida si arriva a destinazione. Riassumendo ecco i passi da seguire:

– installare alien per convertire i pacchetti .rpm in .deb:

# apt-get install alien

– scaricare e decomprimere i pacchetti dal sito:

– viene creata una directory “en-US”; spostiamoci in questa cartella.

$ cd en-US

– entriamo nella directory chiamata RPMS:

$ cd RPMS

– convertire gli RPM in DEB mediante alien:

# alien -k *.rpm

vengono convertiti, uno alla volta, tutti i pacchetti con generazione dei relativi .deb.

– installare i pacchetti .deb generati mediante dpkg:

# dpkg -i *.deb

– a questo punto spostarsi nella direcotory chiamata “desktop-integration”  (che si trova in RPMS) e convertire il pacchetto “libreoffice3.3-freedesktop-menus-3.3-1.noarch.rpm”:

# alien -k libreoffice3.3-freedesktop-menus-3.3-1.noarch.rpm

– otteniamo il pacchetto “libreoffice3.3-freedesktop-menus_3.3-1_all.deb” che andremo a installare:

# dpkg -i libreoffice3.3-freedesktop-menus_3.3-1_all.deb

That’s all :-). Il programma si puo’ lanciare da riga di comando:

$ libreoffice [invio]

Oppure lo troviamo tra le applicazioni per ufficio ben visibile accanto (a chi ce l’ha ancora) a openoffice. Il logo è leggermente diverso.

Ed eccolo in tutto il suo splendore 🙂

la finestra di start di LibreOffice

Postgresql | replace

Ho importato un file CSV in Postgresql in cui i testi erano racchiusi tra doppio apice (“).

Il risultato si traduce in campi (quelli testuali) tutti belli incapsulati in doppie apici che, a dirla tutta, non sono il massimo…soprattuto se si devono fare SELECT o UPDATE via psql (client a riga di comando comodissimo e potente). Ho tentato allora di approfondire cercando una soluzione (in Postgresql) che permettesse di fare un bel FIND AND REPLACE (come siamo soliti fare con openoffice/libreoffice e/o qualsiasi altro editor di testo).

Alla fine ho scovato la funzione REPLACE di Postgresql che ha la seguente sintassi:

replace(string text, from text,to text)

che riportata in concreto diventa:

nome_db =# UPDATE nome_tabella SET nome_campo=replace(nome_campo, ‘valore_vecchio’,’valore_nuovo’);

Vediamo nel caso pratico del mio db. Si tratta di una tabella contente dati relativi a ditte. Facendo una SELECT sul campo “denominazione” prima della modifica con REPLACE si otteneva:

nome_db =# SELECT denominazione FROM ditte WHERE numero=2;

denominazione
—————–
“NOME DITTA A CASO s.n.c.”
(1 riga)

Aggiorniamo il campo denominazione togliendo i doppi apici:

nome_db =# UPDATE ditte SET denominazione=replace(denominazione,'”‘,”);

e alla fine la query di SELECT precedente torna il valore “pulito”:

nome_db =# SELECT denominazione FROM ditte WHERE numero=2;

denominazione
—————–
NOME DITTA A CASO s.n.c.
(1 riga)

Altro esempio: supponiamo di avere un campo che memorizza il percorso di salvataggio di una immagine. Il campo si chiama “foto” e dobiamo aggiornare l’indirizzo IP del server sul quale risiedono le immagini: si passa da server con IP “100.0.4.231” a IP”192.168.4.50″.
Se interroghiamo il DB prima dell’aggiornamento otteniamo:

nome_db =# SELECT foto FROM ditte WHERE numero=2;

foto
—————–
http://100.0.4.231/percorso_al_file_immagine/002.jpg
(1 riga)

Modifichiamo allora solo la parte di campo relativa all’indirizzo IP:

nome_db =# UPDATE ditte SET foto=replace(foto,’100.0.4.231,’192.168.4.50′) WHERE numero=;

UPDATE 1

ed il risultato della SELECT sarà:

nome_db =# SELECT foto FROM ditte WHERE numero=2;

foto
—————–
http://192.168.4.50/percorso_al_file_immagine/002.jpg
(1 riga)

django | modificare le tabelle

Una volta creato il progetto e l’applicazione con django succede di dover apportare delle modifiche alla struttura del database (per esempio aggiunta di campi alle tabelle,..).

Per farlo sono necessari 4 passi:

– eseguire un backup del db con:

$ python manage.py dumpdata manager > db.json

dove manager è il nome dell’applicazione (db) e db.json è un backup di tutto il db (JSON sta per JavaScript Object Annotation: si tratta di un formato di interscambio per dati)

– si apportano le modifiche alla tabella (model); ad esempio inserendo un nuovo campo agendo sul file models.py

– si resetta il database: in questo modo vengono ricreate le tabelle con il nuovo modello (rispondere “yes” alla domanda di conferma di reset):

$ python manage.py reset manager

– ri ricaricano i dati prelevandoli dal backup fatto in precedenza:

$ python manage.py loaddata db.json

Fatto!

django! si, django!

In questo post tento di riassumere (nella maniera piu’ semplice possibile) i passi che ho seguito per creare il primo progetto con django. Da non sviluppatore e abbastanza ignorante nel campo dei linguaggi di programmazione se dovessi definire django con un aggettivo direi: disarmante!

Si ispira al principio DRY (Don’t Repeat Yourself) e la migliore definizione di django che ho trovato è quella fornita da Marco Beri nel suo ottimo libro “Sviluppare applicazioni web con django”: “Django è un ottimo tavolo da lavoro, con tanto di strumenti, per costruire siti dinamici e applicazioni web“. E io aggiungo: le “gambe” del tavolo sono costituite da Python!

Utilizzando Debian troviamo django già pacchettizzato. Purtroppo la versione disponibile non è la piu’ recente; ma basta scaricare i sorgenti dal sito http://www.djangoproject.com/download/ e seguire i 3 (anzi 4) semplici passi indicati:

– si scarica;

– si decomprime il tar.gz;

– ci si sposta nella directory ottenuta dalla decompressione;

– si “suda” per installare il pacchetto: fatto!

E qui comincia il bello. Andiamo per fasi (step):

– si crea una directory di lavoro (la possiamo creare nella nostra home; poi vedremo come fare per renderla visibile al server web).

$ mkdir django_work

– ci spostiamo nella directory creata:

$ cd django_work

– richiamiamo il modulo per la creazione del “progetto” (con django si crea prima un “progetto” e poi “n” applicazioni. C’è molta documentazione in rete che riguarda la strutturazione del framewok):

$ django-admin startproject energia

Questo comando genera nella directory corrente una sottodirectory che ha il nome del progetto indicato (nel nostro caso “energia”) che contiene alcuni file: __init__.py, manage.py, settings.py, e urls.py

NB: con l’installazione di django è stato installato anche un server web (diciamo “provvisorio”) utilissimo per fare i test durante la creazione e implementazione del progetto. Questo server si avvia mediante il comando:

$ python manage.py runserver

Se tutto è ok compare un messaggio simile a questo:

Validating models…

0 errors found….. ecc

Quit the server with CTRL-C.

– Modificare il file settings.py e indicare i parametri alla voce “DATABASES“:

‘ENGINE’:  ‘postgresql_psycopg2″ (se si usa database Posgresql)

‘NAME’:  ‘energia’ (il db si puo’ creare dopo; l’importante è dare questo nome :-))

‘USER’:  ‘sit’ (il proprietario del db creato)

‘HOST’: ‘localhost’

‘PORT’: ” (lasciare in bianco per assumere la porta configurata di default)

– Creare il nuovo database (con lo stesso nome indicato del file “settings.py“). PS: in questo post si assume di lavorare con DB Postgresql; per altre configurazioni (sqlite, mysql,…) vedere la ricca documentazione che si puo’ trovare in rete.

$ su

# su postgres

# psql

# CREATE DATABASE energia OWNER sit;

– lanciare il webserver (quello ausiliario fornito da django con il solo scopo di testare lo sviluppo dell’applicazione) posizionandosi all’interno della directory di lavoro.

$ ./manage.py runserver oppure

$ python manage.py runserver

Deve comparire un messaggio di “0 errors“.

– Puntare il browser alla pagina http://localhost:8000/

dovremmo ottenere una pagina con scritto “IT WORKED…..”

– Creare l’applicazione che chiameremo “manager“:

$ ./manager.py startapp manager

In questo modo viene creata la directory “manager”.

– Definire le tabelle del DB mediante il file “models.py“: le tabelle sono definite come classi python (vedi il tutorial on line)

– L’applicazione nuova chiamata “manager” deve essere attivata modificando il file “…../django_work/energia/settings.py” ed inserendo la voce ‘energia.manager’ nella sezione “INSTALLED_APPS

– Per applicare il modello appena definito cioé costruire la struttura del database lanciare il comando:

$ ./manage.py syncdb

Compare una sequenza di messaggi che indicano l’avvenuta creazione di alcune tabelle (comprese quelle di autenticazione) in quanto previste tra le “INSTALLED_APPS” del file “settings.py” (‘django.contrib.auth‘). Installando l’auth system viene chiesto se si vuole creare un superuser. Rispondere “yes“: viene proposto l’utente attivo. Dare” yes” e immettere un indirizzo e-mail e una password (l’email non è indispensabile).

– A questo punto si puo’ procedere al popolamento della/e tabella/e del db. Il tutorial propone di usare la shell di django ma si puo’ fare benissimo con vari client (io ho usato phppgadmin per Postgresql).

– Creazione delle “view“: si tratta delle viste ossia come devono essere presentati i dati. Prima di farlo definiamo gli URl delle varie pagine editando il file “…/django_work/energia/urls.py“.

Questi pattern associano le espressioni regolari ad un modulo python.

Le view vengono definite nel file “…/django_work/energia/manager/views.py” (sono tipiche dell'”applicazione”). Nelle view definite si fa riferimento a determinati template (file HTML).

– Definire la variabile ‘TEMPLATES_DIRS‘ all’interno del file “settings.py

Esempio: ABSOLUTE_PATH + ‘/home/sit/django_work/energia/manager/templates’

– Creare una directory “templates” all’interno di “manager” e procedere alla creazione dei template (base.html, index.html,…). Per una descrizione più dettagliata sui template si rimanda al tutorial on-line.

Supposto che tutto sia ok si puo’ passare alla pubblicazione vera e propria del nostro lavoro. Ricordiamoci che fino ad ora abbiamo lavorato “in casa” usando il server web ausiliario gentilmente offerto da django. Ma se dobbiamo “uscire” nel mondo dobbiamo usare un “vero” server web. Qui facciamo riferimento ad Apache.

– Nel file “settings.py” nella sezione “DATABASES” verificare che la voce ‘HOST‘ sia impostata a ‘localhost’.

– Modificare il file di configurazione di Apache che si trova in (debian :-)) “/etc/apache2/apache2.conf” aggiungendo:

<Location “/energia/”>

SetHandler python-program

PythonHandler django.core.handlers.modpython

SetEnv DJANGO_SETTINGS_MODULE energia.settings

PythonPath “[‘/home/sit/django_wotk/’,’/home/sit/django_work/energia/’] + sys.path”

PythonOption django.root /energia

PythonDebug On

</Location>

<Location “/media”>

SetHandler None

</Location>

Alias /media /home/sit/src/Django-1.2.1/django/contrib/main/admin/media

Quest’ultimo alias è necessario per caricare i file CSS, JS (modificare i template HTML inserendo “/energia/” a monte di ogni HREF).

NB: ricordarsi di riavviare il server web dopo ogni modifica:

# /etc/init.d/apache2 restart

Spero sia tutto corretto. Commenti benvenuti.

18-19 (20) novembre 2010, GFOSS DAY a Foligno

L’associazione Italiana per l’Informazione Geografica Libera GFOSS.IT (Geospatial Free and Open Source Software) organizza, per i giorni 18 e 19 novembre 2010, a Foligno, la 3a conferenza italiana sul software geografico libero, per fare il punto sullo stato dell’arte del software geografico libero ed Open Source in Italia, ponendo particolare attenzione alle applicazioni nel campo delle pubbliche amministrazioni e delle aziende.

L’associazione GFOSS.IT (http://www.gfoss.it), costituita nel febbraio 2007 da docenti universitari, ricercatori e professionisti provenienti da diverse regioni italiane, ha, tra gli altri, gli obiettivi di:
– favorire lo sviluppo, la diffusione e la tutela del software esclusivamente libero ed open source per l’informazione geografica;
– promuovere gli standard aperti per l’informazione geografica e il libero accesso ai dati geografici.
Il Gfoss Day, tenutosi in precedenza nelle città di Pontedera e Bolzano (http://www.gfoss.it/drupal/convegno e http://www.gfoss.it/drupal/gfossday ), rappresenta uno dei momenti in cui l’associazione GFOSS.IT riunisce soci, aziende, professionisti e pubbliche amministrazioni attive nell’applicazione, sviluppo, promozione e diffusione di software libero geografico.

L’evento sarà aperto e gratuito per tutti i partecipanti. La prima giornata sarà dedicata a momenti formativi durante i quali esperti di fama nazionale ed internazionale terranno corsi mirati su Software GIS (Geographic Information System) e/o WebGIS.

La seconda giornata della conferenza sarà orientata a discutere aspetti tecnologici e legali relativi alla circolazione dei dati geografici. Sono previsti interventi orientati a fare il punto sul processo di adeguamento delle PA italiane alla direttiva Europea INSPIRE (http://inspire.jrc.ec.europa.eu/ – anche alla luce del decreto legislativo 27 gennaio 2010 , n. 32) e sulla promozione di servizi di distribuzione di dati in rete secondo standard condivisi ed internazionali – OGC e ISO (Web Services).

Per questo saranno ospitati interventi di pubbliche amministrazioni che illustreranno i loro progetti ed il loro stato di avanzamento.

Il terzo giorno sara’ dedicato ad una attivita’ di mappatura della citta’ di Foligno (mapping party) coinvolgendo i ragazzi di alcune scuole. I dati raccolti mediante ricevitori GPS saranno poi riversati nel database libero mondiale di OpenStreetMap.

Maggiori informazioni: http://www.gfoss.it/drupal/gfossday2010

DVD-Slideshow | free sliding :-)

Cercavo un sistema (naturalemente “libero”) per creare uno slideshow di una serie di foto. Sarebbe bello si potessero anche inserire dei testi e degli effetti di transizione “morbidi” e magari carini.

Ho trovato DVD-Slideshow. Bello davvero! In Debian si installa con:

# apt-get install dvd-slideshow (sono necessari anche “sox”, “mjpegtools”, “imagemagick” e “ffmpeg”).

Si tratta di un programma a riga di comando. Si, non ha interfaccia grafica ma passando una mezzoretta sul wiki indicato sopra si imparano i pochi comandi base; poi per affinare c’e’ tempo…e comunque il risultato e’ davvero interessante.

Prepariamo l’area di lavoro creando una directory contenente le immagini da processare:

$ mkdir foto

e una directory che conterrà il filmato finale (e’ solo una mia comodità; si puo’ lasciare anche tutto nella stessa dir):

$ mkdir foto/slide

Ci sono 5 moduli dei quali due sono i principali dvd-slideshow e dir2slideshow.

Partiamo da “dir2slideshow” che ha il compito di scansionare una intera directory di foto e creare un file TXT contenente le istruzioni da dare in pasto a dvd-slideshow per creare il video finale.

$ dir2slideshow -n ‘nome_file’ -t 6 -c 1 /percorso/alla/dir/da/processare/

Le opzioni:

-n -> indica il nome del file TXT da generare;

-t -> indica la durata (in secondi) di permanenza di ogni fotogramma;

-c -> indica la durata del “crossfade” (passaggio sfumato) tra una foto e l’altra.

Tutti questi parametri possono essere modificati in un secondo momento editando il file TXT generato.

Una volta creato il file con le struzioni possiamo lanciare il secondo modulo che produrrà il video vero e proprio:

$ dvd-slideshow -n ‘nome_file_video’ -o /directory/di/output/del/video -a /percorso/al/file/musicale/nome_sound.mp3 -f /percorso/al/file/di/istruzioni/nome_file.txt

Le opzioni:

-n -> nome del file finale (video);

-0 -> percorso alla directory che conterrà il video finale;

-a -> file mp3 da inserire come “sfondo musicale”;

-f -> file TXT generato dal modulo dir2slideshow in precedenza.

Alcune note: il file di testo che contiene le istruzioni può essere modificato e personalizzato molto in dettaglio. Si possono inserire titolo iniziale e sottotitoli di ogni immagine. Tuttavia i sottotitoli vengono generati ma non visualizzati. Come suggerito dalle FAQ e’ necessario inserire nel file TXT la seguente istruzione per consentirne la visualizzazione:

subtitle_type=”render”

Consiglio anche la lettura di questo post molto ben fatto!

Se alla fine vogiamo creare un DVD a tutti gli effetti con tanto di menu’ per la navigazione dei “capitoli” ci viene in aiuto il modulo dvd-menu.

Nel nostro caso la sintassi e’ la seguente:

$ dvd-menu -t “primo capitolo” -f nome_file_config.xml -n ‘titolo_principale’ -b /percorso/alla/img/di/sfondo.JPG

Le opzioni:

-t -> titolo dei capitolo che verra’ creato nel menu’ a sinistra;

-f -> percorso al file di configurazione XML creato da dvd-slideshow;

-n -> titolo del DVD visualizzato in alto;

-b -> percorso al file immagine da usare come sfondo

In questo modo viene creata una directory chiama dvd_fs contentente i files pronti per la creazione del DVD. Per creare l’immagine ISO da masterizzare usiamo il programma mkisofs:

$ mkisofs -dvd-video -udf -o dvd.iso dvd_fs

L’immagine chiamata dvd.iso e’ pronta per la masterizzazione (con k3b o altro software).

il primo “Hello world” in C

Non sono un programmatore; non conosco nessun linguaggio di programmazione. Per questo, approfittando di una piccola necessita’ lavorativa, mi sono avvicinato al C.

Bazzicando in rete ho trovato alcuni “punti di partenza” molto ben fatti:

introduzione alla programmazione in C;

piccolo corso di programmazione in C;

E da qui ne e’ uscito un piccolo programmino per convertire le coordinate geografiche (lat/long) da DMS (Gradi Primi Secondi) a DD (Gradi decimali).

L’ho scritto usato l’editor “nano” (semplice quanto efficace editor che offre colorazione del testo ben fatta).

Una volta scritto il testo sottostante salvarlo con il nome di “primo_test.c” (i codici sorgente in C vengono contraddistinti dal suffisso .c).

#include <stdio.h>
float a,b,c,d;
main()
{
printf(“inserisci i gradi:  \n”);
scanf(“%f”, &a);
printf(“inserisci i primi: \n”);
scanf(“%f”, &b);
printf(“inserisci i secondi: \n”);
scanf(“%f”, &c);
d=a+(((c/60)+b)/60);
printf(“l’angolo in formato decimale e’ %f \n”, d);
}

Una volta salvato il codice deve essere compilato. Per fare questo ho usato il compilatore “gcc” mediante la seguente sintassi:

$ gcc primo_test.c -o primo_test.out

Viene creato un file eseguibile chiamato primo_test.out (nel caso non avessimo indicato il nome del file di outptu, gcc avrebbe nominato il file “a.out”).

Il programma si lancia con il comando

$ ./primo_test.out

Vediamo il codice. All’inizio del testo viene indicata la libreria da caricare per eseguire le operazioni (#include <stdio.h>).

Poi si passa al processo. Stampa a console la richiesta di inserire i valore dei gradi dell’angolo da convertire; fatto questo cattura il valore inserito e lo memorizza nella prima variabile dichiarata (di tipo float). Poi chiede di inserire il valore del primi e memorizza il valore nella seconda variabile. Infine richiede i secondi e li memorizza nella terza variabile.

Fatto questo esegue l’operazione di conversione e propone in output il valore dell’angolo calcolato.