OceanBaseデータベースのOracleモードでは、SDO_GEOMETRY タイプの4つのメンバー関数を使用して、SDO_GEOMETRY 空間オブジェクトの次元、タイプ、および有効性情報を照会できます。また、SDO_GEOM パッケージ内の関数 SDO_DISTANCE() およびその他の関数 SDO_RELATE() を使用して、空間オブジェクト間の距離と関係情報を計算することもサポートされています。
SDO_GEOMETRY タイプ
GET_DIMS() と ST_COORDDIM()
GET_DIMS() および ST_COORDDIM() 関数は、空間オブジェクトの次元(つまり、幾何オブジェクトの座標数)を取得するために使用されます。例えば、2次元オブジェクトの場合、次元は2です。3次元オブジェクトの場合、次元は3です。
例:
SELECT SDO_GEOMETRY(2001, NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1,1), SDO_ORDINATE_ARRAY(10,500)).GET_DIMS() AS test_get_dims FROM dual;
実行結果は次のとおりです:
+---------------+
| TEST_GET_DIMS |
+---------------+
| 2 |
+---------------+
1 row in set
SELECT SDO_GEOMETRY(2001, NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1,1), SDO_ORDINATE_ARRAY(10,500)).ST_COORDDIM() AS test_st_coorddim FROM dual;
実行結果は次のとおりです:
+------------------+
| TEST_ST_COORDDIM |
+------------------+
| 2 |
+------------------+
1 row in set
GET_GTYPE()
GET_GTYPE() は、空間オブジェクトの幾何タイプコードを取得するために使用されます。幾何タイプコードは整数値であり、点、線、ポリゴンなど、特定のタイプの幾何オブジェクトを表します。
例:
SELECT SDO_GEOMETRY(2001, NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1,1), SDO_ORDINATE_ARRAY(10,500)).GET_GTYPE() AS test_get_gtype FROM dual;
実行結果は次のとおりです:
+----------------+
| TEST_GET_GTYPE |
+----------------+
| 1 |
+----------------+
1 row in set
ST_ISVALID()
ST_ISVALID() は、空間オブジェクトが有効な幾何オブジェクトであるかどうかを確認するために使用されます。オブジェクトが有効な場合、関数は1を返します。そうでない場合は0を返します。
SELECT SDO_GEOMETRY(2001, NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1,1), SDO_ORDINATE_ARRAY(10,500)).ST_ISVALID() AS test_st_isvalid FROM dual;
実行結果は次のとおりです:
+-----------------+
| TEST_ST_ISVALID |
+-----------------+
| 1 |
+-----------------+
1 row in set
SDO_GEOMパッケージ
SDO_DISTANCE()
SDO_DISTANCE()は、2つの空間幾何オブジェクト間の最小距離を計算するために使用されます。例えば、2次元パラメータgeom1と2次元パラメータgeom2間の最小距離です。
SELECT SDO_GEOM.SDO_DISTANCE(SDO_GEOMETRY('POINT(0 0)', 4326), SDO_GEOMETRY('POINT(0.01 0)', 4326)) FROM dual;
実行結果は次のとおりです:
+-----------------------------------------------------------------------------------------+
| SDO_GEOM.SDO_DISTANCE(SDO_GEOMETRY('POINT(00)', 4326),SDO_GEOMETRY('POINT(0.010)',4326)) |
+-----------------------------------------------------------------------------------------+
| 1113.1949077920626 |
+-----------------------------------------------------------------------------------------+
1 row in set
SDO_AREA()
説明
この関数はV4.3.5 BP5バージョンからサポートされています。
SDO_AREA()は、1つの幾何オブジェクトの平面積を計算するために使用され、返される値の単位は幾何が属するSRSの線形単位と一致します。球面/楕円体への変換は行われません。2D平面幾何のみをサポートしており、3D入力はサポートされていません。
構文は以下のとおりです:
SDO_GEOM.SDO_AREA(geom[, tolerance])
geomは幾何オブジェクトを表します。toleranceはオプションで、デフォルト値はNULLです。面積計算の許容誤差を表し、計算精度を制御するために使用されます。
返される値はNUMBER型のデータであり、幾何オブジェクトの平面積を表します。単位は幾何が属するSRSの線形単位と一致します。
例:
SELECT SDO_GEOM.SDO_AREA(
SDO_GEOMETRY('POLYGON((0 0, 3 0, 3 4, 0 4, 0 0))'),0.005)
) AS area FROM dual;
実行結果は次のとおりです:
+------+
|| AREA |
+------+
|| 12 |
+------+
1 row in set
空間関係判断関数
SDO_CONTAINS()
説明
この関数は、V4.3.5 BP5バージョンからサポートされています。
この関数は、ある幾何オブジェクトが別の幾何オブジェクトを厳密に含むかどうかを判断します。例えば、geomA が geomB を厳密に含むかどうか(境界点は含まれないと見なす)。これは SDO_RELATE(geomA, geomB, 'mask=CONTAINS') と同じであり、論理的には次のようになります:Contains(A, B) ⇔ Within(B, A)。
構文は以下のとおりです:
SDO_CONTAINS(geomA, geomB)
geomAは幾何オブジェクトAを表します。geomBは幾何オブジェクトBを表します。
戻り値は BOOLEAN 型データです:TRUE/FALSE/NULL(空の入力幾何オブジェクトは NULL を返します)。注意してください、SDO_CONTAINS は厳密な包含であり、境界点は FALSE を返します。
例:
SELECT SDO_CONTAINS(
SDO_GEOMETRY('POLYGON((0 0,10 0,10 10,0 10,0 0))', 4326),
SDO_GEOMETRY('POINT(5 5)', 4326)
) AS res FROM dual;
結果は次のとおりです:
+------+
|| RES |
+------+
|| TRUE |
+------+
1 row in set
SDO_ANYINTERACT()
説明
この関数は、V4.3.5 BP5バージョンからサポートされています。
この関数は、ある幾何オブジェクトが別の幾何オブジェクトと交差、接触、重複など、いかなる形式の空間的交差も持つかどうかを判断します。境界の接触も相互作用と見なされます。これは SDO_RELATE(..., 'mask=ANYINTERACT') と同じです。
構文は以下のとおりです:
SDO_ANYINTERACT(geomA, geomB)
geomAは幾何オブジェクトAを表します。geomBは幾何オブジェクトBを表します。
戻り値は BOOLEAN 型データです:TRUE/FALSE/NULL(空の入力幾何オブジェクトは NULL を返します)。
例:
SELECT SDO_ANYINTERACT(
SDO_GEOMETRY('LINESTRING(0 0,10 10)', 4326),
SDO_GEOMETRY('LINESTRING(0 10,10 0)', 4326)
) AS res FROM dual;
結果は次のとおりです:
+------+
|| RES |
+------+
|| TRUE |
+------+
1 row in set
SDO_RELATE()
SDO_RELATE()は、オブジェクトが指定された空間関係に適合するかどうかを判断するために使用されます。
注意事項は以下のとおりです:
- 現在、空間関係演算は
ANYINTERACTのみをサポートしています。 - パラメータ
geom1とgeom2が異なる座標系に基づいている場合、geom2でエラーが報告されます。 - インデックスクエリとして使用する場合、
SDO_RELATE()はWHERE句でSDO_RELATE(geometry1, geometry2, 'mask = <some_mask_val>') = 'TRUE'形式の関数式で使用する必要があり、geometry1はインデックス列である必要があります。
インデックスクエリの例は次のとおりです:
-- テストテーブルtest_spatial_indexを作成
CREATE TABLE test_spatial_index (fid INTEGER NOT NULL PRIMARY KEY, g SDO_GEOMETRY NOT NULL SRID 4326 );
-- いくつかのテストデータを挿入
INSERT INTO test_spatial_index VALUES(1, SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(10 50, null), null, null));
INSERT INTO test_spatial_index VALUES(2, SDO_GEOMETRY(2001, 4326, null, SDO_ELEM_INFO_ARRAY (1,1,1), SDO_ORDINATE_ARRAY (10,50)));
INSERT INTO test_spatial_index VALUES(3, SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(10.1234,50.567,null), null, null));
INSERT INTO test_spatial_index VALUES(4, SDO_GEOMETRY(2001, 4326, null, SDO_ELEM_INFO_ARRAY (1,1,1), SDO_ORDINATE_ARRAY (10.1234,50.567)));
INSERT INTO test_spatial_index VALUES(5, SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(10.1234,50.567,null), null, null));
-- スペースインデックスidxを作成
CREATE INDEX idx ON test_spatial_index(g) INDEXTYPE IS MDSYS.SPATIAL_INDEX;
-- インデックスクエリ
SELECT * FROM test_spatial_index WHERE SDO_RELATE(g, SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(10.1234,50.567,null), null, null), 'querytype=WINDOW mask=anyinteract') = 'TRUE';
実行結果は次のとおりです:
+------+-----------------------------------------------------------------------------+
| FID | G |
+------+-----------------------------------------------------------------------------+
| 3 | SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(10.1234, 50.567, NULL), NULL, NULL) |
| 4 | SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(10.1234, 50.567, NULL), NULL, NULL) |
| 5 | SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(10.1234, 50.567, NULL), NULL, NULL) |
+------+-----------------------------------------------------------------------------+
3 rows in set
実行計画は次のとおりで、idxインデックスを使用してアクセスします:
| |ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)| |
| -------------------------------------------------------------------- |
| |0 |TABLE FULL SCAN|TEST_SPATIAL_INDEX(IDX)|1 |135 | |
| ====================================================================
SDO_UTILパッケージ
GETVERTICES()
説明
この関数は、V4.3.5 BP5バージョンからサポートされています。
この関数は、2D/3Dのジオメトリオブジェクトの頂点座標を取得するために使用されます:
- 2Dジオメトリでは
Z=NULLとなります。 - 3Dジオメトリでは実際の
Z値が返され、Wは常にNULLです。
構文は次のとおりです:
TABLE(SDO_UTIL.GETVERTICES(geom))
- 呼び出し時には
TABLE(...)形式でネストテーブルを展開する必要があります。 geomはジオメトリオブジェクトを表します。
返されるネストテーブルはVERTEX_SET_TYPEで、各行に1つの頂点が含まれ、X/Y/Z/Wおよび予約済みの列が含まれます:
# X,Y,Z,Wは頂点座標、V1..V11は予約済みの列で、今後の拡張用です
# IDは頂点IDで、1から増分します
X,Y,Z,W,V1..V11,ID
例:
SELECT v.id, v.x, v.y, v.z
FROM TABLE(
SDO_UTIL.GETVERTICES(
SDO_GEOMETRY(
3002, -- 3002 = 3Dラインストリング (3D LineString)
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,2,1),
SDO_ORDINATE_ARRAY(
10, 10, 5, -- 最初の点 X=10,Y=10,Z=5
20, 20, 6, -- 2番目の点
30, 10, 7 -- 3番目の点
)
)
)
) v;
実行結果は次のとおりです:
+------+------+------+------+
|| ID | X | Y | Z |
+------+------+------+------+
|| 1 | 10 | 10 | 5 |
|| 2 | 20 | 20 | 6 |
|| 3 | 30 | 10 | 7 |
+------+------+------+------+
3 rows in set