1

SDO_Geometry を含むテーブルがあり、すべてのジオメトリをクエリして始点と終点を見つけてから、これらの点を ORAHAN という別のテーブルに挿入します。私の主な目的は、オラハンの各ポイントについて、ポイントに 2 cm のバッファーを与えるときに、オラハンの別のポイントと交差するかどうかを確認することです。Relate 関数と Buffer 関数を使用していくつかの pl sql を作成しましたが、Map Info でいくつかのレコードを確認すると、それ自体から 1 cm の領域内にポイントがあることがわかりましたが、ORAHANCROSSES と呼ばれる交差テーブルにはレコードがありませんでした。これらの機能を間違って使用していますか、それとも何ですか?

注:私は、Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production および PL/SQL Release 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;

そして、これは互いに約 1 cm の距離にある 3 つのポイントを示す MapInfo マップ イメージです。しかし、オラハンクロスでは、これら3つに一致する記録はありません。

注: 0,00001000km は 1cm に等しい ここに画像の説明を入力

オラハン メタデータ:

select * from user_sdo_geom_metadata where table_name = 'ORAHAN';

ここに画像の説明を入力

そして薄暗い情報:

ここに画像の説明を入力

4

1 に答える 1

3

データの座標系は何ですか? そして、最も重要なことは、メタデータにどの程度の許容範囲を設定したか?

その他のコメント:

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_within_distance (c2.geoloc, c1.geoloc, 'distance=2 unit=cm') = 'TRUE'
and c2.mi_prinx <> c1.mi_prinx;

3) 書かれているように、2 cm 以内にあるポイント A と B のペアは 2 回返されます: 1 回は (A,B) として、もう 1 回は (B,A) として返されます。それを回避する (そしていずれかのケースのみを返す) には、次のようにクエリを記述します。

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_within_distance (c2.geoloc, c1.geoloc, 'distance=2 unit=cm') = 'TRUE'
and c1.rowid < c2.rowid;

3) あなたが言及したポイント数 (400000+) の処理は、次のように 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 機能では利用できません)。

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

あなたの例で2つのポイントを使用してください。距離を計算しましょう:

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 cm 強です。

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

お気づきのように、元の構文が機能しない理由は、SDO_BUFFER() 呼び出しに指定した許容誤差のためです。0.5 (=50cm) として渡すと、半径 0.02 (2cm) のバッファーが生成されます。その効果は、生成されたバッファーがポイント自体に効果的に溶解することです。

たとえば、公差 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 がないという事実は、測定または距離ベースの検索で明示的な単位を使用できないことを意味します。データベースはデータがどの座標系にあるかを認識していないため、2 つの点が設定された cm または m の間隔よりも小さいかどうかを判断する方法がわかりません。できることは、座標がメートル単位であると想定することだけです。

したがって、上記の例では、次のように置き換え'DISTANCE=2 UNIT=CM'ます'DISTANCE=0.02'

于 2016-07-31T21:14:03.357 に答える