Oracle SDO_INSIDE返回零记录
所以我有一个桌子村:Oracle SDO_INSIDE返回零记录,oracle,oracle-spatial,Oracle,Oracle Spatial,所以我有一个桌子村: CREATE TABLE village ( building_id integer PRIMARY KEY, name VARCHAR2(30), visitors integer, building SDO_GEOMETRY ); 和一桌访客: create table visitors( id integer, position SDO_GEOMETRY ); 以下是插页: INSERT INTO village VALUES(2,'Ki
CREATE TABLE village (
building_id integer PRIMARY KEY,
name VARCHAR2(30),
visitors integer,
building SDO_GEOMETRY
);
和一桌访客:
create table visitors(
id integer,
position SDO_GEOMETRY
);
以下是插页:
INSERT INTO village VALUES(2,'KircheV2', 4,
SDO_GEOMETRY(
2003,
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,1),
SDO_ORDINATE_ARRAY(100,100, 100,120, 120,100, 120,120)
)
);
INSERT INTO visitors VALUES (1,
SDO_GEOMETRY(
2001,
NULL,
SDO_POINT_TYPE(110, 110, NULL),
NULL,
NULL
)
);
出于某种原因,当我试图获取“KircheV2”中的所有访问者时,SQL语句总是返回零记录:
SELECT * FROM visitors,village WHERE village.name like 'KircheV2' and (SDO_INSIDE(village.building,visitors.POSITION) = 'TRUE');
背后的原因是什么?坐标110;110应该是正确的在建筑物的中间,所以它应该在建筑物内。 < P>你的数据是不正确的。您可以这样验证它:
SQL> select sdo_geom.validate_geometry_with_context (building,0.005) from village;
SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT(BUILDING,0.005)
-------------------------------------------------------------------------------
13348 [Element <1>] [Ring <1>]
1 row selected.
SELECT * FROM visitors,village WHERE village.name like 'KircheV2' and SDO_INSIDE(visitors.POSITION,village.building) = 'TRUE';
SELECT * FROM visitors,village WHERE village.name like 'KircheV2' and SDO_CONTAINS(village.building,visitors.POSITION) = 'TRUE';
在Oracle(实际上是所有存储系统)中,根据OGC规则,多边形必须闭合,即第一个顶点必须与最后一个顶点重复。因此:
INSERT INTO village VALUES(2,'KircheV2', 4,
SDO_GEOMETRY(
2003,
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,1),
SDO_ORDINATE_ARRAY(100,100, 100,120, 120,100, 120,120, 100,100)
)
);
但是select仍然无法返回任何结果。为什么呢
SQL> select sdo_geom.validate_geometry_with_context (building,0.005) from village;
SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT(BUILDING,0.005)
-------------------------------------------------------------------------------
13349 [Element <1>] [Ring <1>][Edge <2>][Edge <4>]
1 row selected.
这很有意义:顶点明显形成蝴蝶形状:
100100120120100120120120120100100
假设您想要形成一个简单的矩形,那么合适的形状是:
100100120120120100100
仍然没有结果。为什么?
SQL> select sdo_geom.validate_geometry_with_context (building,0.005) from village;
SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT(BUILDING,0.005)
-------------------------------------------------------------------------------
13367 [Element <1>] [Ring <1>]
1 row selected.
多边形中的环必须正确定向。外圈必须为逆时针方向,内圈(孔)必须为顺时针方向。所以你需要这样写:
SQL> select sdo_geom.validate_geometry_with_context (building,0.005) from village;
SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT(BUILDING,0.005)
-------------------------------------------------------------------------------
13348 [Element <1>] [Ring <1>]
1 row selected.
SELECT * FROM visitors,village WHERE village.name like 'KircheV2' and SDO_INSIDE(visitors.POSITION,village.building) = 'TRUE';
SELECT * FROM visitors,village WHERE village.name like 'KircheV2' and SDO_CONTAINS(village.building,visitors.POSITION) = 'TRUE';
100100120100120120100120100120100100
还是没有结果!但这是因为您的查询格式不正确<代码>SDO_INSIDE(a,b)查找完全位于b内的a的所有实例。在您的情况下,这就像询问访客内部的建筑物一样。很明显,您想要的是相反的,所以可以说:SDO\u内部(访客,建筑)
或SDO\u包含(建筑,访客)
,如下所示:
SQL> select sdo_geom.validate_geometry_with_context (building,0.005) from village;
SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT(BUILDING,0.005)
-------------------------------------------------------------------------------
13348 [Element <1>] [Ring <1>]
1 row selected.
SELECT * FROM visitors,village WHERE village.name like 'KircheV2' and SDO_INSIDE(visitors.POSITION,village.building) = 'TRUE';
SELECT * FROM visitors,village WHERE village.name like 'KircheV2' and SDO_CONTAINS(village.building,visitors.POSITION) = 'TRUE';
一些补充意见:
sdo\u util.correct\u geometry
功能将纠正基本错误F(a,b)
这样的操作符中,b
用于搜索a
,因此b
应该是较小的集合。例如,查找此建筑物中的所有访客必须写为SDO\u in(访客,建筑物)
。相反(该客户在哪栋建筑?)写为SDO\u包含(建筑、访客)
请更新您的标签。它不是MySQL就是Oracle。当我执行查询时,我得到这个错误:13226。00000-“不支持没有空间索引的接口”是的。这意味着为了应用空间谓词,必须在搜索的表上使用空间索引。在12.2版本之前,这是一个严格的要求:12.2版本的空间索引已成为可选的,但除非您处理的是小型数据集(100或更少)的简单数据,否则您需要一个空间索引才能获得良好的性能。
SELECT * FROM visitors,village WHERE village.name like 'KircheV2' and SDO_INSIDE(visitors.POSITION,village.building) = 'TRUE';
SELECT * FROM visitors,village WHERE village.name like 'KircheV2' and SDO_CONTAINS(village.building,visitors.POSITION) = 'TRUE';