2016-07-29 84 views
0

我有一個表有SDO_Geometries,我查詢所有的幾何來找到他們的開始和結束點,然後我將這些點插入到另一個名爲ORAHAN的表。現在我的主要目的是針對orahan中的每個點,當給予2cm緩衝點時,我必須找到它是否與orahan中的另一個點相交。 因此,我使用Relate和Bufer函數編寫了一些pl sql,但是當我檢查Map Info中的一些記錄時,我發現它本身在1釐米範圍內有點,但交叉點表中沒有記錄稱爲ORAHANCROSSES。 我是否錯誤地使用了這些函數?Oracle Spatial - SDO_BUFFER不起作用?

注:我使用的是Oracle數據庫11g企業版發佈11.2.0.1.0 - 64位的生產和 PL/SQL發佈11.2.0.1.0 - 和SDO_PACKAGE

ORAHAN大約有40萬條記錄(點等欄目。)

declare 
BEGIN 
for curs in (select * from ORAHAN t) loop 
    for curs2 in (select * 
        from ORAHAN t2 
        where SDO_RELATE(t2.geoloc,SDO_GEOM.SDO_BUFFER(curs.geoloc,0.02,0.5) , 
        'mask=ANYINTERACT') = 'TRUE' 
        and t2.mi_prinx <> curs.mi_prinx) loop      
    Insert INTO ORAHANCROSSES 
    values 
     (curs.Mip, curs.Startmi, curs2.Mip, curs2.Startmi); 
    commit; 
    end loop; 
end loop; 
END; 

這是MapInfo的地圖圖像,顯示3個點,其是彼此接近aproximately 1釐米。但在orahancrosses沒有記錄匹配這些3.

注:0,00001000km等於1釐米 enter image description here

Orahan元數據:

select * from user_sdo_geom_metadata where table_name = 'ORAHAN'; 

enter image description here

而且diminfo:

enter image description here

回答

1

什麼是您的數據的座標系統?而且,最重要的是,您在元數據中設置了哪些公差

一些其他意見:

1)不要使用帶緩衝的方式一涉及。只需使用距離內方法。

2)你並不需要那種查詢的PL/SQL循環只使用一個簡單CTAS:

create table orahancrosses as 
select c1.mip mip_1, c1.startmi startmi_1, c2.mip mip_2, c2.startmi startmi_2 
from orahan c1, orahan c2 
where sdo_wihin_distance (c2.geoloc, c1.geoloc, 'distance=2 unit=cm') = 'TRUE' 
and c2.mi_prinx <> c1.mi_prinx; 

3)寫的,點A和B的夫婦爲2 cm內將被返回兩次:一次爲(A,B),再次爲(B,A)。爲了避免這種情況(只有返回的情形之一),然後寫這樣的查詢:加工點的你提到400000+數(

create table orahancrosses as 
select c1.mip mip_1, c1.startmi startmi_1, c2.mip mip_2, c2.startmi startmi_2 
from orahan c1, orahan c2 
where sdo_wihin_distance (c2.geoloc, c1.geoloc, 'distance=2 unit=cm') = 'TRUE' 
and c1.rowid < c2.rowid; 

3))應該更好地運行使用SDO_JOIN技術,這樣:

create table orahancrosses as 
select c1.mip mip_1, c1.startmi startmi_1, c2.mip mip_2, c2.startmi startmi_2 
from table (
     sdo_join (
      'ORAHAN','GEOLOC', 
      'ORAHAN','GEOLOC', 
      'DISTANCE=2 UNIT=CM' 
     ) 
    ) j, 
     orahan c1, 
     orahan c2 
where j.rowid1 < j.rowid2 
and c1.rowid = j.rowid1 
and c2.rowid = j.rowid2; 

這可能仍然需要時間來處理 - 這取決於數據庫服務器的容量。如果您是Oracle Enterprise Edition的許可證,並且您的硬件具有適當的容量(核心數量),那麼並行性可以減少流逝的時間。

4)你說你正在使用Oracle 11g。什麼確切的版本?版本11.2.0.4是11gR2的終端版本。任何舊的不再支持。現在你應該真的在12cR1(12.1.0.2)上。 12.1.0的主要好處。2在你的案例中,Vector Performance Accelerator功能可以加速大量空間函數和操作符(只有當你擁有合適的Oracle Spatial許可證時 - 它不具備免費的Oracle Locator功能)。

======================================

使用兩個點在你的例子中。讓我們來計算距離:

select sdo_geom.sdo_distance(
    sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.08336913,null),null,null), 
    sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.07336716,null),null,null), 
    0.005 
) distance 
from dual; 


    DISTANCE 
---------- 
.01000197 

1 row selected. 

注意我沒有指定任何SRID。假設座標用米表示,它們之間的距離確實稍大於1釐米。

======================================

之所以你正如您注意到的,原始語法不起作用是因爲您爲SDO_BUFFER()調用指定的容差。您將其作爲0.5(= 50釐米)傳遞以生成半徑爲0.02(2釐米)的緩衝區。其效果是生成的緩衝區有效地溶解到點本身。

例如在公差0.5:

select sdo_geom.sdo_buffer(sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.08336913,null),null,null),0.02,0.5) from dual; 

產地:

SDO_GEOMETRY(2001, NULL, SDO_POINT_TYPE(521554.782, 4230983.08, NULL), NULL, NULL) 

在公差0.005:

select sdo_geom.sdo_buffer(sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.08336913,null),null,null),0.02,0.005) from dual; 

得到適當的緩衝:

SDO_GEOMETRY(2003, NULL, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 2), SDO_ORDINATE_ARRAY(521554.782, 4230983.06, 521554.802, 4230983.08, 521554.782, 4230983.1, 521554.762, 4230983.08, 521554.782, 4230983.06)) 

而且非常接近點現在與該緩衝區匹配:

select sdo_geom.relate(
    sdo_geom.sdo_buffer(sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.08336913,null),null,null),0.02,0.005), 
    'determine', 
    sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.07336716,null),null,null), 
    0.005 
) relation 
from dual; 

RELATION 
------------------------- 
CONTAINS 

1 row selected. 

============================= =========

現在,您的數據沒有正確的顯式SRID,這意味着在測量或基於距離的搜索中使用顯式單位將不起作用。由於數據庫不知道數據所在的座標系,因此它不知道如何確定兩個點的距離小於設定的釐米或米數。你所能做的就是假設座標以米爲單位。

所以在我給上面的例子中,與'DISTANCE=0.02'

+0

更換'DISTANCE=2 UNIT=CM'我的工作,使用Oracle 11gR2的一些項目的公司。奧拉漢擁有大約40萬條記錄(行)。我將盡快編輯我的問題並在元數據中添加容差值。 –

+0

如果公司使用11gR2並且有適當的系統管理員和DBA,那麼他們可能已經在11.2.0.4上。儘管如此,在這個版本以及您需要處理的數據量方面,SDO_JOIN方法絕對是最佳選擇(我在回覆中添加了語法)。這與Vector Performance Accelerator功能在12c中會有所不同。 –

+0

我試着說,SDO_JOIN方法,速度非常快。它在2分鐘內完成了工作。感謝那。但問題依然存在。它沒有找到相交點,而有些點彼此之間的距離爲1釐米。我想我的專欄的diminfo是錯誤的。 –