oracle 空间操作符,Oracle Spatial空间操作符

Oracle Spatial支持许多空间操作符以进行空间邻近分析,这些空间操作符类似于关系操作符(和=),可以在SQL的WHERE子句中使用。

与几何操作不同的是操作符进行空间操作的对象必须有空间索引才行,也就是说空间操作符是与空间索引绑定的(具体来讲:至少空间操作符的第一个参数——table_geometry必须有空间索引)。

空间操作符的语法

(

table_geometry      IN SDO_GEOMETRY (或者 ST_GEOMETRY),

query_geometry      IN SDO_GEOMETRY (或者 ST_GEOMETRY),

[, parameter_string IN VARCHAR2

[, tag           IN NUMBER ]]

)

= 'TRUE'

table_geometry: 空间操作符要运用到的表几何体数据列;

query_geometry: 查询位置,可以是另一个表的几何体数据列,也可以是一个绑定的变量,或者是一个动态创建的几何体对象;

parameter_string: 指定特定的空间操作符参数,有些操作符中是可选的;

tag:在某些特定空间操作符上需要的数值,相关参数只能在parameter_string参数中指定。

此外还有些限定:

1. table_geometry列必须已经空间索引列;

2. 操作符应该总是等于字符串'TRUE',所以,别考虑FALSE了;

3. 要操作的数据库表的列要么是oracle原生的SDO_GEOMETRY类型,要么是ST_GEOMETRY类型及其子类型(例如ST_POINT, ST_LINESTRING或者ST_POLYGON)

空间操作符的语义

当在SQL语句中使用空间操作符时,Oracle会找出那些空间操作符计算为TRUE的数据行。想想id>=20

一个例子:

SELECT COUNT(*)

FROM branches b, customers c

WHERE  b.id=1

AND SDO_WITHIN_DISTANCE

(c.location, b.location, 'DISTANCE=0.5 UNIT=MILE') = 'TRUE';

空间操作符如何计算

因为空间操作符依赖于空间索引,实际上大多数情况下,计算是一种两阶段过滤机制。

0818b9ca8b590ca3270a3433284dd417.png

如图所示,空间操作符首先是要空间索引进行第一次计算,即primary filter。

空间操作符分类

按邻近分析的类型可分为:

1. 位置查询:从指定查询位置找出所有特定距离内的所有数据,即within distance操作符(SDO_WITHIN_DISTANCE);

2. 邻近查询:找出指定查询位置附近最近的那些邻居,即最近邻居(nearest-neighbor)操作符(SDO_NN);

3. 相交查询:找出与指定查询位置相交的所有邻居(Find neighbors that interact with or relate to a query location):主要操作符是SDO_RELATE,更简单的有SDO_FILTER(只是MBR的计算,因此也不需要Geometry Engine操作),此类操作符主要用于区域分析。此外还有对SDO_RELATE的简化版,如SDO_ANYINTERACT, SDO_CONTAINS, SDO_COVERS, SDO_COVEREDBY, SDO_EQUAL, SDO_INSIDE, SDO_ON, SDO_OVERLAPS, 和SDO_TOUCH

相交的分类模型,一个几何体由三部分组成:边界、内部和外部,

对于点:边界就是一个边界点

对于线:边界就是首尾两端的端点,

对于多边形:边界就是边界环 ring

0818b9ca8b590ca3270a3433284dd417.png

SDO_RELATE操作符中定义的几种相交类型,Q即为查询几何体,A对应着数据表中的几何体字段。

这些相交类型分类是根据几何体之间内部和边界的情况进行分类的

空间连接(Spatial Joins)

对于两个都要空间信息的表进行空间操作符操作是很耗时的,例如:

SELECT COUNT(DISTINCT ct.id)

FROM competitors comp, customers ct

WHERE SDO_WITHIN_DISTANCE(ct.location, comp.location, 'DISTANCE=200 UNIT=METER') = 'TRUE';

查询结果1145,查询时间为6.11秒。

使用SDO_JOIN可以提高这类查询的效率。

SDO_JOIN

(

table1 IN VARCHAR2,

col1 IN VARCHAR2,

table2 IN VARCHAR2,

col2 IN VARCHAR2

[, parameter_string IN VARCHAR2 DEFAULT NULL

[, preserve_join_order IN NUMBER DEFAULT 0

[, table1_partition IN VARCHAR2 DEFAULT NULL,

[ , table2_partition IN VARCHAR2 DEFAULT NULL]]]]

)

RETURNS SDO_ROWIDSET

返回值是一组ROWID对()的集合。

前面的查询改为:

SELECT COUNT(DISTINCT ct.id)

FROM competitors comp, customers ct,

TABLE(

SDO_JOIN(

'competitors', 'location',

'customers', 'location',

'DISTANCE=200 UNIT=METER'

)

) jn

WHERE ct.rowid=jn.rowid2 AND comp.rowid = jn.rowid1; 同样的结果,查询速度缩短到1.343秒。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>