我正在使用SDO_NN操作员找到建筑物旁边最近的消防栓。
大厦:
CREATE TABLE "BUILDINGS"
(
"NAME" VARCHAR2(40),
"SHAPE" "SDO_GEOMETRY")
消防栓:
CREATE TABLE "HYDRANTS"
( "NAME" VARCHAR2(10),
"POINT" "SDO_POINT_TYPE"
);
我已经为buildings.shape正确设置了空间索引,我运行查询以获取最近的建筑物'汽车旅馆'消防栓
select b1.name as name, h.point.x as x, h.point.y as y from buildings b1, hydrants h where b1.name ='Motel' and
SDO_nn( b1.shape, MDSYS.SDO_GEOMETRY(2003,NULL, NULL,SDO_ELEM_INFO_ARRAY(1,1003,1),
SDO_ORDINATE_ARRAY( h.point.x,h.point.y)), 'sdo_num_res=1')= 'TRUE';
问题在于:
当我设置参数 sdo_num_res = 1 时,我得到零元组。 当我使sdo_num_res = 2时,我得到一个元组。
这种怪异行为的原因是什么?
注意:我只在building.name ='Motel'时获得零行,对于所有其他元组,当sdo_num_res = 1时,我得到1行
编辑: 插入查询
Insert into buildings (NAME,SHAPE) values ('Motel',MDSYS.SDO_GEOMETRY(2003,NULL,NULL,MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,1),MDSYS.SDO_ORDINATE_ARRAY(564,425,585,436,573,458,552,447)));
Insert into hydrants (name,POINT) values ('p57',MDSYS.SDO_POINT_TYPE(589,448,0));
答案 0 :(得分:0)
要在点到多边形之间执行空间比较,SDO_GEOMETRY
定义为SDO_SRID=2001
,中心设置为SDO_POINT_TYPE->
我们要比较。
MDSYS.SDO_GEOMETRY(2001, NULL, SDO_POINT_TYPE(-79, 37, NULL), NULL, NULL)
答案 1 :(得分:0)
首先,您的查询不会按照您的说法执行操作:它实际上会返回最近的建筑,名为" Motel"从你的任何消防栓。要做你想做的事情(即相反)你需要颠倒SDO_NN的参数顺序:所有空间运算符使用第二个参数的值搜索第一个参数。
然后插入HYDRANTS表是错误的:
Insert into hydrants (name,POINT) values ('p57',MDSYS.SDO_POINT_TYPE(589,448,0));
SDO_POINT_TYPE对象不是以这种方式使用的:它仅在SDO_GEOMETRY类型中使用。正确的方法是:
insert into hydrants (name,POINT) values ('p57',sdo_geometry(2001, null, SDO_POINT_TYPE(589,448,null), null, null));
当然,您需要相应地更改表格定义。
然后您的建筑物也被错误地创建:多边形必须始终关闭,即最后一个点必须与第一个点相同。所以正确的形状应该是这样的:
insert into buildings (NAME,SHAPE) values ('Motel', SDO_GEOMETRY(2003,NULL,NULL,SDO_ELEM_INFO_ARRAY(1,1003,1),SDO_ORDINATE_ARRAY(564,425,585,436,573,458,552,447,564,425)));
以下是完整示例:
创建表格:
create table buildings (
name varchar2(40) primary key,
shape sdo_geometry
);
create table hydrants(
name varchar2(10) primary key,
point sdo_geometry
);
填充表格:
insert into buildings (NAME,SHAPE) values ('Motel', SDO_GEOMETRY(2003,NULL,NULL,SDO_ELEM_INFO_ARRAY(1,1003,1),SDO_ORDINATE_ARRAY(564,425,585,436,573,458,552,447,564,425)));
insert into hydrants (name,POINT) values ('p57',sdo_geometry(2001, null, SDO_POINT_TYPE(589,448,null), null, null));
commit;
确认几何图形都正确无误:
select name, sdo_geom.validate_geometry_with_context (point, 0.05) from hydrants;
select name, sdo_geom.validate_geometry_with_context (shape, 0.05) from buildings;
设置空间元数据并创建空间索引:
insert into user_sdo_geom_metadata (table_name, column_name, diminfo, srid)
values (
'BUILDINGS',
'SHAPE',
sdo_dim_array (
sdo_dim_element ('X', 0,1000,0.05),
sdo_dim_element ('Y', 0,1000,0.05)
),
null
);
commit;
create index buildings_sx on buildings (shape)
indextype is mdsys.spatial_index;
insert into user_sdo_geom_metadata (table_name, column_name, diminfo, srid)
values (
'HYDRANTS',
'POINT',
sdo_dim_array (
sdo_dim_element ('X', 0,1000,0.05),
sdo_dim_element ('Y', 0,1000,0.05)
),
null
);
commit;
create index hydrants_sx on hydrants (point)
indextype is mdsys.spatial_index;
现在尝试正确编写的查询:
select h.name, h.point.sdo_point.x as x, h.point.sdo_point.y as y
from buildings b, hydrants h
where b.name ='Motel'
and sdo_nn(h.point, b.shape, 'sdo_num_res=1')= 'TRUE';
返回:
NAME X Y
---------------- ---------- ----------
p57 589 448
1 row selected.