所有空間資料儲存在 SDO_GEOMETRY 物件型別中,結構定義:
CREATE TYPE sdo_geometry AS OBJECT (
SDO_GTYPE NUMBER, -- 幾何類型:DLTT (D=維度, L=線性引用, TT=類型)
SDO_SRID NUMBER, -- 空間參考系統 ID (NULL=笛卡爾平面)
SDO_POINT SDO_POINT_TYPE, -- 單點幾何 (X,Y,Z)
SDO_ELEM_INFO SDO_ELEM_INFO_ARRAY, -- 元素資訊陣列 (每 3 值一組)
SDO_ORDINATES SDO_ORDINATE_ARRAY -- 座標陣列 (所有頂點扁平化)
);
| 屬性 | 說明 | 範例值 |
|---|---|---|
SDO_GTYPE | 4 位數字 DLTT:D=維度(2/3), L=線性引用(0/1/2/3), TT=類型(00-07) | 2003=2D 多邊形, 2001=2D 點, 2002=2D 線串 |
SDO_SRID | EPSG 代碼,如 4326=WGS84 經緯度;NULL=無投影平面座標 | 4326, 3857, NULL |
SDO_POINT | 單點幾何時使用 (X,Y,Z);複雜幾何設 NULL | SDO_POINT_TYPE(121.5, 25.0, NULL) |
SDO_ELEM_INFO | 每 3 值描述一元素: 1. 起始頂點位移 (1-based) 2. 元素類型 (1=點, 2=線, 1003=外環多邊形, 2003=內環/島) 3. 串連方式 (1=直線, 2=圓弧) | (1,1003,1, 19,2003,1) = 外環起第1點直線連、內環起第19點直線連 |
SDO_ORDINATES | 所有頂點座標扁平存儲:(x1,y1, x2,y2, ...) | (0,0, 10,0, 10,10, 0,10, 0,0, 4,4, 6,4, 6,6, 4,6, 4,4) |
CREATE TABLE mylake (
feature_id NUMBER PRIMARY KEY,
name VARCHAR2(32),
shape MDSYS.SDO_GEOMETRY
);
INSERT INTO USER_SDO_GEOM_METADATA VALUES (
'MYLAKE', -- 表名 (大寫)
'SHAPE', -- 空間欄位名 (大寫)
MDSYS.SDO_DIM_ARRAY(
MDSYS.SDO_DIM_ELEMENT('X', 0, 100, 0.05), -- X 維:最小、最大、容忍度
MDSYS.SDO_DIM_ELEMENT('Y', 0, 100, 0.05) -- Y 維:最小、最大、容忍度
),
NULL -- SRID:NULL=笛卡爾座標;如 4326=WGS84
);
COMMIT;
容忍度:空間運算判斷相等/相交的最小距離閾值。單位與座標系一致。太小→運算失敗/效能差;太大→精度遺失。建議:地理座標 0.000005 度(~0.5m),投影座標 0.05-0.5 米。
CREATE INDEX mylake_idx ON mylake(shape)
INDEXTYPE IS MDSYS.SPATIAL_INDEX
PARAMETERS ('LAYER_GTYPE=POLYGON SDO_INDX_DIMS=2');
PARAMETERS 進階選項:
WORK_TABLESPACE、PARALLEL、SDO_RTR_PCTFREE(節點填充因子)、SDO_DML_BATCH_SIZE(DML 批次更新閾值)。
INSERT INTO mylake VALUES (
10, 'Lake Calhoun',
MDSYS.SDO_GEOMETRY(
2003, -- 2D 多邊形
NULL, -- SRID
NULL, -- POINT
MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,1, 19,2003,1), -- 外環+內環
MDSYS.SDO_ORDINATE_ARRAY(
0,0, 10,0, 10,10, 0,10, 0,0, -- 外環 5 點 (首尾閉合)
4,4, 6,4, 6,6, 4,6, 4,4 -- 內環 5 點 (島嶼)
)
)
);
INSERT INTO mylake VALUES (
11, 'The Windswept',
MDSYS.SDO_GEOMETRY(2003, NULL, NULL,
MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,1),
MDSYS.SDO_ORDINATE_ARRAY(2,2, 3,2, 3,3, 2,3, 2,2)
)
);
INSERT INTO mylake VALUES (
12, 'Blue Crest',
MDSYS.SDO_GEOMETRY(2003, NULL, NULL,
MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,1),
MDSYS.SDO_ORDINATE_ARRAY(7,7, 8,7, 8,8, 7,8, 7,7)
)
);
-- 查詢窗口:矩形 (2,2)-(5,5)
SELECT name boat_name
FROM mylake t
WHERE t.feature_id != 10 -- 排除湖泊本身
AND SDO_FILTER(
t.shape,
MDSYS.SDO_GEOMETRY(2003, NULL, NULL,
MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,1),
MDSYS.SDO_ORDINATE_ARRAY(2,2, 5,2, 5,5, 2,5, 2,2)
),
'QUERYTYPE=WINDOW' -- 窗口查詢,幾何不需來自表
) = 'TRUE';
-- 組合:先 FILTER 再 RELATE,獲得精確結果
SELECT name boat_name
FROM mylake t
WHERE t.feature_id != 10
AND SDO_FILTER(t.shape, , 'QUERYTYPE=WINDOW') = 'TRUE'
AND SDO_RELATE(t.shape, , 'MASK=INSIDE QUERYTYPE=WINDOW') = 'TRUE';
| MASK | 含義 | 圖示 |
|---|---|---|
INSIDE | A 完全在 B 內部 | ●━━○ |
CONTAINS | A 完全包含 B | ○━━● |
COVERS | A 覆蓋 B (允許邊界接觸) | ○━━● |
TOUCH | A 與 B 接觸 (邊界相交、內部不相交) | ○━● |
OVERLAPBDYDISJOINT | 重疊但邊界不相交 | ○╬○ |
OVERLAPBDYINTERSECT | 重疊且邊界相交 | ○╬○ |
EQUAL | 幾何完全相同 | ○=○ |
ANYINTERACT | 任意相交 (上述任一) | ○╬○ |
SDO_RELATE(..., 'MASK=INSIDE+TOUCH QUERYTYPE=WINDOW')
| 函數 | 用途 | 範例 |
|---|---|---|
SDO_GEOM.SDO_AREA | 計算面積 | SDO_GEOM.SDO_AREA(shape, 0.05) |
SDO_GEOM.SDO_LENGTH | 計算長度/周長 | SDO_GEOM.SDO_LENGTH(shape, 0.05) |
SDO_GEOM.SDO_BUFFER | 緩衝區 (擴展/縮減) | SDO_GEOM.SDO_BUFFER(shape, 10, 0.05) |
SDO_GEOM.SDO_CENTROID | 幾何中心點 | SDO_GEOM.SDO_CENTROID(shape, 0.05) |
SDO_GEOM.SDO_CONVEX_HULL | 凸包 | SDO_GEOM.SDO_CONVEX_HULL(shape, 0.05) |
SDO_NN | 最近鄰搜尋 (需空間索引) | SDO_NN(t.shape, :pt, 'SDO_NUM_RES=5') |
SDO_WITHIN_DISTANCE | 距離範圍內搜尋 | SDO_WITHIN_DISTANCE(t.shape, :pt, 'DISTANCE=1000') |
-- 將幾何從 SRID 4326 (WGS84) 轉為 3857 (Web Mercator)
SELECT SDO_CS.TRANSFORM(shape, 3857) FROM mylake WHERE feature_id = 10;
-- 需預先載入 EPSG 定義 (通常預設已載入)
SELECT * FROM MDSYS.CS_SRS WHERE SRID IN (4326, 3857);
USER_SDO_GEOM_METADATA 範圍必須涵蓋所有資料,容忍度適中ALTER INDEX ... REBUILD 或設 SDO_DML_BATCH_SIZE 自動批次更新SDO_FILTER 先行,再 SDO_RELATE 精確;避免單獨用 SDO_RELATE 導致全表掃描PARALLEL 索引建立與查詢Oracle Spatial 以 SDO_GEOMETRY 統一表示點/線/面/多元素幾何,**四步驟(建表→註冊元資料→建空間索引→插入資料)建立完整空間資料庫**。查詢遵循「Primary Filter (SDO_FILTER) → Secondary Filter (SDO_RELATE)」兩階段模式,配合豐富的 MASK 拓撲關係與空間分析函數,支援企業級 GIS 應用。掌握 SDO_ELEM_INFO 編碼規則與座標系統管理,是玩轉 Oracle Spatial 的核心技能。