20.16 SDO_POINTINPOLYGON

書式

SDO_POINTINPOLYGON(cur, geom_obj, tol, params) RETURN ANYDATASET;

説明

一連の行をとり、指定されたポリゴン・ジオメトリ内のこれらの行を戻します。

キーワードおよびパラメータ

説明

cur

次のうちの1つ。

  • REFカーソル: ref_cursorのSQLのSELECTにある最初の2列は、ユーザー表のX点座標とY点座標である必要があります。その2列はNUMBER型である必要があります。(その他の列は、数値型、文字型および日付型の場合があります)。データ型はSYS_REFCURSORです。

  • REFカーソル: refカーソルのSQLのSELECTにある最初の列は、ユーザー表の空間ジオメトリ・オブジェクトである必要があります。列はSDO_GEOMETRY型である必要があります。(その他の列は、数値型、文字型および日付型の場合があります)。データ型はSYS_REFCURSORです。

geom_obj

空間ジオメトリ・オブジェクト: 表のジオメトリか、ジオメトリの一時的なインスタンスのどちらかで、curから選択されたすべての点に対してチェックされます。データ型はSDO_GEOMETRYです。

tol

許容差(「許容差」を参照)。0.0より大きい値を指定する必要があります。データ型はNUMBERです。

params

キーワードと値を指定する、オプションのパラメータ文字列です。演算子の処理を指定します。使用可能なキーワードについては、「使用上のノート」の表20-5を参照してください。データ型はVARCHAR2です。デフォルトはNULLです。

戻り値

SDO_POINTINPOLYGONは、ANYDATASET TYPEのオブジェクトを戻します(Oracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照)。ANYDATASETの出力列は、curパラメータで指定されたものになります。

使用上のノート

厳密には、SDO_POINTINPOLYGONは演算子ではなくテーブル・ファンクションです。(テーブル・ファンクションについては、『Oracle Database PL/SQL言語リファレンス』を参照してください。)ただし、使用方法が演算子に類似し、他のファンクションおよびプロシージャと同じパッケージに同梱されていないため、空間演算子の章で説明しています。

curパラメータで使用されるSQL文では、WHERE句に任意の数の条件を指定できます。結果の行をSDO_POINTINPOLYGON演算子に渡す前に、この機能を使用して他の属性でデータをフィルタできます。

出力列は入力列と同一ですが、戻された行のみが選択基準に一致したものになります。

表20-5に、paramsパラメータのキーワードを示します。

20-5 SDO_POINTINPOLYGON演算子のparamsキーワード

キーワード 説明

mask

対象の位相関係。有効な値は、'mask=<value>'です(<value>は、TOUCHOVERLAPBDYDISJOINTOVERLAPBDYINTERSECTEQUALINSIDECOVEREDBYCONTAINSCOVERSANYINTERACTONの1つ以上の組合せです)。たとえば'mask=inside+touch'のように、複数のマスクが論理Boolean演算子ORで結合されます。9つの交差関係パターンについては、「空間関係およびフィルタ処理」を参照してください。

curが点のX座標とY座標のペアである場合、TOUCHおよびONはシノニムです。

このパラメータがNULLであるか、または空の文字列を含む場合、mask=ANYINTERACTであるとみなされます。

sdo_batch_size

バッチで処理される最大行数を指定します。デフォルト値は4000で、最大値は32768です。データ型はNUMBERです。

たとえば: 'sdo_batch_size=5000'

パラレル問合せサーバーを使用するには、次のいずれかを実行します。

  • /*+ PARALLEL(<table alias>, <n>) */オプティマイザ・ヒントを指定します。<table_alias>は、指定された表の別名で、<n>は並列度です。

  • 適切な権限のアカウントで次のコマンドを入力し、パラレル問合せの実行を有効にします。

    ALTER SESSION FORCE PARALLEL QUERY;

次の例では、COLA_MARKETS表のデータに基づいて、COLA_MARKET_POINTSという新しい表を作成します(「空間データの挿入、索引付けおよび問合せの例」を参照)。次に、MKT_ID列の値が1より大きい各ジオメトリ内の点を選択します。(SDO_UTIL.INTERIOR_POINTファンクションを使用して、問合せ条件に一致する各ジオメトリ内に存在する点を取得します。)

-- Create a new table with a different name based on the data from the 
-- COLA_MARKETS table. This table has four columns: X, Y, MKT_ID, and NAME.
 
CREATE TABLE cola_market_points AS
SELECT a.point.sdo_point.x X, a.point.sdo_point.y Y, MKT_ID, NAME
 FROM (
SELECT mkt_id, name, sdo_util.interior_point(shape) point FROM cola_markets) a;

-- Limit to MKT_ID > 1. Also, use the PARALLEL hint.
SELECT /*+ PARALLEL(a, 4) */ *
FROM TABLE(sdo_PointInPolygon(
  CURSOR(select * from cola_market_points where mkt_id > 1),
  SDO_GEOMETRY(
    2003,
    NULL,
    NULL,
    MDSYS.SDO_ELEM_INFO_ARRAY(1, 1003, 1),
    MDSYS.SDO_ORDINATE_ARRAY(1, 1, 8, 1, 8, 6, 5, 7, 1, 1)),
  0.05)) a;
 
         X          Y     MKT_ID NAME                                           
---------- ---------- ---------- --------------------------------               
    6.3125      2.875          2 cola_b                                         
    4.6875      3.875          3 cola_c

次の例では、前の例と同じSDO_POINTINPOLYGON問合せを実行しますが、COLA_MARKET_POINTS表を作成する必要はなく、MKT_ID列値が1より大きい行ごとに、X座標とY座標のペアではなく、点ジオメトリが戻されます。(出力は、簡単に読むことができるように、再フォーマットされています。)

-- Limit to MKT_ID > 1. Also, use the PARALLEL hint. 
SELECT /*+ PARALLEL(a, 4) */ name, mkt_id, point
FROM TABLE(sdo_PointInPolygon(
  CURSOR(select sdo_util.interior_point(shape) point, mkt_id, name 
         from cola_markets where mkt_id > 1),
SDO_GEOMETRY
  2003,
  NULL,
  NULL,
  MDSYS.SDO_ELEM_INFO_ARRAY(1, 1003, 1),
  MDSYS.SDO_ORDINATE_ARRAY(1, 1, 8, 1, 8, 6, 5, 7, 1, 1)),  0.05)) a;

NAME   MKT_ID  POINT(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)
------ ------- ----------------------------------------------------------------------------
cola_b   2     SDO_GEOMETRY(2001, NULL, SDO_POINT_TYPE(6.3125, 2.875, NULL), NULL, NULL)
cola_c   3     SDO_GEOMETRY(2001, NULL, SDO_POINT_TYPE(4.6875, 3.875, NULL), NULL, NULL)

次の例はWHERE句でバインド変数を使用して、params文字列を指定します。PIP_DATAという名前の表が存在すると想定しています。

DECLARE
 my_cursor SYS_REFCURSOR;
 my_pip_cursor SYS_REFCURSOR;
 stmt varchar2(2000);
 cnt number;
BEGIN
  stmt := 'SELECT count(*) FROM ' ||
          ' TABLE (Sdo_PointInPolygon(' ||
          'CURSOR(select * from pip_data where x < :x1),' ||
          ' :g1, :tol, ''mask=DISJOINT sdo_batch_size=6000'')) ';
 open my_cursor for stmt
 using 100, -- :x1
       SDO_GEOMETRY( 2003, NULL, NULL,
              SDO_ELEM_INFO_ARRAY(1, 1003, 1),
              SDO_ORDINATE_ARRAY(10, 10, 70,10, 70, 70, 50,70,
                                 40,50, 20,70, 10,70, 10,10)), -- :g1
       0.05; -- :tol
 FETCH my_cursor into cnt;
 dbms_output.put_line(to_char(cnt));
END;
/

関連トピック