我的業務發展目標是使用 Oracle Spatial 存盤我們的坐標資料。目前,我們從在海洋區域進行測量的科學家那里接收坐標,這些坐標以點的數字對或多邊形的長 varchar 陣列的形式存盤在我們的 Oracle 資料庫中。但是,我們希望通過使用 Oracle Spatial 來改進我們對這些資料的管理。
我們從科學家那里獲得的坐標資訊通常是 CSV 檔案,附加資料并作為欄位中的條目加載到 Oracle 表中。
我知道我可以手動將頂點輸入 SDO_ORDINATE_ARRAY 但我們經常在一個 CSV 檔案中提供數百個坐標對,這使得手動路徑非常低效。
有人可以告訴我是否有辦法通過從已存盤的資料庫中的其他表中提取資訊來填充 SDO_ORDINATE_ARRAY 的內容嗎?
我嘗試過的一個例子如下:
名為 GEOMTEST 的測驗表由 NAME varchar2(50) COORDS varchar2(4000) COORD_GEOM SDO_GEOMETRY 組成
我在英國威爾士的興趣區域“卡迪根灣”中填充了名稱。COORDS 是我在 varchar2 中存盤為陣列的多邊形。這是從 CSV 檔案匯入的。COORD_GEOM 是我希望將 COORDS 的內容轉換成的。
我試圖運行這段代碼,但收到一個錯誤:
插入到 geomtest (coord_geom) 值(SDO_GEOMETRY(2003,4326,null,SDO_ELEM_INFO_ARRAY(1,1003,1),SDO_ORDINATE_ARRAY 值(從 geomtest 中選擇坐標));
我使用 Toad 作為我的客戶端,錯誤是“錯誤:第 18 行。第 120 列,結束第 18 行,第 125 列:找到‘值’:保留字不能用作識別符號。
我認為這與我在 INSERT 陳述句的 SDO_ORDINATE_ARRAY 部分中使用 select 陳述句有關,但不確定如何繼續。
我將不勝感激任何建議,
非常感謝
肖恩
uj5u.com熱心網友回復:
不幸的是,您不能直接將包含數字的字串傳遞給SDO_ORDINATE_ARRAY建構式。一種解決方案是撰寫一個自定義字串標記器函式,它將坐標字串決議為單獨的數字,并構建一個SDO_ORDINATE_ARRAY物件。這是一個:
create or replace function tokenize (str clob)
return sdo_ordinate_array
is
s clob := str||',';
i number;
j number;
t sdo_ordinate_array := sdo_ordinate_array();
begin
i := 1;
loop
j := instr(s, ',', i);
exit when j = 0;
t.extend();
t(t.count) := to_number(substr(s,i,j-i));
i := j 1;
end loop;
return t;
end;
/
show errors
這是它的作業原理。首先讓我們用幾個例子創建一個簡單的表:
drop table geomtest purge;
create table geomtest (
id number,
name varchar2(50 char),
coords clob,
coord_geom sdo_geometry
);
insert into geomtest (id, name, coords)
values (
2686,
'TX/Mitchell',
'-101.17416, 32.527592, -101.17417, 32.523998, -101.1836, 32.087082, -100.82121, 32.086479, -100.66497, 32.085278, -100.66024, 32.5252, -101.17416, 32.527592'
);
insert into geomtest (id, name, coords)
values (
2769,
'TX/Yoakum',
'-103.05616, 33.388332, -103.06416, 32.958992, -102.59455, 32.958733, -102.59436, 33.388393, -103.05616, 33.388332'
);
commit;
然后讓我們使用 tokenizer 函式來更新幾何列:
update geomtest
set coord_geom = sdo_geometry(2003,4326,null,sdo_elem_info_array(1,1003,1),tokenize(coords));
commit;
檢查結果:
SQL> select * from geomtest;
ID NAME COORDS COORD_GEOM(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)
---- ----------- ------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2686 TX/Mitchell -101.17416, 32.527592, -101.17417, 32.523998, -101.1836, 32.087082, -100.82121, 32.086479, -100.66497, 32.085278, -100.66024, 32.5252, -101.17416, 32.527592 SDO_GEOMETRY(2003, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1), SDO_ORDINATE_ARRAY(-101.17416, 32.527592, -101.17417, 32.523998, -101.1836, 32.087082, -100.82121, 32.086479, -100.66497, 32.085278, -100.66024, 32.5252, -101.17416, 32.527592))
2769 TX/Yoakum -103.05616, 33.388332, -103.06416, 32.958992, -102.59455, 32.958733, -102.59436, 33.388393, -103.05616, 33.388332 SDO_GEOMETRY(2003, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1), SDO_ORDINATE_ARRAY(-103.05616, 33.388332, -103.06416, 32.958992, -102.59455, 32.958733, -102.59436, 33.388393, -103.05616, 33.388332))
2 rows selected.
筆記
我使用了一
CLOB列來存盤坐標。一個 4000 位元組的字串太小,無法容納任何嚴肅的幾何圖形(除非您的所有形狀都非常簡單——只有幾個點)。There are more efficient ways if doing this string-to-geometry conversion, but they imply that you use geometry-oriented strings notations: GeoJSON, WKT, GML. Those are naturally supported by Oracle. They also allow more complex structures like multi-polygons or polygons with holes.
EDIT: I rewrote the function to directly return a SDO_GEOMETRY object instead. This makes it easier to use:
create or replace function string_to_geom (str clob)
return sdo_geometry
is
s clob := str||',';
i number;
j number;
t sdo_ordinate_array := sdo_ordinate_array();
begin
i := 1;
loop
j := instr(s, ',', i);
exit when j = 0;
t.extend();
t(t.count) := to_number(substr(s,i,j-i));
i := j 1;
end loop;
return sdo_geometry (2003, 4326, null, sdo_elem_info_array (1,1003,1), t);
end;
/
show errors
User it like this:
update geomtest
set coord_geom = string_to_geom(coords);
commit;
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/314322.html
下一篇:Oraclesql-SP2-0552:系結變數“T_END”未宣告錯誤,但“T_START”很好,為什么?兩者都使用TO_DATE()
