sdo_relate 给出错误的查询结果

sdo_relate giving a wrong query result

我在两个特征 class 中有两个几何图形,一个名为 "HY90299 ",另一个名为 "hyboxsdo ",这两个几何图形不相交。

但是当我 运行 在 oralce 中进行空间查询时,

"select sdo_relate(t.shape,g.shape ,'mask=ANYINTERACT') from HY90299 t,hyboxsdo g " ,

它 return "true",结果不正确。我做错了吗?

我的oracle版本是11g

you can get the two geometry by 

1.i put the  two geometry into two shape file . you can get them from here
https://pan.baidu.com/s/1YQnwe8nstzgHOAwHgx9JGQ

2.or create the two geometry  by wkt
①MULTIPOLYGON (((-16.657423019000021 82.843477248999989, 16.710901260000014 66.242341995000004, 74.611375808999981 57.038061142000004, 111.18630027799998 67.126588820999984, -16.657423019000021 82.843477248999989)))
②MULTIPOLYGON (((60.839999999999975 26.569999999999993, 143.45000000000005 26.569999999999993, 143.45000000000005 55.75, 60.839999999999975 55.75, 60.839999999999975 26.569999999999993)))

附加

1.select * from user_sdo_geom_metadata where table_name='HY90299'

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

return "HY90299    SHAPE     {{null,-180,180,0.001},{null,-90,90,0.001}}    4326"



2.select sdo_geom.validate_geometry_with_context(c.shape,0.000000005) from  hy90299 c
   select sdo_geom.validate_geometry_with_context(c.shape,0.001) from hy90299 c

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

all return  "true"



3.select shape from hy90299

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

return "{2003,4326,null,{1,1003,1},{111.186300278,67.126588821,-16.657423019,82.843477249,16.71090126,66.242341995,74.611375809,57.038061142,111.186300278,67.126588821}}"



4.select sdo_geom.relate(t.shape,'determine',sdo_geometry(2003,4326,null, SDO_ELEM_INFO_ARRAY(1,1003,3),SDO_ORDINATE_ARRAY(60.840,26.570,143.450,55.750)),0.000000005) as spat_rel from HY90299 t

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

return "DISJOINT"



5.select sdo_geom.relate(t.shape,'determine',sdo_geometry(2003,4326,null, SDO_ELEM_INFO_ARRAY(1,1003,1),SDO_ORDINATE_ARRAY(60.840,26.570, 143.450,26.570, 143.450,55.750,60.840,55.750,60.840, 26.570)),0.000000005) as spat_rel from HY90299 t

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

return "OVERLAPBDYINTERSECT"

来自手册 (https://docs.oracle.com/cd/B28359_01/appdev.111/b28400/sdo_operat.htm#SPATL1039),空间 operators "must always be used in a WHERE clause",不在查询的 SELECT 部分。

要使用它们(如前所述,在 WHERE 子句中),它们必须具有空间索引。

如果您想查看空间关系,可以使用空间 函数之一 - 例如:

select t.*,g.*, sdo_geom.relate(t.shape,'determine',g.shape,0.000000005) as spat_rel
from HY90299 t, hyboxsdo g

如果需要,您也可以将函数添加到 WHERE 语句中,以过滤结果 - 例如在上面的代码段中添加:

where sdo_geom.relate(t.shape,'determine',g.shape,0.000000005) not in ('TOUCH','DISJOINT')

对于一些几何图形,你会没事的。随着几何图形数量的增加,您必须使用空间索引并在 WHERE 子句中添加运算符,或者使用另一种方式来过滤行(例如通过属性、id 等)——空间函数不能很好地扩展。

您还有责任选择适合您的数据和查询的 TOLERANCE 值(我选择 0.000000005,因为您的形状似乎有 8 位有效小数)。

最后但并非最不重要的一点是,您需要确保您的几何图形有效(同样,在适当的公差范围内)。

HTH

追加:
1)

with HY90299 as (
  select sdo_util.from_wktgeometry( 
  'MULTIPOLYGON (((-16.657423019000021 82.843477248999989, 16.710901260000014 66.242341995000004, 74.611375808999981 57.038061142000004, 111.18630027799998 67.126588820999984, -16.657423019000021 82.843477248999989)))'
  ) shape from dual ), 
HYBOXSDO as (
  select sdo_util.from_wktgeometry( 
  'MULTIPOLYGON (((60.839999999999975 26.569999999999993, 143.45000000000005 26.569999999999993, 143.45000000000005 55.75, 60.839999999999975 55.75, 60.839999999999975 26.569999999999993)))'
  ) shape  from dual )
select sdo_geom.relate(t.shape,'determine',g.shape,0.000000005)
from HY90299 t,hyboxsdo g ;

结果是 DISJOINT - 还有:

with HY90299 as (
select sdo_geometry(2003,4326,null, SDO_ELEM_INFO_ARRAY(1,1003,1),SDO_ORDINATE_ARRAY(-16.657423019000021, 82.843477248999989, 16.710901260000014, 66.242341995000004, 74.611375808999981, 57.038061142000004, 111.18630027799998, 67.126588820999984, -16.657423019000021, 82.843477248999989))
 shape from dual )
select sdo_geom.relate(t.shape,'determine',
sdo_geometry(2003,4326,null, SDO_ELEM_INFO_ARRAY(1,1003,3),SDO_ORDINATE_ARRAY(60.840,26.570,143.450,55.750))
,0.000000005) as spat_rel from HY90299 t

结果还是 DISJOINT。
你的 'overlapbdyintersect' 不应该在那里 - 检查你的 tables 的内容(因为你的两个查询的不同是 'window' 几何,仔细检查 hyboxsdo table) .
2)你错了。宽容 必不可少的。如果您在上述查询中使用 sdo_geom.relate(t.shape,'determine',g.shape,2) - 即 2 米的公差 -,您将获得 TOUCH 而不是 DISJOINT(由此,您还可以看出您的几何图形相距大约 2m)。但是,对于这两个几何图形,您永远不会重叠。
3) 几何的有效性与您使用的公差直接相关。您的几何图形 有效的(小数点后 8 位)- 我只是说如果您不认为它是理所当然的,它会为您省去很多麻烦。永远不要假设 - 检查!
4) 如何 将几何图形放入 table 并不重要。您 可能 唯一想考虑的(尤其是在生产环境中)是存储在数据库中的小数位数——如果您的数据在精确度(例如 3 位小数)上很有意义,你最好四舍五入或截断你的坐标。更简单的坐标导致更小的占用空间(数据库存储)和更快的性能。