3.1 ST_GEOMETRY and SDO_GEOMETRY Interoperability
The SQL Multimedia ST_GEOMETRY root type, including its subtypes, and the Oracle Spatial SDO_GEOMETRY type are essentially interoperable.
The ST_GEOMETRY subtypes are:
-
ST_CIRCULARSTRING
-
ST_COMPOUNDCURVE
-
ST_CURVE
-
ST_CURVEPOLYGON
-
ST_GEOMCOLLECTION
-
ST_LINESTRING
-
ST_MULTICURVE
-
ST_MULTILINESTRING
-
ST_MULTIPOINT
-
ST_MULTIPOLYGON
-
ST_MULTISURFACE
-
ST_POINT
-
ST_POLYGON
-
ST_SURFACE
The ST_GEOMETRY type has an additional constructor method (that is, in addition to the constructors defined in the ISO standard) for creating an instance of the type using an SDO_GEOMETRY object. This constructor has the following format:
ST_GEOMETRY(geom SDO_GEOMETRY);
Example 3-1 Using the ST_GEOMETRY Type for a Spatial Column
Example 3-1 creates a table using the ST_GEOMETRY type for a spatial column instead of the SDO_GEOMETRY type, and it uses the ST_GEOMETRY constructor to specify the SHAPE column value when inserting a row into that table.
CREATE TABLE cola_markets ( mkt_id NUMBER PRIMARY KEY, name VARCHAR2(32), shape ST_GEOMETRY); INSERT INTO cola_markets VALUES( 1, 'cola_a', ST_GEOMETRY( SDO_GEOMETRY( SDO_POLYGON2D, -- two-dimensional polygon NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1003,3), -- one rectangle (1003 = exterior) SDO_ORDINATE_ARRAY(1,1, 5,7) -- only 2 points needed to -- define rectangle (lower left and upper right) with -- Cartesian-coordinate data ) ) );
If you create a table with a spatial column of type ST_GEOMETRY, you should add its information to the USER_SDO_GEOM_METADATA view and create a spatial index on the ST_GEOMETRY column, just as you would for spatial data defined using the SDO_GEOMETRY type. After you have performed these operations, you can use Oracle Spatial operators (described in Spatial Operators ) in the ST_GEOMETRY data. In addition to the operators defined in the standard, you can use the SDO_NN and SDO_WITHIN_DISTANCE operators.
Example 3-2 Creating, Indexing, Storing, and Querying ST_GEOMETRY Data
Example 3-2 performs many of the same basic operations as in Simple Example: Inserting, Indexing, and Querying Spatial Data, but it uses the ST_GEOMETRY type instead of the SDO_GEOMETRY type for the spatial column.
CREATE TABLE cola_markets ( mkt_id NUMBER PRIMARY KEY, name VARCHAR2(32), shape ST_GEOMETRY); INSERT INTO cola_markets VALUES( 1, 'cola_a', ST_GEOMETRY( SDO_GEOMETRY( SDO_POLYGON2D, -- two-dimensional polygon NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1003,3), -- one rectangle (1003 = exterior) SDO_ORDINATE_ARRAY(1,1, 5,7) -- only 2 points needed to -- define rectangle (lower left and upper right) with -- Cartesian-coordinate data ) ) ); INSERT INTO cola_markets VALUES( 2, 'cola_b', ST_GEOMETRY( SDO_GEOMETRY( SDO_POLYGON2D, -- two-dimensional polygon NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1003,1), -- one polygon (exterior polygon ring) SDO_ORDINATE_ARRAY(5,1, 8,1, 8,6, 5,7, 5,1) ) ) ); INSERT INTO cola_markets VALUES( 3, 'cola_c', ST_GEOMETRY( SDO_GEOMETRY( SDO_POLYGON2D, -- two-dimensional polygon NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1003,1), -- one polygon (exterior polygon ring) SDO_ORDINATE_ARRAY(3,3, 6,3, 6,5, 4,5, 3,3) ) ) ); INSERT INTO cola_markets VALUES( 4, 'cola_d', ST_GEOMETRY( SDO_GEOMETRY( SDO_POLYGON2D, -- two-dimensional polygon NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1003,4), -- one circle SDO_ORDINATE_ARRAY(8,7, 10,9, 8,11) ) ) ); --------------------------------------------------------------------------- -- UPDATE METADATA VIEW -- --------------------------------------------------------------------------- -- Update the USER_SDO_GEOM_METADATA view. This is required before -- the spatial index can be created. Do this only once for each layer -- (that is, table-column combination; here: cola_markets and shape). INSERT INTO user_sdo_geom_metadata (TABLE_NAME, COLUMN_NAME, DIMINFO, SRID) VALUES ( 'cola_markets', 'shape', SDO_DIM_ARRAY( -- 20X20 grid SDO_DIM_ELEMENT('X', 0, 20, 0.005), SDO_DIM_ELEMENT('Y', 0, 20, 0.005) ), NULL -- SRID ); ------------------------------------------------------------------- -- CREATE THE SPATIAL INDEX -- ------------------------------------------------------------------- CREATE INDEX cola_spatial_idx ON cola_markets(shape) INDEXTYPE IS MDSYS.SPATIAL_INDEX_V2; --------------------------- -- SDO_NN and SDO_WITHIN_DISTANCE -------------------------- -- SDO_NN operator. SELECT /*+ INDEX(c cola_spatial_idx) */ c.mkt_id, c.name FROM cola_markets c WHERE SDO_NN(c.shape, sdo_geometry(2001, NULL, sdo_point_type(10,7,NULL), NULL, NULL), 'sdo_num_res=2') = 'TRUE'; -- SDO_NN_DISTANCE ancillary operator SELECT /*+ INDEX(c cola_spatial_idx) */ c.mkt_id, c.name, SDO_NN_DISTANCE(1) dist FROM cola_markets c WHERE SDO_NN(c.shape, sdo_geometry(2001, NULL, sdo_point_type(10,7,NULL), NULL, NULL), 'sdo_num_res=2', 1) = 'TRUE' ORDER BY dist; -- SDO_WITHIN_DISTANCE operator (two examples) SELECT c.name FROM cola_markets c WHERE SDO_WITHIN_DISTANCE(c.shape, SDO_GEOMETRY(2003, NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1003,3), SDO_ORDINATE_ARRAY(4,6, 8,8)), 'distance=10') = 'TRUE'; -- What geometries are within a distance of 10 from a query window -- (here, a rectangle with lower-left, upper-right coordinates 4,6, 8,8)? -- But exclude geoms with MBRs with both sides < 4.1, i.e., cola_c and cola_d. SELECT c.name FROM cola_markets c WHERE SDO_WITHIN_DISTANCE(c.shape, SDO_GEOMETRY(2003, NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1003,3), SDO_ORDINATE_ARRAY(4,6, 8,8)), 'distance=10 min_resolution=4.1') = 'TRUE'; ------------------------------------- -- Some ST_GEOMETRY member functions ------------------------------------- SELECT c.shape.GET_WKB() FROM cola_markets c WHERE c.name = 'cola_b'; SELECT c.shape.GET_WKT() FROM cola_markets c WHERE c.name = 'cola_b'; SELECT c.shape.ST_COORDDIM() FROM cola_markets c WHERE c.name = 'cola_b'; SELECT c.shape.ST_ISVALID() FROM cola_markets c WHERE c.name = 'cola_b'; SELECT c.shape.ST_SRID() FROM cola_markets c WHERE c.name = 'cola_b'; SELECT c.shape.ST_SRID(4326) FROM cola_markets c WHERE c.name = 'cola_b'; SELECT c.shape.ST_ISEMPTY() FROM cola_markets c WHERE c.name = 'cola_b'; SELECT c.shape.ST_ENVELOPE() FROM cola_markets c WHERE c.name = 'cola_b'; SELECT c.shape.ST_BOUNDARY() FROM cola_markets c WHERE c.name = 'cola_b'; SELECT c.shape.ST_GEOMETRYTYPE() FROM cola_markets c WHERE c.name = 'cola_b'; SELECT c.shape.ST_ISSIMPLE() FROM cola_markets c WHERE c.name = 'cola_b'; SELECT c.shape.ST_DIMENSION() FROM cola_markets c WHERE c.name = 'cola_b'; SELECT c.shape.ST_CONVEXHULL() FROM cola_markets c WHERE c.name = 'cola_b'; SELECT c.shape.ST_CENTROID() FROM cola_markets c WHERE c.name = 'cola_b'; SELECT c.shape.ST_GETTOLERANCE() FROM cola_markets c WHERE c.name = 'cola_b'; -- Some member functions that require a parameter DECLARE cola_a_geom ST_GEOMETRY; cola_b_geom ST_GEOMETRY; cola_c_geom ST_GEOMETRY; cola_d_geom ST_GEOMETRY; returned_geom ST_GEOMETRY; returned_number NUMBER; BEGIN -- Populate geometry variables with cola market shapes. SELECT c.shape INTO cola_a_geom FROM cola_markets c WHERE c.name = 'cola_a'; SELECT c.shape INTO cola_b_geom FROM cola_markets c WHERE c.name = 'cola_b'; SELECT c.shape INTO cola_c_geom FROM cola_markets c WHERE c.name = 'cola_c'; SELECT c.shape INTO cola_d_geom FROM cola_markets c WHERE c.name = 'cola_d'; SELECT c.shape.ST_EQUALS(cola_a_geom) INTO returned_number FROM cola_markets c WHERE c.name = 'cola_b'; DBMS_OUTPUT.PUT_LINE('Is cola_b equal to cola_a?: ' || returned_number); SELECT c.shape.ST_SYMMETRICDIFFERENCE(cola_a_geom) INTO returned_geom FROM cola_markets c WHERE c.name = 'cola_b'; SELECT c.shape.ST_DISTANCE(cola_d_geom) INTO returned_number FROM cola_markets c WHERE c.name = 'cola_b'; DBMS_OUTPUT.PUT_LINE('Distance between cola_b equal to cola_d: ' || returned_number); SELECT c.shape.ST_INTERSECTS(cola_a_geom) INTO returned_number FROM cola_markets c WHERE c.name = 'cola_b'; DBMS_OUTPUT.PUT_LINE('Does cola_b intersect cola_a?: ' || returned_number); SELECT c.shape.ST_CROSS(cola_a_geom) INTO returned_number FROM cola_markets c WHERE c.name = 'cola_b'; DBMS_OUTPUT.PUT_LINE('Does cola_b cross cola_a?: ' || returned_number); SELECT c.shape.ST_DISJOINT(cola_a_geom) INTO returned_number FROM cola_markets c WHERE c.name = 'cola_b'; DBMS_OUTPUT.PUT_LINE('Is cola_b disjoint with cola_a?: ' || returned_number); SELECT c.shape.ST_TOUCH(cola_a_geom) INTO returned_number FROM cola_markets c WHERE c.name = 'cola_b'; DBMS_OUTPUT.PUT_LINE('Does cola_b touch cola_a?: ' || returned_number); SELECT c.shape.ST_WITHIN(cola_a_geom) INTO returned_number FROM cola_markets c WHERE c.name = 'cola_b'; DBMS_OUTPUT.PUT_LINE('Is cola_b within cola_a?: ' || returned_number); SELECT c.shape.ST_OVERLAP(cola_a_geom) INTO returned_number FROM cola_markets c WHERE c.name = 'cola_b'; DBMS_OUTPUT.PUT_LINE('Does cola_b overlap cola_a?: ' || returned_number); SELECT c.shape.ST_CONTAINS(cola_a_geom) INTO returned_number FROM cola_markets c WHERE c.name = 'cola_b'; DBMS_OUTPUT.PUT_LINE('Does cola_b contain cola_a?: ' || returned_number); SELECT c.shape.ST_INTERSECTION(cola_a_geom) INTO returned_geom FROM cola_markets c WHERE c.name = 'cola_b'; SELECT c.shape.ST_DIFFERENCE(cola_a_geom) INTO returned_geom FROM cola_markets c WHERE c.name = 'cola_b'; SELECT c.shape.ST_UNION(cola_a_geom) INTO returned_geom FROM cola_markets c WHERE c.name = 'cola_b'; SELECT c.shape.ST_SYMDIFFERENCE(cola_a_geom) INTO returned_geom FROM cola_markets c WHERE c.name = 'cola_b'; SELECT c.shape.ST_TOUCHES(cola_a_geom) INTO returned_number FROM cola_markets c WHERE c.name = 'cola_b'; DBMS_OUTPUT.PUT_LINE('Does cola_b touch cola_a?: ' || returned_number); SELECT c.shape.ST_CROSSES(cola_a_geom) INTO returned_number FROM cola_markets c WHERE c.name = 'cola_b'; DBMS_OUTPUT.PUT_LINE('Does cola_b cross cola_a?: ' || returned_number); END; /
Parent topic: SQL Multimedia Type Support