まず、ポリゴンの形式が正しくありません: 閉じません。多角形の場合、最後の点は最初の点と一致する必要があります。次のようにしてエラーを検出できます。
SQL> select sdo_geom.validate_geometry_with_context (SDO_GEOMETRY(2003, 8307, null, SDO_ELEM_INFO_ARRAY(1,1003,1),SDO_ORDINATE_ARRAY(10,10, 10,-10, -10,-10, -10,10)), 0.05) from dual;
13348 [Element <1>] [Ring <1>]
1 row selected.
ORA-13348: polygon boundary is not closed
それを修正すると、別のエラーが発生します。
SQL> select sdo_geom.validate_geometry_with_context (SDO_GEOMETRY(2003, 8307, null, SDO_ELEM_INFO_ARRAY(1,1003,1),SDO_ORDINATE_ARRAY(10,10, 10,-10, -10,-10, -10,10, 10,10)), 0.05) from dual;
13367 [Element <1>] [Ring <1>]
1 row selected.
ORA-13367: wrong orientation for interior/exterior rings
ポリゴンの場合、ポイントは反時計回りである必要があります。それを修正すると、ポリゴンは正しくなります。
SQL> select sdo_geom.validate_geometry_with_context (SDO_GEOMETRY(2003, 8307, null, SDO_ELEM_INFO_ARRAY(1,1003,1),SDO_ORDINATE_ARRAY(10,10, -10,10, -10,-10, 10,-10, 10,10)), 0.05) from dual;
TRUE
1 row selected.
また、クエリは適切に機能します。次に例を示します。
create table t1 (id number, note varchar2(20), geom sdo_geometry);
insert into t1 (id, note, geom)
values (
1,
'Not closed',
SDO_GEOMETRY(2003, 8307, null, SDO_ELEM_INFO_ARRAY(1,1003,1), SDO_ORDINATE_ARRAY(10,10, 10,-10, -10,-10, -10,10))
);
insert into t1 (id, note, geom)
values (
2,
'Wrong orientation',
SDO_GEOMETRY(2003, 8307, null, SDO_ELEM_INFO_ARRAY(1,1003,1), SDO_ORDINATE_ARRAY(10,10, 10,-10, -10,-10, -10,10, 10,10))
);
insert into t1 (id, note, geom)
values (
3,
'Valid',
SDO_GEOMETRY(2003, 8307, null, SDO_ELEM_INFO_ARRAY(1,1003,1), SDO_ORDINATE_ARRAY(10,10, -10,10, -10,-10, 10,-10, 10,10))
);
commit;
insert into user_sdo_geom_metadata (table_name, column_name, diminfo, srid)
values (
'T1',
'GEOM',
sdo_dim_array (
sdo_dim_element ('Long',-180,180,0.5),
sdo_dim_element ('Lat',-90,90,0.5)
),
8307
);
commit;
create index t1_sx on t1 (geom) indextype is mdsys.spatial_index;
テスト テーブルには、ポリゴンの 3 つのバリアントが含まれています。クエリを試してみましょう:
select *
from t1
where sdo_relate(
geom,
SDO_GEOMETRY('MULTIPOINT((0 0))',8307),
'mask=anyinteract'
) = 'TRUE';
これは正しい結果を返します:有効なポリゴンのみがポイントを含むものとして正しく識別されます:
ID NOTE GEOM(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)
---------- -------------------- -------------------------------------------------------------------------------
3 Valid SDO_GEOMETRY(2003, 8307, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1), SDO_ORDINATE_ARRAY(10, 10, -10, 10, -10, -10, 10, -10, 10, 10))
1 row selected.
point-in-polygon の ANYINTERACT と CONTAINS の違いについては、ポリゴンの境界上(より正確には境界の許容範囲内) にあるポイントに影響を与える可能性があります。ANYINTERACT 検索はそれらを返します。CONTAINS/INSIDE 検索はそうではありません。
これは、たとえばポイントをポリゴンに分散させたい場合 (販売地域の顧客ポイントの場所など) に重要であり、一部の顧客の場所のポイントが隣接する地域間の境界にある場合があります。ANYINTERACT 検索では、それらの場所が両方の地域にあることが報告されます。 . INSIDE 検索では、どちらにも含まれていないと報告されます。
最後に、クエリに簡単な構文を使用します。
select *
from t1
where sdo_anyinteract(
geom,
SDO_GEOMETRY('MULTIPOINT((0 0))',8307)
) = 'TRUE';
エラー コード (13348 など) に対応するメッセージを取得する方法に関する情報。私は通常、この手法を使用します。
set serveroutput on
exec dbms_output.put_line(sqlerrm(-13348))
これにより、完全なエラー メッセージが出力されます。マイナス記号を付けてエラーを渡す必要があることに注意してください。