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 位小数)上很有意义,你最好四舍五入或截断你的坐标。更简单的坐标导致更小的占用空间(数据库存储)和更快的性能。
我在两个特征 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 位小数)上很有意义,你最好四舍五入或截断你的坐标。更简单的坐标导致更小的占用空间(数据库存储)和更快的性能。