Oracle Spatial and Graph介绍(2)--空间索引及空间运算

本文主要介绍 Oracle 空间索引的使用以及在处理空间对象数据类型时可以使用的运算符。

1、空间索引

1.1、创建空间索引

空间索引需要在类型为 SDO_GEOMETRY 的列上创建,语法如下:

CREATE INDEX [schema.]index ON [schema.]table (column)
INDEXTYPE IS MDSYS.SPATIAL_INDEX_V2
[PARAMETERS ('index_params [physical_storage_params]' )]
[{ NOPARALLEL | PARALLEL [ integer ] }];

关键字和参数:

说明
INDEX_PARAMS 确定空间索引的特性。
layer_gtype 几何类型,SDO_GTYPE 的英文名称,如:POINT。
sdo_dml_batch_size 在提交操作后,每批次处理的索引更新数量;默认值为 4000。
sdo_indx_dims 指定要索引的维度数量,必须小于或等于实际维度的数量;默认值为 2。
sdo_max_memory 指定用于执行空间索引构建或重建操作的最大内存量,范围为 64000 到 200000000,默认值为 10000000。
sdo_non_leaf_tbl TRUE 表示除了为索引的叶子节点创建一个索引表(表名为 MDRT_...)外,还为非叶节点创建一个单独的索引表(表名为 MDNT...);FALSE表示为索引的叶节点和非叶节点创建一个单一的表(表名形式为 MDRT_...$)。默认值为 FALSE。
sdo_rtr_pctfree 指定在创建索引时,每个索引树节点中留空的最小百分比。留空的插槽可以在以后插入新数据时填充。该值范围从 0 到 50。默认值为 10。
sequence_initial 指定在索引创建过程中,Spatial 和 Graph 内部使用的 '初始' 序列缓存值。如果预期空间数据集的大小将显著增加,可以通过增大 sequence_initial 值来提高 DML 操作的运行时性能。默认值为 100。
sequence_next 指定在索引创建后,Spatial 和 Graph 内部使用的 '下一个' 序列缓存值。如果预计会频繁添加大量空间数据,可以通过增大 sequence_next 值来提高 DML 操作的运行时性能。默认值为 100。
PHYSICAL_STORAGE_PARAMS 确定用于创建空间索引数据表的存储参数。
tablespace 指定表空间
initial 与 CREATE TABLE 语句的 STORAGE 子句中的 INITIAL 意思相同。
next 与 CREATE TABLE 语句的 STORAGE 子句中的 NEXT 意思相同。
minextents 与 CREATE TABLE 语句的 STORAGE 子句中的 MINEXTENTS 意思相同。
maxextents 与 CREATE TABLE 语句的 STORAGE 子句中的 MAXEXTENTS 意思相同。
pctincrease 与 CREATE TABLE 语句的 STORAGE 子句中的 PCTINCREASE 意思相同。
work_tablespace 指定用于创建索引的临时表的表空间。(仅适用于创建空间 R 树索引,而不适用于其他类型的索引。)指定工作表空间可以减少索引表空间中的碎片,但它需要的存储空间是最终索引大小的两倍;然而,在索引创建后,您可以删除或重新使用工作表空间。
securefile 是否启用 SecureFiles 智能压缩;默认值为 FALSE。
compression compression=<OFF|LOW|MEDIUM|HIGH> 控制空间索引节点的压缩级别。要指定 OFF 以外的任何值,必须同时指定 securefile=TRUE,并且必须拥有 Oracle 高级压缩选项的许可证并实现 SecureFiles 智能压缩。默认值为 OFF。
{ NOPARALLEL | PARALLEL [ integer ] } 控制在创建索引以及后续查询和 DML 操作中使用串行(NOPARALLEL)执行还是并行(PARALLEL)执行。对于并行执行,可以指定一个整数值作为并行度。默认值为 NOPARALLEL。(如果指定了 PARALLEL 而没有设置并行度,Oracle 数据库将计算最佳的并行度。)

要确定空间索引是否有效,需检查 USER_INDEXES 视图中的 DOMIDX_OPSTATUS 列是否为 FAILED。这与常规索引的情况不同,常规索引需要检查 USER_INDEXES 视图中的 STATUS 列是否为 FAILED。

创建索引例子:

--创建样例表
create table a_school(
  school_name varchar(64),
  address varchar2(64),
  position SDO_GEOMETRY
);

--插入元数据
insert into USER_SDO_GEOM_METADATA 
values('A_SCHOOL','POSITION',MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X', -180, 180, 0.005), MDSYS.SDO_DIM_ELEMENT('Y', -90, 90, 0.005)),8307);

--创建索引
create index idx_a_school_position on a_school(position) 
INDEXTYPE IS MDSYS.SPATIAL_INDEX_V2
PARAMETERS ('layer_gtype=POINT')

1.2、删除空间索引

DROP INDEX [schema.]index [FORCE];

删除索引例子:

drop index idx_a_school_position force;

2、空间运算

2.1、SDO_ANYINTERACT

检查两个几何图形是否具有 ANYINTERACT 拓扑关系;相当于使用 SDO_RELATE 操作符并指定 'mask=ANYINTERACT'。检查两个几何对象是否存在任何形式的交互,不论是交点、交线还是交区域。用法:

SDO_ANYINTERACT(geometry1, geometry2);

例子:

select SDO_ANYINTERACT(SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(2,2, 4,4)
),
SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(4,4, 8,8)
)) from dual --TRUE

2.2、SDO_CONTAINS

检查两个几何图形是否具有 CONTAINS 拓扑关系;相当于使用 SDO_RELATE 操作符并指定 'mask=CONTAINS'。几何 A 完全包含几何 B 的所有点,且 B 的边界不能接触 A 的边界;如:岛屿在海洋内部。用法:

SDO_CONTAINS(geometry1, geometry2);

例子:

select SDO_CONTAINS(SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(2,2, 8.1,8.1)
),
SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(4,4, 8,8)
)) from dual --TRUE

2.3、SDO_COVEREDBY

检查两个几何图形是否具有 COVEREDBY 拓扑关系;相当于使用 SDO_RELATE 操作符并指定 'mask=COVEREDBY'。几何 B 完全覆盖几何 A,边界至少有一个点重叠;如:行政区划精确覆盖。用法:

SDO_COVEREDBY(geometry1, geometry2)

例子:

select SDO_COVERedby(SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(5,5, 8,8)
),
SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(4,4, 8,8)
)) from dual --TRUE

2.4、SDO_COVERS

检查两个几何图形是否具有 COVERS 拓扑关系;相当于使用 SDO_RELATE 操作符并指定 'mask=COVERS';与 SDO_COVEREDBY 类似,只不过 SDO_COVEREDBY 判断第二个几何图形是否包含第一个几何图形,SDO_COVERS 则判断第一个几何图形是否包含第二个几何图形。用法:

SDO_COVERS(geometry1, geometry2)

例子:

select SDO_COVERs(SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(4,4, 8,8)
),
SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(5,5, 8,8)
)) from dual --TRUE

2.5、SDO_EQUAL

检查两个几何图形是否具有 EQUAL 拓扑关系;相当于使用 SDO_RELATE 操作符并指定 'mask=EQUAL'。用法:

SDO_EQUAL(geometry1, geometry2);

例子:

select SDO_EQUAL(SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(4,4, 8,8)
),
SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(4,4, 8,8)
)) from dual --TRUE

2.6、SDO_FILTER

检查两个几何对象的外接矩形是否存在交互快,速排除不可能发生交互的对象,是一种更快速的筛选操作。用法:

select SDO_FILTER(SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(1,1, 2,2)
),
SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(2,2, 8,8)
)) from dual --TRUE

2.7、SDO_INSIDE

检查两个几何图形是否具有 INSIDE 拓扑关系;相当于使用 SDO_RELATE 操作符并指定 'mask=INSIDE'。检查一个空间对象是否完全位于另一个空间对象的内部。用法:

SDO_INSIDE(geometry1, geometry2);

例子:

select SDO_INSIDE(SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(2.1,2.1, 3,3)
),
SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(2,2, 8,8)
)) from dual --TRUE

2.8、SDO_ON

检查两个几何图形是否具有 ON 拓扑关系;相当于使用 SDO_RELATE 操作符并指定 'mask=ON'。检查两个几何对象是否完全重合或一个几何对象是否完全位于另一个几何对象的边界上,如:1、判断一个点是否位于多边形的边界上;2、判断一条线是否完全在某个区域的边界上。用法:

SDO_ON(geometry1, geometry2);

例子:

select SDO_ON(SDO_GEOMETRY(
        2002,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 2, 1),--线
        SDO_ORDINATE_ARRAY(7,7, 7,8)
),
SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(7,7, 9,9)
)) from dual

2.9、SDO_OVERLAPBDYDISJOINT

 检查两个几何图形是否具有 OVERLAPBDYDISJOINT 拓扑关系;相当于使用 SDO_RELATE 操作符并指定 'mask=OVERLAPBDYDISJOINT'。检查两个几何对象是否满足如下关系:1、两个几何对象有交集;2、交集部分属于两几何对象的一部分;3、两几何对象边界不相交。用法:

SDO_OVERLAPBDYDISJOINT(geometry1, geometry2);

例子:

select SDO_OVERLAPBDYDISJOINT(SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(3,3, 10,10)
),SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 2, 1),--线
        SDO_ORDINATE_ARRAY(0,4, 4,4)
)) from dual; --TRUE

select SDO_OVERLAPBDYDISJOINT(SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(3,3, 10,10)
),SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(2,2, 8,8)
)) from dual --FALSE,边界有相交

2.10、SDO_OVERLAPBDYINTERSECT

 检查两个几何图形是否具有 OVERLAPBDYINTERSECT 拓扑关系;相当于使用 SDO_RELATE 操作符并指定 'mask=OVERLAPBDYINTERSECT'。检查两个几何对象是否满足如下关系:1、两个几何对象有交集;2、交集部分属于两几何对象的一部分;3、两几何对象边界相交。用法:

SDO_OVERLAPBDYINTERSECT(geometry1, geometry2);

例子:

select SDO_OVERLAPBDYINTERSECT(SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(3,3, 10,10)
),
SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(2,2, 6,6)
)) from dual --TRUE

2.11、SDO_OVERLAPS

 检查两个几何图形是否具有 OVERLAPS 拓扑关系;相当于使用 SDO_RELATE 操作符并指定 'mask=OVERLAPS'。检查两个几何对象是否满足如下关系:1、两个几何对象有交集;2、交集部分属于两几何对象的一部分。用法:

SDO_OVERLAPS(geometry1, geometry2);

例子:

select SDO_OVERLAPS(SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(3,3, 10,10)
),
SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(2,2, 6,6)
)) from dual --TRUE

2.12、SDO_RELATE

 检查两个几何图形是否具有指定的拓扑关系。用法:

SDO_RELATE(geometry1, geometry2, param);

param 参数说明:

指定 mask 关键字,并可选地指定 min_resolution 和 max_resolution 关键字中的一个或两个。此参数的数据类型为 VARCHAR2。
mask 关键字指定拓扑关系。此参数是必需的。有效的 mask 关键字值是以下九中拓扑关系中的一个或多个:TOUCH、OVERLAPBDYDISJOINT、OVERLAPBDYINTERSECT、EQUAL、INSIDE、COVEREDBY、CONTAINS、COVERS、ANYINTERACT、ON。多个 mask 使用逻辑布尔运算符 OR 结合,例如 'mask=inside+touch'。
min_resolution 仅包含那些其最小边界矩形(MBR)的边长大于或等于指定值的几何体。例如,min_resolution=10 仅包含那些几何体的 MBR 宽度或高度(或两者)至少为 10 的几何体。
max_resolution 仅包含那些其最小边界矩形(MBR)的边长小于或等于指定值的几何体。例如,max_resolution=10 仅包含那些几何体的 MBR 宽度或高度(或两者)小于或等于 10 的几何体。

例子:

select SDO_RELATE(SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(2.1,2.1, 3,3)
),
SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(2,2, 8,8)
),'mask=INSIDE') from dual

2.13、SDO_TOUCH

 检查两个几何图形是否具有 TOUCH 拓扑关系;相当于使用 SDO_RELATE 操作符并指定 'mask=TOUCH'。检查两个几何对象是否有共享边界但没有重叠的面积。用法:

SDO_TOUCH(geometry1, geometry2);

例子:

select SDO_TOUCH(SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(2,2, 3,3)
),
SDO_GEOMETRY(
        2003,
        null,
        NULL,
        SDO_ELEM_INFO_ARRAY(1, 1003, 3),--矩形
        SDO_ORDINATE_ARRAY(3,3, 6,6)
)) from dual --TRUE

2.14、SDO_WITHIN_DISTANCE

 查询与给定几何对象(例如兴趣区域或兴趣点)距离不超过指定值的空间对象。用户:

SDO_WITHIN_DISTANCE(geometry1, aGeom, params);

params 参数说明:

参数 说明
distance 指定距离值。如果几何对象与坐标系统关联,则距离单位默认为与坐标系统关联的单位。这是必需的关键字。数据类型为 NUMBER。
ellipsoidal 使用椭球体距离进行计算(为 true),使用球面距离计算(为 false,默认值)
min_resolution 仅包含那些其最小边界矩形(MBR)的边长大于或等于指定值的几何体
max_resolution 仅包含那些其最小边界矩形(MBR)的边长小于或等于指定值的几何体
querytype 将 querytype 设置为 FILTER 表示仅执行初步过滤操作。如果未指定 querytype,则执行初步过滤和二级过滤操作(默认值)。
unit 一个带有 unit= 的字符串,后面跟着来自 MDSYS.SDO_DIST_UNITS 表的 SDO_UNIT 值(例如,'unit=KM')。默认值与坐标系关联。对于地理数据,默认单位是米。

例子:

select SDO_WITHIN_DISTANCE(SDO_GEOMETRY(
        2001,
        8307,
        SDO_POINT_TYPE(118.784169,32.041747, NULL),
        null,
        null
),
SDO_GEOMETRY(
        2001,
        8307,
        SDO_POINT_TYPE(118.813340,32.041747, NULL),
        null,
        null
),'distance=3000,unit=m') from dual --TRUE 两个点距离2755m左右

 

 

 

参考:https://docs.oracle.com/en/database/oracle/oracle-database/19/spatl/spatial-reference-information.html。

 

posted @ 2025-07-26 20:23  且行且码  阅读(57)  评论(0)    收藏  举报