Oracle Spatial中SDO_Geometry详细说明

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Oracle Spatial中SDO_Geometry详细说明
在ArcGIS中通过SDE存储空间数据到Oracle中有多种存储方式,分别有:二进制Long Raw 、ESRI的ST_Geometry以及基于Oracle Spatial的SDO_Geometry等等。

关于这几种方式的各自的优缺点不是主要的探讨的方向,这些我们可以通过ArcGIS中的ArcGIS Server Help得到相关的帮助。

这里主要是学习关于基于Oracle Spatial的存储方式,通过这种存储方式几何列Shape的字段类型为mdsys.sde_geometry类型。

Oracle Spatial定义的SDO_GEOMETRY类型为:
CREATE TYPE sdo_geometry AS OBJECT (
SDO_GTYPE NUMBER, //前面字符串为字段名;后面字符串为字段类型
SDO_SRID NUMBER,
SDO_POINT SDO_POINT_TYPE,
SDO_ELEM_INFO SDO_ELEM_INFO_ARRAY,
SDO_ORDINATES SDO_ORDINATE_ARRAY);
其中sdo_geometry AS OBJECT ,标识该类型为对象类型。

开始我们可以想想它为ArcObjects 中的Geometry对象(本来要素的shape字段中的对象就是Geometry),而不要理解他是怎么样组织的。

至于该类型中的SDO_POINT_TYPE、SDO_ELEM_INFO_ARRAY、SDO_ORDINATE_ARRAY也是Oracle Spatial自定义的类型和sdo_geometry 是一样的。

现在对sdo_geometry 类型中的各个参数简单的介绍:
1、SDO_GTYPE :表示要存储的几何类型,如点线面。

它是通过NUMBER类型来表达的;
2、SDO_SRID :几何的空间参考坐标系,类型也为NUMBER;
3、SDO_POINT :如果几何类型点类型的话,就是存储点坐标,否则为空。

oracle自定义的SDO_POINT_TYPE类型;
4、SDO_ELEM_INFO :定义要如何理解SDO_ORDINATES中的坐标串的;
5、SDO_ORDINATES :存储实际坐标的,以X、Y以及不同点之间都是逗号隔开;
下面将详细介绍这些字段参数的含义
一、SDO_GTYPE
SDO_GTYPE值是有四位数字组成的,它们的格式为:dltt 。

其中,d 表示几何的维数。

如二维、三维对应的d=2和d=3;
l 定义了LRS。

一般l=0;
tt 定义了地理对象的类型。

现在使用从00到07,如tt=01代表为单点;
下面就是t=2的二维几何类型,SDO_GTYPE参数值具体,如图1:
SDO_GTYPE 几何类型相关描述
2000 未知的地理类型Spatial会无视这个类型的地理对象
2001 单点Point类型地理对象包含一个普通的点
2002 单线Polyline和Curve类型地理对象包含直线或片段segments
2003 Polygon类型地理对象包含一个普通的多边形,但不包含空岛
2004 集合COLLECTION类型地理包含不同类型元素集合
2005 多点MultiPoint类型地理对象包含多个点的集合
2006 多线MutliPolyline和多曲线类型地理对象有一或更多的线或曲线集合
2007 多多边形MutliPolygon类型一个地理对象包含岛(多岛)的多边形和N个多边形
对于一个给定的层,所有的地理对象必须都是相同的维度,不能将二维与三维的数据放在一个层里。

二、SDO_SRID
SDO_SRID定义了空间坐标参考系统。

如果SDO_SRID为null,则没有指定坐标系统,如果SDO_SRID不为null,那么它的值必须在在MDSYS.CS_SRS 表中的SRID 列有对应的值,而且它的值必须插入USER_SDO_GEOM_METADATA视图中。

MDSYS.CS_SRS 表参考图3
MDSYS.CS_SRS表
列名类型列名描述
CS_NAME VARCHAR2(68) 坐标系统名称
SRID NUMBER(38) 空间参考ID,为唯一值。

1-999999为spatial使用的空间参
考,1000000以后为用户自定义
AUTH_SRID NUMBER(38) 可选的SRID,是个外键。

另一个坐标系统的SRID AUTH_NAME VARCHAR2(256)
WKTEXT VARCHAR2(2046)
CS_BOUNDS MDSYS.SDO_GEOMETRY
三、SDO_POINT
SDO_POINT类型的构造方法为:sdo_point_type(x,y,z),其中x,y,z类型为Double 和Int都可
SDO_POINT字段定义为含有X、Y、Z属性的SDO_POINT_TYPE类型。

如果几何类型为点类型的话,SDO_ELEM_INFO 和SDO_ORDINATES对应的值都为Null,SDO_POINT 不为空。

其它情况下,SDO_POINT会被Spatial所忽略即设为Null。

如果这个层只有点对象,那么推荐你将其保存在SDO_POINT属性中。

SDO_POINT_TYPE类型的定义如下:
CREATE TYPE sdo_point_type AS OBJECT (
X NUMBER, //X坐标值
Y NUMBER, //y坐标值
Z NUMBER); //z坐标值
四、SDO_ELEM_INFO
SDO_ELEM_INFO类型的构造方法为:sdo_elem_info_array(a,b.c),其中a,b.c为
Number类型。

SDO_ELEM_INFO是理解和掌握SDO_Geometry的重点和难点,SDO_ELEM_INFO 定义了如何理解SDO_ORDINATES中的坐标字符串属性。

SDO_ELEM_INFO每三个数字组合为一个SDO_ELEM_INFO属性单元(具体可以结合下面的例子理解)。

每个SDO_ELEM_INFO属性单元由:SDO_STARTING_OFFSET、SDO_ETYPE 和
SDO_INTERPRETATION 组成。

下面介绍一下这三个数字的具体含义:
4.1、SDO_STARTING_OFFSET:声明了组成当前几何片段的第一个坐标在
SDO_ORDINATES数组中的坐标序号。

坐标序号是从1开始起算的而非从0开始。

这里的
SDO_ORDINATES就是sdo_geometry 中的坐标序列,坐标序列是已逗号隔开的数字,具体的计算如:sdo_ordinate_array(1,4,6,7,8,9)中如果以'6'开始几何片段的话,坐标序号
SDO_STARTING_OFFSET=3。

(具体参考下面的例子理解)
4.2、SDO_ETYPE :声明元素的类型。

可结合SDO_STARTING_OFFSET和SDO_ETYPE 表来理解.
SDO_ETYPE 值= 1, 2, 1003,或2003,说明几何为简单的几何类型。

可以全部按
SDO_ELEM_INFO 属性单元【即三个以逗号隔开的数】来理解sdo_ordinate_array中的坐标序列。

特别说明:SDO_ETYPE 值= 1003 ,假如几何类型为面,则表示为外多边形环(以逆时针顺序)
SDO_ETYPE 值= 2003 ,假如几何类型为面,则表示为内多边形环(以顺时针顺序)
SDO_ETYPE 值= 4,1005或2005,说明几何为组合元素,往往第一个三数字组不是SDO_ELEM_INFO 属性单元,而是为了说明组合元素的信息。

具体可以参见下面复杂多义线和复杂多边形的例子。

4.3、SDO_INTERPRETATION:有两种可能的意思,依赖地SDO_ETYPE是否是组合元素。

如果SDO_ETYPE 值= 4,1005或2005,标识的是有多少组合部分,具体参考复杂多义线和复杂多边形的例子。

如果SDO_ETYPE 值= 1, 2, 1003,或2003,标识决定了元素坐标队列的翻译顺序。

SDO_STARTING_OFFSET和SDO_ETYPE 表如下图4:
五、SDO_ORDINATES
SDO_ORDINATES类型的构造方法为:sdo_ordinate_array(x1,y1,x2,y2,……),其中x1,y1类型等为Double和Int都可。

SDO_ORDINATES存储的是空间对象的几何节点坐标序列,用逗号将X、Y、Z以及不同点之间隔开,该字段性质:长度=1048576的数字Number类型。

如果几何为二维的情况,存储的序列为{Y1, X2, Y2, X3, Y3, X4, Y4......}格式;几何为三维坐标的话,如三维坐标的多边形它的存储的序列为{X1, Y1, Z1, X2, Y2, Z2, X3, Y3, Z3, X4, Y4, Z4, X1, Y1, Z1}格式。

坐标序列中的数据必须都合法且不为空。

具体坐标的组合成几何的结合SDO_ELEM_INFO来理解。

六、参考例子:
6.1、矩形:
矩形的具体几何形状和坐标,如下图:
用SDO_GEOMETRY定义该矩形,如何确定sdo_geometry()构造方法中的各个参数值。

详细解释如下:
SDO_GTYPE = 2003;2003中的2表示二维数据,2003中的3表示表示多边形。

具体参考图1
SDO_SRID = NULL;
SDO_POINT = NULL;
SDO_ELEM_INFO = (1, 1003, 3).;在属性单元SDO_ELEM_INFO (1,1003,3)中的最后一个3表示该几何为矩形,具体参考图4。

---因为它是矩形且为二维所以它的构造方法为:sdo_point_type(左下坐标,右上坐标)。

SDO_ORDINATES = (1,1, 5,7). 定义了具体的左下坐标和右上坐标的坐标序列。

例子:用SQL 命令插入一个矩形:
INSERT INTO beniy388 VALUES(
1, //其他的属性字段的值
'UpDooGIS', //其他的属性字段的值
MDSYS.SDO_GEOMETRY( //几何字段SDO_GEOMETRY的值
2003, -- 二维多边形
NULL,
NULL,
MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,3), -- 一个矩形(1003为逆时针方向)
MDSYS.SDO_ORDINATE_ARRAY(1,1, 5,7) -- 只需要两点
)
);
6.2、有岛多边形:
有岛多边形的具体几何形状和坐标,如下图:
用SDO_GEOMETRY定义该多边形,如何确定sdo_geometry()构造方法中的各个参数值。

详细解释如下:
SDO_GTYPE = 2003;---2003中的2表示二维数据,2003中的3表示表示多边形。

具体参考图1
SDO_SRID = NULL;
SDO_POINT = NULL;
SDO_ELEM_INFO = (1,1003,1, 19,2003,1);---有两个三元组SDO_ELEM_INFO属性元素。

具体参考图4
---其中1003表明对应的坐标序列组成的几何A为外多边形环(顺时针);而2003表明对应的坐标序列组成的几何B为内多边形环(逆时针)。

---19 表示几何B坐标序列开始的位置,也就是说从19开始的几何坐标组成几何B,而1到18组成几何A。

SDO_ORDINATES = (10,10, 10,14, 6,10, 14,10);---坐标系列
例子:用SQL 命令插入一个有岛的多边形:
INSERT INTO beniy388 VALUES
10, //其他的属性字段的值
'UpDooGIS', //其他的属性字段的值
MDSYS.SDO_GEOMETRY( //几何字段SDO_GEOMETRY的值
2003,
NULL,
NULL,
MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,1, 19,2003,1), -- 有岛多边形
MDSYS.SDO_ORDINATE_ARRAY(2,4, 4,3, 10,3, 13,5, 13,9, 11,13, 5,13, 2,11, 2,4,7,5, 7,10, 10,10, 10,5, 7,5)
)
);
6.3、复杂多义线
下图描述的是一个由一条直线和一条曲线构成的复杂多义线。

图中出现了4个点,(10,10)和(10,14)点表示的是直线;10,14), (10,6), 和 (14,10) 描述的是圆弧曲线:
用SDO_GEOMETRY定义该复杂多义线,如何确定sdo_geometry()构造方法中的各个参数值。

详细解释如下:
SDO_GTYPE = 2002;2002中的2表示二维数据,第二个2表示表示一条或多条直线段。

具体参考图1。

SDO_SRID = NULL;
SDO_POINT = NULL;
SDO_ELEM_INFO = (1,4,2, 1,2,1, 3,2,2). ---有三个三元组,其中后两个是
SDO_ELEM_INFO属性元素三元组,前一个为表述组合。

具体参考图4。

---第一个三元组【1,4,2】,根据4可以得到是个描述三元组,2表示有两个几何元素组成,即后两个三元组描述各自的几何A和几何B。

---第二个三元组【1,2,1】,为SDO_ELEM_INFO属性元素三元组,它描述的是几何A。

根据图4可以得到它是一条直线段,且该直线段的最后一个节点还是下一个几何B的开始点,即几何A和几何B有几何节点重合。

---第二个三元组【3,2,2】,为SDO_ELEM_INFO属性元素三元组,它描述的是几何B。

根据图4可以得到它是一条曲线段,该几何B的起点和几何A终点节点重合。

SDO_ORDINATES = (10,10, 10,14, 6,10, 14,10);---坐标系列
例子:用SQL 命令插入一个复杂多义线:
INSERT INTO beniy388 VALUES(
11, //其他的属性字段的值
'UpDooGIS', //其他的属性字段的值
MDSYS.SDO_GEOMETRY( //几何字段SDO_GEOMETRY的值
2002,
NULL,
NULL,
MDSYS.SDO_ELEM_INFO_ARRAY(1,4,2, 1,2,1, 3,2,2), --
复杂多义线
MDSYS.SDO_ORDINATE_ARRAY(10,10, 10,14, 6,10, 14,10)
)
);
----------------------------------------------------------------------------------------------------- Oracle Spatial基本操作
Oracle Spatial主要通过元数据表、空间数据字段(即sdo_Geometry字段)和空间索引来管理空间数据,并在此基础上提供一系列空间查询和空间分析的程序包,让用户进行更深层次的GIS应用开发。

Oracle Spatial使用空间字段sdo_Geometry存储空间数据,用元数据表来管理具有sdo_Geometry 字段的空间数据表,并采用R树索引和四叉树索引技术来提高空间查询和空间分析的速度。

1、元数据表说明
Oracle Spatial的元数据表存储了有空间数据的数据表名称、空间字段名称、空间数据的坐标范围、坐标系以及坐标维数说明等信息。

用户必须通过元数据表才能知道Oracle数据库中是否有Oracle Spatial 的空间数据信息。

通过元数据视图(USER_SDO_GEOM_METADATA)访问元数据表。

元数据视图的基本定义为:
2、空间字段解析
Oracle Spatial的空间数据都存储在空间字段sdo_Geometry中,理解sdo_Geometry是编写Oracle Spatial程序的关键。

sdo_Geometry是按照Open GIS规范定义的一个对象,其原始的创建方式如下所示。

① sdo_Gtype
是一个NUMBER型的数值,用来定义存储几何对象的类型。

sdo_Gtype是一个4个数字的整数,其格式为dltt,其中d表示几何对象的维数;l表示三维线性参考系统中的线性参考值,当d为3维或者4
维时需要设置该值,一般情况下为空;tt为几何对象的类型,Oracle Spatial定义了7种类型的几何类型,目前,tt使用了00到07,其中08到99是Oracle Spatial保留的数字,以备将来几何对象扩展所用。

② sdo_Srid
sdo_Srid也是一个NUMBER型的数值,它用于标识与几何对象相关的空间坐标系。

如果sdo_Srid 为空(null),则表示没有坐标系与该几何对象相关;如果该值不为空,则该值必须为MDSYS.CS_SRS 表中SRID字段的一个值,在创建含有几何对象的表时,这个值必须加入到描述空间数据表元数据的USER_SDO_GEOM_METADATA视图的SRID字段中。

对于我们通常使用国际标准的
Longitude/Latitude(8307),Oracle Spatial规定,一个几何字段中的所有几何对象都必须为相同的sdo_Srid值。

③ sdo_Point
sdo_Point是一个包含三维坐标X,Y,Z数值信息的对象,用于表示几何类型为点的几何对象。

如果sdo_Elem_Info和SDO_ORDINATES数组都为空,则sdo_Point中的X,Y,Z为点对象的坐标值,否则,sdo_Point的值将被忽略(用NULL表示)。

Oracle Spatial强烈要求用sdo_Point存储空间实体为点类型空间数据,这样可以极大的优化Oracle Spatial的存储性能和查询效率。

④ sdo_Elem_Info
sdo_Elem_Info是一个可变长度的数组,每3个数作为一个元素单位,用于表示坐标是如何存储在SDO_ORDINATES数组中的。

本文把组成一个元素的3个数称为3元组。

一个3元组包含以下3部分的内容:
◇ SDO_STARTING_OFFSET
SDO_STARTING_OFFSET 表明每个几何元素的第一个坐标在SDO_ORDINATES数组中的存储位置。

它的值从1开始,逐渐增加。

◇ SDO_ETYPE
SDO_ETYPE 用于表示几何对象中每个组成元素的几何类型。

当它的值为1, 2, 1003和2003时,表明这个几何元素为简单元素。

如果SDO_ETYPE为1003,表明该多边形为外环(第一个数为1表示外环),坐标值以逆时针存储;如果SDO_ETYPE为2003,表明该多边形为内环(第一个数为2表示内环),坐标值以顺时针存储。

当SDO_ETYPE为4, 1005和2005时,表明这个几何元素为复杂元素。

它至少包含一个3元组用以说明该复杂元素具有多少个几何简单元素。

同样,1005表示多边形为外环,坐标值以逆时针存储;2005表示多边形为内环,坐标值以顺时针存储。

◇ SDO_INTERPRETATION
SDO_INTERPRETATION具有两层含义,具体的作用由SDO_ETYPE是否为复杂元素决定。

如果SDO_ETYPE是复杂元素(4, 1005和2005),则SDO_INTERPRETATION表示它后面有几个子3元组属于这个复杂元素。

如果SDO_ETYPE是简单元素(1, 2, 1003和2003),则SDO_INTERPRETATION 表示该元素的坐标值在SDO_ORDINATES中是如何排列的。

需要注意的是,对于复杂元素来说,组成它的子元素是连续的,一个子元素的最后一个点是下一个子元素的起点。

最后一个子元素的最后一个坐标要么与下一个元素的SDO_STARTING_OFFSET值减1所对应的坐标相同,要么是整个SDO_ORDINATES数组的最后一个坐标。

⑤ sdo_Ordinates
SDO_ORDINATES是一个可变长度的数组,用于存储几何对象的实际坐标,是一个最大长度为1048576,类型为Number的数组。

SDO_ORDINATES必须与sdo_Elem_Info数组配合使用,才具有实际意义。

SDO_ORDINATES 的坐标存储方式由几何对象的维数决定,如果几何对象为二维,则SDO_ORDINATES的坐标以{ x1, y1, x2, y2, …}顺序排列,如果几何对象为三维,则SDO_ORDINATES的坐标以{x1, y1, z1, x2, y2, z2, …}的顺序排列。

3、空间索引技术:
Oracle Spatial提供R树索引和四叉树索引两种索引机制来提高空间查询和空间分析的速度。

用户需
要根据不同空间数据类型创建不同的索引,当空间数据类型比较复杂时,如果选择索引类型不当,将使Oracle Spatial创建索引的过程变得非常慢。

三、将经纬度转化成地名
目前各类位置服务LBS最终返回的都是误差允许范围内的经纬度,如GPS车载终端,手机定位等移动设备,系统通过一定的技术算法可以将其转化成具体的地名或附近的地标。

或根据需要返回当前位置用户关心的周边信息:如医院、宾馆、加油站、公交车站等内容。

1、空间数据到Oracle Spatial的导入
当前专题空间数据库建立的过程包括技术设计、资料准备、数据获取和数据入库等内容。

数据的获取常可利用现有的GIS 专业软件如GeoStar、MAPGIS、SUPERMAP、ARCGIS 等来实现,获得的数据通过某一空间数据引擎(如Easyloader)上载到Oracle 数据库中,实现利用Oracle Spatial 存储、管理空间数据。

MAPORA 引擎是把MAPGIS 的明码格式通过编程实现空间数据上载Oracle Spatial 的一种方法。

2、定位服务的整个流程
3、Oracle Spatial关联用到的程序包:
◆ sdo_Geom.Relate(sdo_Geometry1, ‘MASK’, sod_Geometry2, tolerance ):用于判断一个几何体与另一个几何体的关系,我们用于判断当前点是否在某一个面(省份面、县市面、乡镇面)上。

◇ sdo_Geometry1,sdo_Geometry2为空间数据对应的几何对象。

◇ Tolerance: 容许的精度范围;
◇ MASK=Anyinteract/Contains/Coveredby/Covers/Disjoint/
○ Anyinteract: sdo_Geometry2落在sdo_Geometry1面上包括在边上。

○ Contains: sdo_Geometry2完全包含在sdo_Geometry1几何对象中,并且两个几何对象的边没有交叉。

○ Coveredby: sdo_Geometry1完全包含在sdo_Geometry2中,并且这两个几何对象的边有一个或多个点相互重叠。

○ Covers: sdo_Geometry2完全包含在sdo_Geometry1中,并且这两个几何对象的边有一个或多个点相互重叠。

○ Disjoint: 两个几何没有重叠交叉点,也没有共同的边。

○ Equal: 两个几何是相等的。

○ Inside: sdo_Geometry1完全包含在sdo_Geometry2几何对象中,并且两个几何对象的边没有交叉。

○ On: sdo_Geometry1的边和内部的线完全在sdo_Geometry2上。

○ Overlapbdydisjoint: 两个几何对象交迭,但是边没有交叉。

○ Overlapbdyintersect: 两个几何对象交迭,并且边有部分交叉。

○ Touch: 两个几何对象有共同的边,但没有交叉。

◆ sdo_nn( sdo_Geometry1, sdo_Geometry2, ‘sdo_num_res’, Tolerance ):用于返回几何体sdo_Geometry2周边附近有什么其他几何体集。

◇ sdo_Geometry1,sdo_Geometry2为空间数据对应的几何对象。

◇ Tolerance: 容许的精度范围;
◇ sdo_num_res=n: 表示返回n个几何体,=1表示只返回一个。

◆ sdo_Geom.Within_Distance(sdo_Geometry1, Distance, sdo_Geometry2, Tolerance, 'unit' )用于判断几何体sdo_Geometry2在指定的距离Distance内周边附近有什么其他几何体集。

◇ sdo_Geometry1,sdo_Geometry2为空间数据对应的几何对象。

◇ Tolerance: 容许的精度范围;
◇ Distance: 指定的距离;
◇ Unit: 用于表示距离的单位,可能是Unit=M/ Unit=KM等长度单位,但必须是
SDO_DIST_UNITS表中列举出来的单位之一。

4、返回的信息:
返回的信息根据业务需要可以返回空间信息关联到的所有信息,然后用三段论方式组合成一段话,通过SMS等方式返回到移动终端。

◆可以是当前位置的地名、城市地标、自定义地标、道路名称等位置信息;
◆可以是当前位置的周边信息:医院、宾馆、加油站、公交车站等;
查询:SELECT c.geometry.SDO_GTYPE,c.geometry.SDO_ORDINATES,
c.geometry.SDO_ELEM_INFO,c.geometry.SDO_SRID,c.geometry.SDO_POINT.X,
c.geometry.SDO_POINT.Y,c.geometry.SDO_POINT.Z FROM xz_chengshi c
空间数据类型与元数据
Oracle Spatial由一坨的对象数据类型,类型方法,操作子,函数与过程组合而成。

一个地理对象作为一个SDO_GEOMETRY对象保存在表的一个字段里。

空间索引则由普通的DDL和DML语句来建立与维护。

本章主要说了一些例子演示如何建立,查询,索引空间数据。

2.1 简单的插入,索引与查询空间数据例子
本节演示一个很简单建立空间表,插入,建立索引,查询数据的过程。

场景是一个软饮料公司,用地理信息来表示他们的产品(可乐)在各个地区的情况。

这些情况可以是:市场份额,竞争压力,增长潜力等等。

而地区可以是邻近的市,州,省或国家。

我们要作的是:
1.建立一个表(COLA_MARKETS)来保存空间数据
2.插入四个(cola_a, cola_b, cola_c, cola_d)地区的数据
3.升级USER_SDO_GEOM_METADATA视图来反正这些地区的维度信息
4.建立空间索引(COLA_SPATIAL_IDX)
5.进行一些空间查询
Example 2¨C1Simple Example: Inserting,Indexing, and Querying Spatial Data
-- Create a table for cola (soft drink) markets in a
-- given geography (such as city or state).
-- Each row will be an area of interest for a specific
-- cola (for example, where the cola is most preferred
-- by residents, where the manufacturer believes the
-- cola has growth potential, and so on).
-- (For restrictions on spatial table and column names, see
-- Section2.6.1 and Section2.6.2.)
CREATE TABLE cola_markets (
mkt_id NUMBER PRIMARY KEY,
name VARCHAR2(32),
shape SDO_GEOMETRY);
-- The next INSERT statement creates an area of interest for
-- Cola A. This area happens to be a rectangle.
-- The area could represent any user-defined criterion: for
-- example, where Cola A is the preferred drink, where
-- Cola A is under competitive pressure, where Cola A
-- has strong growth potential, and so on.
INSERT INTO cola_markets VALUES(
1,
'cola_a',
SDO_GEOMETRY(
2003, -- two-dimensional polygon
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,3), -- one rectangle (1003 = exterior)
SDO_ORDINATE_ARRAY(1,1, 5,7) -- only 2 points needed to
-- define rectangle (lower left and upper right) with
-- Cartesian-coordinate data
)
);
-- The next two INSERT statements create areas of interest for
-- Cola B and Cola C. These areas are simple polygons (but not
-- rectangles).
INSERT INTO cola_markets VALUES(
2,
'cola_b',
SDO_GEOMETRY(
2003, -- two-dimensional polygon
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,1), -- one polygon (exterior polygon ring)
SDO_ORDINATE_ARRAY(5,1, 8,1, 8,6, 5,7, 5,1)
)
);
INSERT INTO cola_markets VALUES(
3,
'cola_c',
SDO_GEOMETRY(
2003, -- two-dimensional polygon
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,1), -- one polygon (exterior polygon ring)
SDO_ORDINATE_ARRAY(3,3, 6,3, 6,5, 4,5, 3,3)
)
);
-- Now insert an area of interest for Cola D. This is a
-- circle with a radius of 2. It is completely outside the
-- first three areas of interest.
INSERT INTO cola_markets VALUES(
4,
'cola_d',
SDO_GEOMETRY(
2003, -- two-dimensional polygon
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,4), -- one circle
SDO_ORDINATE_ARRAY(8,7, 10,9, 8,11)
)
);
---------------------------------------------------------------------------
-- UPDATE METADATA VIEW --
---------------------------------------------------------------------------
-- Update the USER_SDO_GEOM_METADATA view. This is required
-- before the Spatial index can be created. Do this only once for each
-- layer (that is, table-column combination; here: COLA_MARKETS and SHAPE).
INSERT INTO user_sdo_geom_metadata
(TABLE_NAME,
COLUMN_NAME,
DIMINFO,
SRID)
VALUES (
'cola_markets',
'shape',
SDO_DIM_ARRAY( -- 20X20 grid
SDO_DIM_ELEMENT('X', 0, 20, 0.005),
SDO_DIM_ELEMENT('Y', 0, 20, 0.005)
),
NULL -- SRID
);
-------------------------------------------------------------------
-- CREATE THE SPATIAL INDEX --
-------------------------------------------------------------------
CREATE INDEX cola_spatial_idx
ON cola_markets(shape)
INDEXTYPE IS MDSYS.SPATIAL_INDEX;
-- Preceding statement created an R-tree index.
-------------------------------------------------------------------
-- PERFORM SOME SPATIAL QUERIES --
-------------------------------------------------------------------
-- Return the topological intersection of two geometries.
SELECT SDO_GEOM.SDO_INTERSECTION(c_a.shape, c_c.shape, 0.005)
FROM cola_markets c_a, cola_markets c_c
WHERE c_ = 'cola_a' AND c_ = 'cola_c';
-- Do two geometries have any spatial relationship?
SELECT SDO_GEOM.RELATE(c_b.shape, 'anyinteract', c_d.shape, 0.005)
FROM cola_markets c_b, cola_markets c_d
WHERE c_ = 'cola_b' AND c_ = 'cola_d';
-- Return the areas of all cola markets.
SELECT name, SDO_GEOM.SDO_AREA(shape, 0.005) FROM cola_markets;
-- Return the area of just cola_a.
SELECT , SDO_GEOM.SDO_AREA(c.shape, 0.005) FROM cola_markets c
WHERE = 'cola_a';
-- Return the distance between two geometries.
SELECT SDO_GEOM.SDO_DISTANCE(c_b.shape, c_d.shape, 0.005)
FROM cola_markets c_b, cola_markets c_d
WHERE c_ = 'cola_b' AND c_ = 'cola_d';
-- Is a geometry valid?
SELECT , SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT(c.shape, 0.005)
FROM cola_markets c WHERE = 'cola_c';
-- Is a layer valid? (First, create the results table.)
CREATE TABLE val_results (sdo_rowid ROWID, result VARCHAR2(2000));
CALL SDO_GEOM.VALIDATE_LAYER_WITH_CONTEXT('COLA_MARKETS', 'SHAPE',
'VAL_RESULTS', 2);
SELECT * from val_results;
2.2 SDO_GEOMETRY对象类型
在Spatial中,地理对象的描述是放在一个单独的类型为SDO_GEOMETRY的字段中的。

任何有这个字段的表,都至少要定义一个其它主键字段。

Oracle Spatial定义的SDO_GEOMETRY类型为:
CREATE TYPE sdo_geometry AS OBJECT (
SDO_GTYPE NUMBER,
SDO_SRID NUMBER,
SDO_POINT SDO_POINT_TYPE,
SDO_ELEM_INFO SDO_ELEM_INFO_ARRAY,
SDO_ORDINATES SDO_ORDINATE_ARRAY);
当然Spatial也定义了SDO_POINT_TYPE, SDO_ELEM_INFO_ARRAY, 和
SDO_ORDINATE_ARRAY类型:
CREATE TYPE sdo_point_type AS OBJECT (
X NUMBER,
Y NUMBER,
Z NUMBER);
CREATE TYPE sdo_elem_info_array AS VARRAY (1048576) of NUMBER;
CREATE TYPE sdo_ordinate_array AS VARRAY (1048576) of NUMBER;
因为SDO_ORDINATE_ARRAY最大为1048576,所以SDO_GEOMETRY对象的顶点数量就依赖于它的维度,二维为524288,三维为349525,四维只有262144个顶点了。

2.2.1 SDO_GTYPE
SDO_GTYPE属性声明了地理对象的类型。

它由四位数据组成dltt:
1.d表明了维度
2.l定义了LRS(这个没看懂,在第七章会说,到时候再说)
3.tt定义了地理对象的类型00至07,08和99保留
dl00:未知的地理类型,Spatial会无视这个类型的地理对象
dl01:点对象,地理对象包含一个点
dl02:线或曲线,地理对象可以包含直线与曲线
dl03:多边形,地理对象可以包含有洞或无洞的多边形,对于有洞的多边形,先是描述外边,然后再描述内边
dl04:集合,地理对象为不同类型的集合
dl05:多点,地理对象是多个点的集合
dl06:多线或多曲线,地理对象有一或更多的线或曲线集合
dl07:多多边形,地理对象有多个不相交的多边形组成
对于一个给定的层(同一字段),所有的地理对象必须都是相同的维度,不能将二维与三维的数据放在一个层里。

2.2.2 SDO_SRID
SDO_SRID属性定义了空间坐标参考系统。

如果SDO_SRID为null,则没有指定坐标系统,如果SDO_SRID不为null,那么它的值必须在SDO_COORD_REF_SYS表中,而且它的值必须插入USER_SDO_GEOM_METADATA视图中。

2.2.3 SDO_POINT
SDO_POINT属性定义为SDO_POINT_TYPE类型,它是X,Y,Z之类的数字组成。

如果
SDO_ELEM_INFO与SDO_ORDINATES数组都为NULL,并且SDO_POINT属性不为null,那么会被缺省认为是点对象。

其它情况下,SDO_POINT会被Spatial所忽略。

如果这个层只有点对象,那么推荐你将其保存在SDO_POINT属性中。

2.2.4 SDO_ELEM_INFO
SDO_ELEM_INFO属性定义要如何理解SDO_ORDINATES属性。

每三个数字为一组
1.SDO_STARTING_OFFSET:声明了第一个坐标在SDO_ORDINATES数组中的位置。

位置开始于1而不是0。

因此,第一个元素的第一个坐标是SDO_GEOMETRY.SDO_ORDINATES(1).
2.SDO_ETYPE:声明元素的类型:
1,2,1003,2003:被认为是简单元素,它们由SDO_ELEM_INFO数组的单个三值对定义。

对于1003与2003来说:1003为外多边形环(以逆时针顺序),2003为内多边形环(以顺时针顺序),如果你使用四位的SDO_ETYPE那么,你也要使用四位的SDO_GTYPE。

4,1005,2005:被认为是组合元素。

这些组合元素是连续,上一个的结尾点是下一个元素的开始点。

而且点不重复
2.SDO_INTERPRETATION:表示的意思依赖地SDO_ETYPE是否是组合元素。

如果SDO_ETYPE不是组合元素(1,2,1003,2003),那么这个属性决定了元素坐标队列的翻译顺序。

如下:
SDO_TYPE SDO_INTERPRETATION MEANING
0 any number 不支持
1 1 点类型
1 9 有方法的点
1 n > 1 N个点的集合
2 1 由直线段组成的线段
2 2 由曲线组成的线段
每一曲线段由三个点来描述:起点,任意在曲线段上的一点,终点,前一个终点是下一个的起点。

1003or2003 1 由直线段组合的多边形,最后一点要与第一个点相同
1003or2003 2 由曲线组合的多边形,最后一点要与第一个点相同
1003or2003 3 矩形,由左下至右上的两个点描述的矩形。

1003or2003 4 圆,由三个非共线的点进行描述
4 n > 1 由直线与曲线组合的线段,N描述了多少个点组成一个线段
1005or2005 n > 1 由直线与曲线组合的多边形
2.2.5 SDO_ORDINATES
这个属性就是一个1048576长的数组,保存了地理对象的坐标。

对于三维数据,空间索引将对Z轴无视。

这个数组中的数据必须都有效。

2.2.6 使用条件:
Spatial并不去检查地理对象数据的完整性,对于不合规则的数据,它只是将期忽略。

当然,可以使用SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT函数来进行检查。

2.3 SDO_GEOMETRY中的方法
SDO_GEOMETRY类型有自己的方法,可以使用它们来得到SDO_GEOMOTRY中的一些信息:
Get_Dims Number 返回对象的维度与ST_CoordDim返回相同的结果
Get_GType Number 返回对象的类型
Get_LRS_Dim Number 返回对象使用LRS地理坐标系统
Get_WKB BLOB 返回众所周知的二进制(WKB)的地理对象
Get_WKT CLOB 返回众所周知的文本(WKT)格式的地理对象
ST_CoordDim Number 返回坐标维度
ST_IsValid Number 如果地理对象有效返回0,否则返回1,这个方法使用0.001作为公差,使用
SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT函数来指定其它的公差值。

ELECT c.shape.Get_Dims()
FROM cola_markets c WHERE = 'cola_b';
C.SHAPE.GET_DIMS()
------------------
2
SELECT c.shape.Get_GType()
FROM cola_markets c WHERE = 'cola_b';
C.SHAPE.GET_GTYPE()
-------------------
3
SELECT a.route_geometry.Get_LRS_Dim()
FROM lrs_routes a WHERE a.route_id = 1;
A.ROUTE_GEOMETRY.GET_LRS_DIM()
------------------------------
3
SELECT c.shape.Get_WKT()
FROM cola_markets c WHERE = 'cola_b';
C.SHAPE.GET_WKT()
--------------------------------------------------------------------------------
POLYGON ((5.0 1.0, 8.0 1.0, 8.0 6.0, 5.0 7.0, 5.0 1.0))
SELECT c.shape.ST_CoordDim()
FROM cola_markets c WHERE = 'cola_b';
C.SHAPE.ST_COORDDIM()
---------------------
SELECT c.shape.ST_IsValid()
FROM cola_markets c WHERE = 'cola_b';
C.SHAPE.ST_ISVALID()
--------------------
1
2.4 SDO_GEOMETRY的构造函数
SDO_GEOMETRY对象的构造函数可以使用WKT与WKB来建立。

SDO_GEOMETRY(wkt CLOB, srid NUMBER DEFAULT NULL);
SDO_GEOMETRY(wkt VARCHAR2, srid NUMBER DEFAULT NULL);
SDO_GEOMETRY(wkb BLOB, srid NUMBER DEFAULT NULL);
SRID值必须与表中同字段的其它的SRID相同
SELECT SDO_GEOMETRY('POINT(-79 37)') FROM DUAL;
SDO_GEOMETRY('POINT(-7937)')(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z),
SDO_ELEM_I
--------------------------------------------------------------------------------
SDO_GEOMETRY(2001, NULL, SDO_POINT_TYPE(-79, 37, NULL), NULL, NULL)
例子:
DECLARE
cola_b_wkb BLOB;
cola_b_wkt_clob CLOB;
cola_b_wkt_varchar VARCHAR2(255);
cola_b_geom SDO_GEOMETRY;
BEGIN
-- Get cola_b geometry into CLOB, VARCHAR2, and BLOB objects,
-- for use by the constructor.
SELECT c.shape.Get_WKT() INTO cola_b_wkt_clob
FROM cola_markets c WHERE = 'cola_b';
cola_b_wkt_varchar := cola_b_wkt_clob;
SELECT c.shape.Get_WKB() INTO cola_b_wkb
FROM cola_markets c WHERE = 'cola_b';
-- Use some SDO_GEOMETRY constructors;
-- insert 3 geometries into the table; display the geometries later.
cola_b_geom := SDO_GEOMETRY(cola_b_wkt_clob);
INSERT INTO cola_markets VALUES (101, 'cola_b_from_clob', cola_b_geom);
cola_b_geom := SDO_GEOMETRY(cola_b_wkt_varchar);
INSERT INTO cola_markets VALUES (102, 'cola_b_from_varchar', cola_b_geom);
cola_b_geom := SDO_GEOMETRY(cola_b_wkb);
INSERT INTO cola_markets VALUES (103, 'cola_b_from_wkb', cola_b_geom);
END;
/
PL/SQL procedure successfully completed.
-- Display the geometries created using SDO_GEOMETRY constructors.
-- All three geometries are identical.
SELECT name, shape FROM cola_markets WHERE mkt_id > 100;
NAME
--------------------------------
SHAPE(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES) --------------------------------------------------------------------------------
cola_b_from_clob
SDO_GEOMETRY(2003, NULL, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1),
SDO_ORDINATE_ARR
AY(5, 1, 8, 1, 8, 6, 5, 7, 5, 1))
cola_b_from_varchar
SDO_GEOMETRY(2003, NULL, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1),
SDO_ORDINATE_ARR
AY(5, 1, 8, 1, 8, 6, 5, 7, 5, 1))
cola_b_from_wkb
SDO_GEOMETRY(2003, NULL, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1),
SDO_ORDINATE_ARR
AY(5, 1, 8, 1, 8, 6, 5, 7, 5, 1))
2.5 例子大集合
2.5.1 矩形:SDO_GTYPE = 2003, SDO_SRID = NULL, SDO_POINT = NULL, SDO_ELEM_INFO = (1, 1003, 3), SDO_ORDINATES = (1, 1, 5, 7)
INSERT INTO cola_markets VALUES(
1,
'cola_a',
SDO_GEOMETRY(
2003, -- two-dimensional polygon
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,3), -- one rectangle (1003 = exterior)
SDO_ORDINATE_ARRAY(1,1, 5,7) -- only 2 points needed to
-- define rectangle (lower left and upper right) with
-- Cartesian-coordinate data
)
);
2.5.2 有洞的多边形:SDO_GTYPE = 2003, SDO_SRID = NULL, SDO_PONT = NULL,
SDO_ELEM_INFO = (1,1003,1,19,2003,1)这个声明了两个元素,1,1003,1与19,2003,1,1003表明这是一个外多边形,2003表明这是一个内多边形,SDO_ORDINATES = (2, 4, 4, 3, 10, 3, 13, 5, 13, 9, 11, 13, 5, 13, 2, 11, 2, 4, 7, 5, 7, 10, 10, 10, 10, 5, 7, 5)。

对于
SDO_GEOM.SDO_AREA函数来说,这个面积等于外多边形减内多边形的面积。

对于
SDO_GEOM.SDO_LENGTH函数来说,边长等于外多边形与内多边形的总和。

INSERT INTO cola_markets VALUES(
10,
'polygon_with_hole',
SDO_GEOMETRY(2003, -- two-dimensional polygon
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,1, 19,2003,1), -- polygon with hole
SDO_ORDINATE_ARRAY(2,4, 4,3, 10,3, 13,5, 13,9, 11,13, 5,13, 2,11, 2,4, 7,5, 7,10, 10,10, 10,5, 7,5)
)
);多边形不能多层嵌套,就是说A中有B,但B中不能再有C了。

2.5.3 组合线段: SDO_GTYPE = 2002, SDO_SRID = NULL, SDO_POINT = NULL,
SDO_ELEM_INFO = (1, 4, 2, 1, 2, 1, 3, 2, 2)这个表明4,2是说明这个元素是一个组合线段,由两
个子元素组成。

1,2,1说明这个元素是个直线段,坐标从第一个开始,3,2,2说明第二个元素为曲线,坐标从第三个开始,是个曲线,SDO_ORDINATES=(10,10,10,14,6,10,14,10)
INSERT INTO cola_markets VALUES(
11,
'compound_line_string',
SDO_GEOMETRY(
2002,
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,4,2, 1,2,1, 3,2,2), -- compound line string
SDO_ORDINATE_ARRAY(10,10, 10,14, 6,10, 14,10)
)
);
2.5.4 组合多边形:SDO_GTYPE=2003,
SDO_SRID=NULL,SDO_POINT=NULL,SDO_ELEM_INFO=(1,1005,2,1,2,1,5,2,2),SDO_ORDI NATES=(6,10,10,1,14,10,10,14,6,10)
INSERT INTO cola_markets VALUES(
12,
'compound_polygon',
SDO_GEOMETRY(
2003, -- two-dimensional polygon
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1005,2, 1,2,1, 5,2,2), -- compound polygon
SDO_ORDINATE_ARRAY(6,10, 10,1, 14,10, 10,14, 6,10)
)
);
2.5.5 点:SDO_GTYPE=2001,SDO_SRID=NULL,SDO_POINT=SDO_POINT_TYPE(12, 14, NULL),SDO_ELEM_INFO=NULL,SDO_ORDINATES=NULL
INSERT INTO cola_markets VALUES(
90,
'point_only',
SDO_GEOMETRY(
2001,
NULL,
SDO_POINT_TYPE(12, 14, NULL),
NULL,
NULL));
2.5.6 有向点:这是一个特殊的地理对象,它由一个点与一个虚拟的终点组成,它可以表示一个有方向的图标之类的东东。

SDO_GTYPE=2001,SDO_SRID=NULL, SDO_POINT = NULL,
SDO_ELEM_INFO=(1,1,1,3,1,0),SDO_ORDINATES=(12,14,0.3,0.2),12,14为点的坐标,0.3,0.2表示相对与起点的角度。

INSERT INTO cola_markets VALUES(
91,
'oriented_point',
SDO_GEOMETRY(
2001,
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1,1, 3,1,0),
SDO_ORDINATE_ARRAY(12,14, 0.3,0.2)));。

相关文档
最新文档