Oracle Spatial: i dati spaziali

martedì 4 settembre 2012 alle 04:56 | Pubblicato su 11g, Oracle Locator, Oracle Spatial | Lascia un commento
Tag: ,

Nel post introduttivo ad Oracle Spatial ho cominciato a spiegare cos’è questa componente del database Oracle, partendo da una veloce descrizione dalla struttura dati su cui si basa tutto. SDO_GEOMETRY è un tipo dato definito come oggetto, quindi un tipo dato strutturato e dotato anche di alcuni metodi base. Gli oggetti sono una estensione del database relazionale Oracle e possono essere usati come altri tipi dato, quindi si possono creare tabelle che accanto a colonne con tipi dato classici come VARCHAR2, NUMBER e DATE possono avere colonne di tipo SDO_GEOMETRY; non ci sono limiti particolari, per cui è possibile inserire in una tabella quante colonne di tipo SDO_GEOMETRY si vuole, però normalmente (e fin’ora non ho visto esempi diversi) si usano tabelle con una sola colonna di tipo SDO_GEOMETRY. Io mi sto focalizzando più sull’utilizzo di dati spaziali geografici, in cui nelle colonne di tipo SDO_GEMETRY si registrano ad esempio tracciati di strade, di fiumi, di ferrovie, confini amministrativi ecc, in questo ambito si parla di layer, quindi c’è un layer con contiene i limiti amministrativi, con i propri attributi, uno per le strade ecc ecc. Come spiegato meglio in questo Whitepaper di Oracle è bene mantenere tabelle separate per oggetti geometrici con caratteristiche diverse, applicare in sostanza delle regole di normalizzazione. Nulla impedisce di inserire in una stessa tabella oggetti geometrici di tipo diverso, punti , linee, poligoni ma dal punto di vista logico e organizzativo e poi anche di prestazioni può non essere una buona idea.

METADATI

Per accedere a funzionalità di elaborazione ed analisi dei dati spaziali occorre inserire per ogni “layer”, dove per layer intendiamo una coppia tabella-colonna, dei metadata in una vista di sistema appositamente dedicata chiamata USER_SDO_GEOM_METADATA (esiste anche la versione ALL_SDO_GEOM_METADATA). Si tratta in realtà di viste “modificabili” che fanno capo a una tabella che si trova sempre nello schema MDSYS. Il tracciato di USER_SDO_GEOM_METADATA è:


SPATIAL@svil112_methone > desc user_sdo_geom_metadata
 Name Null? Type
 ----------------------------------------- -------- --------------------
 TABLE_NAME NOT NULL VARCHAR2(32)
 COLUMN_NAME NOT NULL VARCHAR2(1024)
 DIMINFO MDSYS.SDO_DIM_ARRAY
 SRID NUMBER

Quindi i primi due dati da inserire sono semplicemente il nome tabella e il nome campo di tipo SDO_GEOMETRY, poi c’è il campo diminfo, di tipo MDSYS.SDO_DIM_ARRAY:


SPATIAL@svil112_methone > desc MDSYS.SDO_DIM_ARRAY
 MDSYS.SDO_DIM_ARRAY VARRAY(4) OF MDSYS.SDO_DIM_ELEMENT
 Name Null? Type
 ----------------------------------------- -------- -------------
 SDO_DIMNAME VARCHAR2(64)
 SDO_LB NUMBER
 SDO_UB NUMBER
 SDO_TOLERANCE NUMBER

che è un array di record che in sostanza specificano per ogni dimensione spaziale un’etichetta (SDO_DIMNAME), un limite inferiore (SDO_LB), un limite superiore (SDO_UB) e una tolleranza. Dopo queste informazioni va inserito anche l’id del sistema di riferimento (SRID) che deve essere coerente con quello inserito nello stesso campo SDO_GEOMETRY  e può anche essere NULL.

Questi metadati servono per l’utilizzo di alcune funzioni di elaborazione dei dati spaziali e anche per la  creazione degli indici spaziali. Per i campi di tipo SDO_GEOMETRY è possibile creare degli appositi indici (indici di tipo R-Tree) che hanno lo scopo di migliorare le prestazioni delle elaborazioni su questo tipo dato. Si tratta di indici particolari, per la cui creazione però basta aggiungere alla sintassi utilizzata per gli indici standard la parte:


INDEXTYPE IS MDSYS.SPATIAL_INDEX;

Una delle particolarità di questi indici è che se anche fallisce con un errore la loro creazione rimane comunque un oggetto creato, per cui occorre comunque fare il drop per ricrearli:


SPATIAL@svil112_methone > CREATE INDEX IDX_TEST_1_SPIX ON TEST_1(B) INDEXTYPE IS MDSYS.SPATIAL_INDEX;
CREATE INDEX IDX_TEST_1_SPIX ON TEST_1(B) INDEXTYPE IS MDSYS.SPATIAL_INDEX
*
ERROR at line 1:
ORA-29855: error occurred in the execution of ODCIINDEXCREATE routine
ORA-13249: internal error in Spatial index: [mdidxrbd]
ORA-13249: Error in Spatial index: index build failed
ORA-13249: Error in spatial index: [mdrcrtxfergm]
ORA-13249: Error in spatial index: [mdpridxtxfergm]
ORA-13200: internal error [ROWID:AAAa+yAAEAACO9fAAA] in spatial indexing.
ORA-13206: internal error [] while creating the spatial index
ORA-13364: layer dimensionality does not match geometry dimensions
ORA-06512: at "MDSYS.SDO_INDEX_METHOD_10I", line 10

 

SPATIAL@svil112_methone > CREATE INDEX IDX_TEST_1_SPIX ON TEST_1(B) INDEXTYPE IS MDSYS.SPATIAL_INDEX;
CREATE INDEX IDX_TEST_1_SPIX ON TEST_1(B) INDEXTYPE IS MDSYS.SPATIAL_INDEX
 *
ERROR at line 1:
ORA-00955: name is already used by an existing object

Nell’esempio sopra ho fatto un esperimento, ho inserito in una tabella due record:


SPATIAL@svil112_methone > insert into test_1 values (1,Sdo_geometry (2001, null, null, sdo_elem_info_array (1,1,1), sdo_ordinate_array (10,5)));

1 row created.

SPATIAL@svil112_methone > insert into test_1 values (2,Sdo_geometry (2001, null, null, sdo_elem_info_array (1,1,1), sdo_ordinate_array (10,5,7)));

1 row created.

SPATIAL@svil112_methone > COMMIT;

Commit complete.

uno contiene un punto a due dimensioni e uno a tre dimensioni, è possibile farlo come si vede, poi ho inserito i metadati:


SPATIAL@svil112_methone > INSERT INTO USER_SDO_GEOM_METADATA VALUES ('TEST_1','B',SDO_DIM_ARRAY(SDO_DIM_ELEMENT('X', 0, 100, .005), SDO_DIM_ELEMENT('Y
', 0, 100, .005), SDO_DIM_ELEMENT('Z', 0, 99999, .005)),NULL);

1 row created.

SPATIAL@svil112_methone > COMMIT;

Commit complete.

La creazione dell’indice però fallisce lamentandosi del fatto che :

ORA-13364: layer dimensionality does not match geometry dimensions

le dimensioni specificate nei metadati sono tre ma una delle geometrie nella tabella ne ha solo due. Se rimuovo i metadati e riprovo a creare l’indice:


SPATIAL@svil112_methone > delete from USER_SDO_GEOM_metadata where table_name='TEST_1';

1 row deleted.

SPATIAL@svil112_methone > drop index idx_test_1_spix ;

Index dropped.

SPATIAL@svil112_methone > CREATE INDEX IDX_TEST_1_SPIX ON TEST_1(B) INDEXTYPE IS MDSYS.SPATIAL_INDEX;
CREATE INDEX IDX_TEST_1_SPIX ON TEST_1(B) INDEXTYPE IS MDSYS.SPATIAL_INDEX
*
ERROR at line 1:
ORA-29855: error occurred in the execution of ODCIINDEXCREATE routine
ORA-13203: failed to read USER_SDO_GEOM_METADATA view
ORA-13203: failed to read USER_SDO_GEOM_METADATA view
ORA-06512: at "MDSYS.SDO_INDEX_METHOD_10I", line 10

la creazione da errore perché richiede i metadati.

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: