1. SDO_GEOMETRY的逻辑实现

SDO_GEOMETRY数据类型具有两个逻辑部件:

  • 几何体的空间参考系(也叫坐标系)
  • 元素数组(ElementArray)

概念类图如下图所示。

在这里插入图片描述

2. SDO_GEOMETRY的类型、属性和值

在oracle数据库中查看SDO_GEOMETRY的结构:

SQL> DESCRIBE SDO_GEOMETRY;
Element       Type                      
------------- ------------------------- 
SDO_GTYPE     NUMBER                    
SDO_SRID      NUMBER                    
SDO_POINT     MDSYS.SDO_POINT_TYPE      
SDO_ELEM_INFO MDSYS.SDO_ELEM_INFO_ARRAY 
SDO_ORDINATES MDSYS.SDO_ORDINATE_ARRAY  
GET_GTYPE     FUNCTION                  
GET_DIMS      FUNCTION                  
GET_LRS_DIM   FUNCTION                  
GET_WKB       FUNCTION                  
GET_WKT       FUNCTION                  
ST_COORDDIM   FUNCTION                  
ST_ISVALID    FUNCTION                  
SDO_GEOMETRY  FUNCTION                  
SDO_GEOMETRY  FUNCTION                  
SDO_GEOMETRY  FUNCTION    

共有5个属性:

  • SDO_GTYPE:表示几何对象实际形状的类型(点、线、面、多点、多线、多面)。
  • SDO_SRID:指定空间参考系。

后3个属性指定几何对象的坐标。

  • SDO_POINT:如果几何对象是点POINT类型,则将他的坐标存储在SDO_POINT中。否则,SDO_POINT属性置为空NULL

如果几何对象不是点POINT类型,如线POLYLINE面POLYGON,则将坐标存储在SDO_ELEM_INFO_ARRAYSDO_ORDINATE_ARRAY中。

  • SDO_ORDINATE:数组,存储所有集合对象的坐标。
  • SDO_ELEM_INFO:规定在SDO_ORDINATES数组中,一个新的元素从什么地方开始,怎么连接(直线还是弧),是点(最好直接存储在SDO_POINT属性中)、线还是面。

3. SDO_GTYPE属性

SDO_GTYPE是一个4位数字,格式为D00T

取值范围
第1位,D2 = 2维
3 = 3维
4 = 4维
第2位一般为0
第3位一般为0
第4位,T0 = 无解释类型
1 = 点,5 = 多点
2 = 线,6 = 多线
3 = 面,7 = 多面
4 = 集合
8 = 立方体
9 = 多重立方体

4. SDO_SRID属性

指定了集合对象的空间参考系。

一个表中,所有几何对象应该具有同样的 SDO_SRID 值。

就如同一个shapefile文件中,只能存储某一特定类型的几何对象。

5. SDO_POINT属性

该属性定义了点的坐标,如一棵树的位置。该属性的类型是SDO_POINT_TYPE类型。

在oracle数据库中查看 SDO_POINT_TYPE 类型:

SQL> DESCRIBE SDO_POINT_TYPE;
Element Type   
------- ------ 
X       NUMBER 
Y       NUMBER 
Z       NUMBER 

在数据表test_point表中插入一个点:

-- 方法1
insert into TEST_POINT (ID, NAME, GEOM)
values
 (
    1,
    'Tom',
    SDO_GEOMETRY(
        2001,   -- SDO_GTYPE
        4326,   -- SDO_SRID,4326表示 "WGS 84坐标系"
        SDO_POINT_TYPE(  -- SDO_POINT
          113.125,   -- 经度
          23.564,    -- 纬度
          NULL       -- 没有第三纬度,置为空
        ),
        NULL,
        NULL
    )
 );

-- 方法2
insert into TEST_POINT (ID, NAME, GEOM)
values
 (
    2,
    'Jerry',
    SDO_GEOMETRY(
        'POINT(113.126 23.835)',   -- WKT描述的点数据
        4326       -- SRID
    )
 );

注意:

  • 经纬度表示的点坐标,经度放在第一位,纬度放在第二位。
  • SDO_POINT只能存储二维或三维的点,对于四维的点,需要使用SDO_ELEM_INFOSDO_ORDINATES属性存储。

6. SDO_ORDINATES属性

该属性存储了几何对象所有维数的坐标。其类型是SDO_ORDINATE_ARRAY,本质是一个数字型的可变长度数组。

如果一个数据的维度是D,那么每D个连续的数就指定了一个坐标。

例如存储一条直线 A -- B -- C的数据内容为 ( X A , Y A , X B , Y B , X C , Y C ) (X_A, Y_A, X_B, Y_B, X_C, Y_C) (XA,YA,XB,YB,XC,YC)

7. SDO_ELEM_INFO属性

该属性的类型是SDO_ELEM_INFO_ARRAY

数组中,每3个连续的数可以组成一个三元描述符,用来描述几何对象或几何对象的一部分。

三元组的形式为 <offset, element-type interpretation>

  • offset:指定了元素的坐标在SDO_ORDINATES存储的起始索引。
  • element-type和interpretation:根据元素类型(点线面)的不同和边界连接方式的不同取不同的值。

7.1 总览

SDO_ELEM_TYPESDO_INTERPRETATION含义举例
0任意无效
11单点
1n(n>1)多点
21单线 (直线连接)
22单线(弧线连接)
每段弧线由3个点描述,前一段弧线的
终点是下一段弧线的起点。
1003 / 20031多边形(直线连接)
1003:外环
2003:内环
有洞的多边形
1003 / 20032多边形(弧线连接)
1003:外环
2003:内环
1003 / 20033矩形
用左下角和右上角两个点描述
1003 / 20034
用任意三个非共线的点坐标描述
4n(n>1)多线
详见下面的介绍
1005 / 2005n(n>1)多多边形
详见下面的介绍

7.2 单点、单线、单面(多边形)

  • offset:永远设置为1,SDO_ORDINATES中只有一个元素。
  • element-type:与几何体的SDO_GTYPE(格式D00T)中的T对应。
    • 点:1
    • 线:2
    • 面:1003
  • interpretation:表示一个元素所包含的更细微的信息。
    • 点:1。
    • 线或面:
      • 直线连接:1
      • 弧线连接:2
    • 矩形:3
    • 圆:4

注意:
多边形的外环按照逆时针指定顶点坐标,内环则是顺时针。

7.2.1 单点

直接存储在 SDO_POINT 属性中

SDO_GEOMETRY(
  2001,   -- SDO_GTYPE(格式D00T)
  4525,   -- SRID
  SDO_POINT_TYPE(37741879.441, 37766551.886),
  NULL,
  NULL
);

或者存储在 SDO_ORDINATES 属性中(不推荐)

SDO_GEOMETRY(
  2001, 
  4525,
  NULL,  -- SDO_POINT置为空
  SDO_ELEM_INFO_ARRAY(
    1,   -- offset=1,第一个元素(也只有一个元素)
    1,   -- element-type=1,表示点
    1    -- interpretation=1,表示单点
  ),
  SDO_ORDINATE_ARRAY(
    37741879.441,  -- X
    37766551.886   -- Y
  )
);
7.2.2 单线(直线连接)
SDO_GEOMETRY(
  2002,
  4525,
  NULL,
  SDO_ELEM_INFO_ARRAY(
    1,
    2,    -- e-type=2,表示线
    1     -- interpretation=1,表示直线连接
  ),
  SDO_ORDINATE_ARRAY(  -- <x, y>
    37750743.000, 2565769.866, -- 第1个点
    37757489.889, 2564711.530, -- 第2个点
    37759011.246, 2567092.785, -- 第3个点
    37755472.437, 2570102.426, -- 第4个点
    37757853.691, 2571524.565  -- 第5个点
  )
);
7.2.3 单线(弧线连接)

在这里插入图片描述

SDO_GEOMETRY(
  2002,
  4525,
  NULL,
  SDO_ELEM_INFO_ARRAY(
    1,
    2,  -- e-type=2,表示线
    2   -- interpretation=2,表示弧线连接
  ),
  SDO_ORDINATE_ARRAY(  -- <x, y>
    Xa, Ya,  -- A点
    Xb, Yb,  -- B点
    Xc, Yc,  -- C点
    Xd, Yd,  -- D点
    Xe, Ye   -- E点
    -- ABC构成一段弧线,CDE构成一段弧线,以此类推...
  )
);
7.2.4 多边形(直线连接)
SDO_GEOMETRY(
  2003,
  4525,
  NULL,
  SDO_ELEM_INFO_ARRAY(
    1,
    1003,  -- e-type=1003,表示多边形(外环),顶点逆时针顺序
    1      -- interpretation=1,表示直线连接
  ),
  SDO_ORDINATE_ARRAY(
    37750743.000, 2565769.866, -- 第1个点
    37757489.889, 2564711.530, -- 第2个点
    37759011.246, 2567092.785, -- 第3个点
    37755472.437, 2570102.426, -- 第4个点
    37757853.691, 2571524.565, -- 第5个点
    37750743.000, 2565769.866  -- 第1个点(首尾相接)
  )
);
7.2.5 多边形(弧线连接)

在这里插入图片描述

SDO_GEOMETRY(
  2003,
  4525,
  NULL,
  SDO_ELEM_INFO_ARRAY(
    1,
    1003,  -- e-type=1003,表示多边形(外环),顶点逆时针顺序
    2      -- interpretation=2,表示弧线连接
  ),
  SDO_ORDINATE_ARRAY(
    Xa, Ya,
    Xb, Yb,
    Xc, Yc,
    Xd, Yd,
    Xe, Ye,
    Xf, Yf,
    Xg, Yg,
    Xh, Yh,
    Xa, Ya  -- 首尾相接
  )
);
7.2.6 矩形

在这里插入图片描述

SDO_GEOMETRY(
  2003,
  4525,
  NULL,
  SDO_ELEM_INFO_ARRAY(
    1,
    1003,  -- e-type=1003,表示多边形(外环),顶点逆时针顺序
    3      -- interpretation=3,表示矩形
  ),
  SDO_ORDINATE_ARRAY(
    Xa, Ya,  -- 左下角坐标(A点)
    Xc, Yc   -- 右上角坐标(C点)
  )
);
7.2.7 圆

在这里插入图片描述

SDO_GEOMETRY(
  2003,
  4525,
  NULL,
  SDO_ELEM_INFO_ARRAY(
    1,
    1003,  -- e-type=1003,表示多边形(外环),顶点逆时针顺序
    4      -- interpretation=4,表示圆形
  ),
  SDO_ORDINATE_ARRAY( -- 圆上任意三点坐标
    Xa, Ya,   -- A点
    Xb, Yb,   -- B点
    Xc, Yc    -- C点
  )
);

特别注意:

圆和弧只能用在投影坐标系或本地坐标系中,不能用在地理坐标系(大地坐标系)中!!!

7.3 多点、多线、多面

TODO…

END

Thanks for Reading!

转载自作者个人网站:https://blog.icrystal.top/archives/7.html

作者:iCrystal
邮箱:leopard.c@outlook.com
博客:https://blog.icrystal.top
GitHub: https://github.com/Leopard-C

更多推荐