Operatori Spaziali

mercoledì 12 settembre 2012 alle 12:37 | Pubblicato su 11g, Oracle Locator, Oracle Spatial | Lascia un commento
Tag: , , ,

Facendo riferimento al paragrafo 5.2 del manuale “Oracle Spatial user’s guide and reference” versione 11.2, cerco di parlare un po’ degli operatori spaziali. Prima di tutto dico che gli operatori fanno ancora parte della componente Locator (Licensing Information) il che significa che il loro utilizzo è gia possibile con la Standard Edition senza sovrapprezzo.

Gli operatori spaziali sono delle particolari funzioni che si utilizzano nelle clausole WHERE degli statemente per filtrare i dati in base a logiche geometriche; il formato di questi operatori è generalmente questo:


<nome  operatore>(
geometria_tabella SDO_GEOMETRY,
geometria_riferimento SDO_GEOMETRY,
[,stringa_parametri IN VARCHAR2
[,tag IN NUMBER]]
)='TRUE'

Gli operatori funzionano solo su campi SDO_GEOMETRY gia indicizzati, in mancanza di un indice spaziale valido sul campo usato come primo argomento dell’operatore viene restituito un errore.

Il manuale spiega che le query spaziali vengono normalmente eseguite con una logica a due livelli, prima viene fatta una selezione approssimata e poi sul risultato di questa prima selezione viene fatta una selezione esatta. Cosa si intende con selezione approssimata lo si può capire andando a vedere il primo operatore spaziale: SDO_FILTER, questo operatore controlla non se due geometrie interagiscano ma se i loro MBR interagiscono. L’MBR, Minimum Bounding Rectangle di una geometria è il reattangolo più piccolo possibile che contiene la geometria. Per un punto l’MBR è il punto stesso, per un segmento è il segmento stesso, per poligoni più complessi è facile immaginare cosa sia l’MBR. Gli indici spaziali lavorano proprio su MBR e questo permette di fare una prima selezione in modo molto efficente. Riporto paro paro dal manuale un esempio di uso di questo operatore:


SELECT A.Feature_ID FROM TARGET A WHERE sdo_filter(A.shape, SDO_geometry(2003,NULL,NULL,
 SDO_elem_info_array(1,1003,3),
 SDO_ordinate_array(x1,y1, x2,y2))
 ) = 'TRUE';

Gli operatori spaziali vengono usati sempre così, dentro la clausola WHERE ponendo l’uguaglianza alla stringa ‘TRUE’. Quindi SDO_FILTER fa solo una selezione “primaria”, approssimata quindi nell’esempio vengono restituiti tutti i record per cui l’MBR del campo  SHAPE è adiacente o contenuto nel rettangolo i cui vertici estremi sono x1,y1,x2,y2.

Per interrogazioni esatte vi sono altri operatori, il primo citato nella documentazione è SDO_RELATE che serve a trovare geometrie che si “sovrappongono” in qualche maniera; il terzo parametro serve a specificare il tipo di sovrapposizione che si vuole ricercare, un esempio è ‘mask=anyinteract’ ma al posto di anyinteract (il cui significato mi sembra intuitivo) si può specificare contains, covers, inside, equal, ecc. per le combinazioni diverse da anyinteract il significato può essere poco intuitivo ma qui non voglio approfondire questo aspetto e mi limito a una veloce carrellata degli operatori, precisando che esistono per ciascuna delle possibilità degli operatori dedicati, ad esempio SDO_CONTAINS, SDO_ANYINTERACT, ecc.

Per trovare oggetti entro una certa distanza da un riferimento si può utilizzare l’operatore SDO_WITHIN_DISTANCE, specificando come stringa per il terzo parametro qualcosa come ‘distance=5’ dove l’unità di misura nel caso di sistema di riferimento geodetico dovrebbe essere sempre metri. Faccio notare che nella documentazione c’è qualcosa che non va, si dice che l’operatore non è efficente per fare join fra due tabelle, però l’esempio per una soluzione alternativa usa la funzione SDO_BUFFER senza speficare il package (SDO_GEOM) e usando la parola UNRECOVERABLE che stando alla documentazione è deprecata.

L’ultimo operatore di cui parlo è SDO_NN, NN sta per Nearest Neighbor, quindi questo operatore serve a trovare gli oggetti più vicini a un certo oggetto (quello specificato nel secondo argomento). Senza specificare nulla per il terzo parametro usando questo operatore si trovano tutti gli oggetti in ordine di distanza crescente, altrimenti specificando come terzo parametro ‘sdo_num_res=n’ dove n è un numero intero si trovano i primi n oggetti  più vicini (però non più in ordine di distanza crescente).

Sia per l’operatore SDO_WITHIN_DISTANCE che per l’operatore SDO_NN viene specificato che non sono supportati per fare join spaziali, quindi non sono supportate query del tipo:


select * from tab1 a, tab2 b where sdo_nn(a.geom,b.geom,'sdo_num_res=1')='TRUE'

Infatti io ho provato e può accadere che funzioni come che dia errore tipo questo:

ERROR at line 1:
ORA-13249: SDO_NN cannot be evaluated without using index
ORA-06512: at “MDSYS.MD”, line 1723
ORA-06512: at “MDSYS.MDERR”, line 17
ORA-06512: at “MDSYS.PRVT_IDX”, line 9

anche se entrambi i campi sono indicizzati. Di anomalie sul funzionamento se ne parla anche qui, ma io ad esempio sono riuscito a farlo funzionare solo con l’hint INDEX, ma visto l’avviso di non supporto dato sulla documentazione non so quanto sia affidabile.

Assieme all’operatore SDO_NN è possibile usare l’operatore discendente (ancillary) SDO_NN_DISTANCE che messo nella sezione SELECT ritorna anche la distanza fra gli oggetti selezionati e quello di riferimento.

Per eseguire vere e proprie join spaziali occorre usare l’opertore SDO_JOIN, che però come si può vedere dalla documentazione non è un vero operatore ma una funzione (una table function). Non ho ancora fatto molti test per poter dire se SDO_JOIN sopperisce completamente ai problemi che ho avuto sopratutto con SDO_NN nel caso di join fra tabelle, spero di dedicarci un post apposito.

 

Lascia un commento »

RSS feed for comments on this post. TrackBack URI

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

Crea un sito o un blog gratuitamente presso WordPress.com.
Entries e commenti feeds.

%d blogger cliccano Mi Piace per questo: