Top 5 Recent Articles
ARTICLES CATEGORIES
- Algorithms (22)
- All (399)
- Biography (1)
- Blog (44)
- Business Requirements (1)
- Commentary (1)
- Conversion (2)
- Customers (2)
- Data Models (1)
- Education (2)
- GeoRaptor (13)
- GPS (1)
- Image Processing (2)
- Import Export (8)
- Licensing (2)
- LiDAR (1)
- Linear Referencing (4)
- Manifold GIS (3)
- Mapping (1)
- MySQL Spatial (7)
- Networking and Routing (including Optimization) (5)
- Open Source (18)
- Oracle Spatial and Locator (194)
- Partitioning (1)
- PostGIS (36)
- Projections (1)
- Published Articles (1)
- qGIS (1)
- Recommendations (1)
- Services (1)
- Software Change Log (1)
- Source Code (37)
- Space Curves (9)
- Spatial Database Functions (109)
- Spatial DB comparison (1)
- Spatial XML Processing (11)
- SQL Server Spatial (92)
- Standards (3)
- Stored Procedure (17)
- Tessellation or Gridding (10)
- Tools (2)
- Topological Relationships (1)
- Training (2)
- Triangulation (2)
The significance of sdo_lb/sdo_ub in USER_SDO_GEOM_METDATA: Do I need it?
Questions are often raised about the significance of the SDO_LB and SDO_UB fields of the SDO_DIM_ELEMENT structures that define the spatial extent of the dimensions (SDO_DIM_ARRAY) of a table/column in Oracle’s metadata tables (accessed via the USER_SDO_GEOM_METADATA and ALL_SDO_GEOM_METADATA views).
The structure of the the ALL_SDO_GEOM_METADATA view is:
SQL> describe ALL_SDO_GEOM_METADATA Name Null? Type ----------------------------------------------------------------------- -------- ------------------- OWNER NOT NULL VARCHAR2(32) TABLE_NAME NOT NULL VARCHAR2(32) COLUMN_NAME NOT NULL VARCHAR2(1024) DIMINFO MDSYS.SDO_DIM_ARRAY SRID NUMBER
An MDSYS.SDO_DIM_ARRAY is an array of MDSYS.SDO_DIM_ELEMENTs as follows:
SQL> describe 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
Note, an SDO_DIM_ELEMENT structure is created for each dimension of the data eg 2 for 2D data, 3 for 3D data etc.
An example is:
INSERT INTO ALL_SDO_GEOM_METADATA ( OWNER, TABLE_NAME, COLUMN_NAME, DIMINFO, SRID ) VALUES ( 'CODESYS', 'GEODLINE2D', 'GEOM', MDSYS.SDO_DIM_ARRAY( MDSYS.SDO_DIM_ELEMENT('Longitude',-180,180,0.05), MDSYS.SDO_DIM_ELEMENT('Latitude' ,-90,90,0.05)), 8311);
These questions are often raised in the context of spatial indexing and also their use in overloaded functions in Oracle’s SDO_GEOM package which can take either an SDO_DIM_ARRAY structure or an tolerance (cf SDO_TOLERANCE) value such as in the following versions of the geometry validation functions:
FUNCTION VALIDATE_GEOMETRY RETURNS VARCHAR2 Argument Name Type In/Out Default? ------------------------------ ----------------------- ------ -------- THEGEOMETRY SDO_GEOMETRY IN THEDIMINFO SDO_DIM_ARRAY IN FUNCTION VALIDATE_GEOMETRY RETURNS VARCHAR2 Argument Name Type In/Out Default? ------------------------------ ----------------------- ------ -------- THEGEOMETRY SDO_GEOMETRY IN TOLERANCE NUMBER IN
Indexing
When Oracle Spatial predominantly used QuadTree indexing it was necessary to ensure that the area to be tesselated covered the entire contents of the table/column. Thus, one entered in extents to MDSYS.SDO_DIM_ARRAY that were sensible (ie just covered the area) such that the tesselation could occur effectively and efficiently at the chosen tiling level as expressed by SDO_LEVEL in the PARAMETERS clause of the spatial index creation statement.
If your MDSYS.SDO_DIM_ARRAY SDO_LB/SDO_UBs do not cover the area to be indexed then when you try to create a Quad Tree index with a statement like this:
CREATE INDEX projline2d_geom ON projline(geom) INDEXTYPE IS mdsys.spatial_index PARAMETERS('SDO_LEVEL=8');
You will get this error if the extent of the data in projline2d(geom) includes data outside of the extent recorded in the sdo_dim_array structure:
SQL Error: 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-13206: internal error [Tessellate] while creating the spatial index ORA-13249: Error in spatial index: [mdpridxtessellate] ORA-13200: internal error [ROWID:AAAPofAAJAAAPNIAAA] in spatial indexing. ORA-13019: coordinates out of bounds ORA-06512: at "MDSYS.SDO_INDEX_METHOD_9I", line 7 ORA-06512: at line 1 29855. 00000 - "error occurred in the execution of ODCIINDEXCREATE routine"
Now RTree indexing does not require a definition of the entire extent of the area to be indexed as the indexing is based on the MBR of individual sdo_geometries and not the regular tesselation of a defined space.
So, nowadays, where RTree indexing is used (and is the recommended spatial indexing method since Oracle Spatial 9.2) the values in the MDSYS.SDO_DIM_ELEMENT’s SDO_LB/SDO_UB fields are irrelevant for spatial indexing. So, if one rebuilt the above index using RTree indexing the index would be created:
CREATE INDEX projline2d_geom ON projline(geom) INDEXTYPE IS mdsys.spatial_index PARAMETERS('sdo_indx_dims=2, layer_gtype=MULTILINE');
So what is the use of putting values into these fields when using RTree indexing? Geospatial practitioners tend to use the SDO_DIM_ARRAY to define the extent of the data because some GIS packages do actually use it for “Zoom to Extent” type operations (which would be far faster than SELECT SDO_AGGR_MBR(geom) FROM table!).
Use in Overloaded Functions
Now that cleans up the sdo_lb/sdo_ub elements of the sdo_dim_array structure. But what about tolerance vs MDSYS.SDO_DIM_ARRAYy using in functions?
Now, I tend to avoid hardcoding tolerance values in queries that involve the tolerance parameter (and not the MDSYS.SDO_DIM_ARRAY form) unless it is different from the SDO_TOLERANCE value in the SDO_DIM_ARRAY). Where the tolerance is the same, I always use the MDSYS.SDO_DIM_ARRAY form as it is easier to use in queries.
Compare this:
SELECT mdsys.sdo_geom.validate_geometry(a.geom,asgm.diminfo) FROM all_sdo_geom_metadata asgm, projline2d a WHERE asgm.owner = 'CODESYS' AND asgm.table_name = 'PROJLINE2D' AND asgm.column_name = 'GEOM';
To this:
SELECT mdsys.sdo_geom.validate_geometry(a.geom,b.sdo_tolerance) FROM (SELECT t.sdo_tolerance FROM all_sdo_geom_metadata asgm, TABLE(asgm.diminfo) t WHERE asgm.owner = 'CODESYS' AND asgm.table_name = 'PROJLINE2D' AND asgm.column_name = 'GEOM' AND t.sdo_dimname = 'X' ) b, projline2d a;
And I think you can see why!
I hope this explanation is of some use.
If you want to learn more about spatial indexing click here
regards
Simon
Documentation
- MySQL Spatial General Functions
- Oracle LRS Objects
- Oracle Spatial Exporter (Java + pl/SQL)
- Oracle Spatial Object Functions
- Oracle Spatial Object Functions (Multi Page)
- PostGIS pl/pgSQL Functions
- SC4O Oracle Java Topology Suite (Java + pl/SQL)
- SQL Server Spatial General TSQL Functions
- SQL Server Spatial LRS TSQL Functions