(C)2020 CC-BY-SA Enrico Ferreguti Luca Lanteri Rocco Pispico
In linguaggio SQL sono possibili parecchi tipi di Query:
query di creazione tabella:
query di inserimento dati:
query di cancellazione tabella:
query di aggiornamento:
ma quello che ci interessa oggi è la query di ricerca
I dialetti SQL sono molti e ci sono grandi differenze di dettaglio.
Ma la struttura della sintassi principale per l'estrazione dei dati
rimane praticamente la stessa per tutti i RDBMS.
Oggi lavoreremo con SQlite, nella sua versione con estensioni spaziali
Spatialite
il cui sviluppo è open source ed è curato da
Alessandro Furieri
Per facilitare e velocizzare il workshop le esercitazioni sono completamente basate su un una versione speciale di Spatialite compilata per l'utilizzo da browser. Il database è residente nella memoria del browser, ma è facilmente scaricabile per l'utilizzo con QGIS per chi lo desidera:veneto.sqlite
E' possibile una visualizzazione tabellare:
o una visualizzazione su mappa: Le tabelle contengono un campo *geom* con le informazioni spaziali memorizzate in latitudine e longitudine (ETRS89 epsg:4258) e visualizzabili
producendo una geometria geojson per mezzo della funzione AsGeoJSON()
Il formato geojson è un formato testuale facilmente interpretabile da javascript come un'oggetto (dati serializzati) contentente dati geografici e relativi attributi. Il formato è uno standard codificato di internet e costituisce una specie di lingua universale per l'interscambio di dati geografici nel web
Disponiamo delle seguenti tabelle, visualizzabili eseguendo le query:
L'elenco delle tabelle e dei relativi campi disponibili può essere visualizzato in ogni momento premendo il bottone "elenco tabelle"
E' buona prassi limitare il numero di record che una query può restituire, soprattutto in fase di sviluppo e test della query complesse, in modo da velocizzare i tempi di ricerca e non impattare sulle performance del database od ottenere risultati più significativi
Alias:
Query nidificate:
Accodamenti:
le condizioni in WHERE possono essere assemblate con AND, OR e negate con NOT attenzione alla precedenza degli operatori
le query nidificate possono essere utilizzate per ottenere un valore interrogando un'altra tabella
campi calcolati ed alias
ordinamento crescente
ordinamento decrescente
ordinamento alfabetico multiplo
La funzione fondamentale dei database relazionali è consentire l'aggregazione di dati tra due tabelle stabilendo una relazione tra campi
JOIN associa a tutte le righe di una tabella le righe di un'altra solo se soddisfano una condizione, altrimenti NULL
Un'altra caratteristica delle query SELECT è la capacità di creare delle tabelle di sintesi da altre più complesse
L'estensione spaziale di SQlite è Spatialite, e dispone di una serie molto completa di funzioni per la manipolazione di informazioni geografiche: Reference List ed è compatibile con lo standard OGC per le funzioni geospaziali nei database
Le funzioni basilari che utilizzeremo nel workshop sono le seguenti
I tipi geometrici possono essere i seguenti:
L'informazione spaziale è contenuta in almeno un campo geometrico. Nelle tabelle del workshop il campo geografico è per convenzione il campo "geom", ma nulla vieta che possa avere un altro nome.
Il formato di memorizzazione è binario, e quindi non visualizzabile "per gli umani" ma disponiamo di funzioni che permettono di trasformarlo in un formato più amichevole:
Il risultato della query può essere visualizzato in mappa quando la tabella di output contiene un campo "geojson" contente le geometrie da visualizzare in formato geojson:
Il formato geojson è l'espressione testuale di un'oggetto javascript prodotta secondo lo standard "json" ed è facilmente "digeribile" dalle applicazioni web
L'altra condizione perchè la geometria possa essere visualizzata correttamente nel visualizzatore è che il dato geografico deve essere espresso in gradi di latitudine e longitudine. Le tabelle predefinite sono nel formato ETRS89-epsg4258, sono quindi compatibili con il visualizzatore
L'unione di due tabelle è possibile quando una condizione di JOIN è soddisfatta. Se la condizione è basata su una relazione spaziale tra geometrie, si stabilisce un Join spaziale tra dati
Dall'unione delle tabelle potrebbe risultare dei risultati non univoci:
Sarà quindi opportuno raggruppare i risultati
E' da notare come in altri DBMS la calusola GROUP BY pretende che tutti i campi siano esplicitamente aggregati. SQlite implicitamente mette il primo risultato
Le funzioni spaziali possono essere usate per collezionare le geometrie aggregate da una query di raggruppamento
L'intersezione tra geometrie lineari genera geometrie puntuali:
E' possibile acquisire dati dimensionali delle geometrie inserite lunghezze, aree, distanze
Essendo le geometrie espresse in latitudine e longitudine, I dati geometrici sono espressi in gradi. E' quindi necessario trasformare le coordinate in un sistema di riferimento proiettato per ottenere le corrette dimensioni in metri
La funzione di buffer genera un poligono i cui vertici distano ad una distanza costante da una geometria generatrice
Individuazione di un buffer di 10 km dalla ferrovia
individuazione dei centri ricadenti nel buffer appena individuato
metodo alternativo meno performante ma che recupera i dati
NB: i dati geografici sono espressi in latitudine e longitudine quindi la distanza di buffer va espressa in gradi (0.01 gradi corrispondono circa a 950 m)
Individuazione dei comuni limitrofi
Usando st_intersects al posto di st_touches si include anche il comune stesso di Verona
Si può quindi raggruppare la tabella sommando la lunghezza di ogni arco
Nota bene: Questa query non funzionerebbe in postgis poichè nel caso di raggruppamento Postgresql richiede di specificare una funzione di aggregazione per ogni campo
Individuazione del fiume: Trattandosi di un grafo idrologico, il fiume è individuato da una serie di archi:
Metodo 1: quindi si può raggruppare sommando la lunghezza di ugni arco
Nota bene: Questa query non funzionerebbe in postgis poichè nel caso di raggruppamento Postgresql richiede di specificare una funzione di aggregazione per ogni campo
Metodo 1: con subquery
Metodo 2: con join
Nota bene: Questa query non funzionerebbe in postgis poichè nel caso di raggruppamento Postgresql richiede di specificare una funzione di aggregazione per ogni campo
/ − Incontri Estivi GFOSS 2020 − Introduzione ai database geospaziali