oracle spatial

2.

几何引擎:它提供了分析,比较和操作几何体的函数。
几何引擎函数:SDO_GEOM.SDO_DISTANCE
索引引擎:为了提高查询效率,ORACLE SPATIAL提供了空间索引引擎
几何引擎函数:SDO_NN(nearest neighbor),SDO_ANYINTERACT
检查在ORACLE DATABASE中是否安装了ORACLE SPATIAL
SQL> col comp_name format a10;
SQL> select comp_name,status from dba_registry where comp_name='Spatial';
COMP_NAME STATUS
---------- ----------------------
Spatial   VALID
SQL>
说明成功安装了,状态为VALID或是LOADED都可以

检查SPATIAL安装的版本
SQL> select sdo_version from dual;  //or select * from v$version ;
SDO_VERSION
-------------------------------------
11.2.0.1.0

ORACLE Spatial技术分布在两层上:数据库服务器(DATABASE SERVER)和应用服务器(APPLICATION SERVER)
数据库服务器(DATABASE SERVER):

l        高级空间引擎
Ø        路由
Ø        网络数据模型(NDM)
Ø        线性参考系统(LRS)
Ø        分析挖掘
Ø        拓扑和GEORASTER类型
Ø        拓扑数据模型
Ø        GEORASTER       查询和分析
Ø        所有引擎查询操作
Ø        几何引擎
l        数据模型
Ø        SDO_GEOMETRY样式
l        位置使能
Ø        ORACLE使用工具
Ø        地理编码器

应用服务器(APPLICATION SERVER):

l        可视化
Ø        地图缓冲服务器
Ø        FOI(feature-of-interrest,兴趣特性)服务器
Ø        渲染引擎

ORACLE Spatia支持以下的空间数据操作:
l        使用SDO_GEOMETRY数据类型存储数据模型
l        使用索引引擎和几何引擎进行查询分析
l        使用地理编码器通过转换地址数据到SDO_GEOMETRY数据实现位置使能
l        使用MAPVIEWER和ORACLE MAPS进行可视化
l        高级空间引擎功能,如网络分析和路由

LOCATOR的核心功能:

l        使用SDO_GEOMETRY数据类型存储存储空间数据的数据模型
l        使用索引引擎和几何引擎进行查询分析
l        SEO_GEOM.SDO_DISTANCE和SDO_GEOM.VALIDATE_GEOMETRY_XXX函数,这些函数也是LOCATOR的一部分

LOCATOR的的典型应用:

l        简单的GIS应用程序
l        简单的商业应用
l        CAD/CAM和类似的应用程序
LOCATO提供了SPATIAL技术的一个核心子集
3.
Spatial将一个表的SDO_GEOMETRY列的所有对象作为一个空间层

空间元数据的字典视图
SQL> desc user_sdo_geom_metadata;名称                                     是否为空?类型----------------------------------------- -------- -------------------------TABLE_NAME                                NOT NULL VARCHAR2(32)COLUMN_NAME                              NOT NULL VARCHAR2(1024)DIMINFO                                     MDSYS.SDO_DIM_ARRAYSRID                                         NUMBER

SRID的属性
大地坐标系(GEODETIC):角坐标,用来对应地球表面的“经度,维度”来表示
投影坐标系(PROJECTED):直角坐标系
本地坐标系(LOCAL):直角坐标系,与地球表面无关,有时是某一应用专用的。

大地坐标系的SRID属性
SQL> select srid from mdsys.cs_srs where wktext like 'GEOGCS%';
投影坐标系的SRID属性
SQL> select srid from mdsys.cs_srs where wktext like 'PROJCS%';
本地坐标系的SRID属性
SQL>select sridfrommdsys.cs_srswherewktext like'LOCAL_CS%';
DIMINFO的属性
空间数据库本质上是多维的
SQL> desc sdo_dim_array;SDO_DIM_ARRAY VARRAY(4) OF MDSYS.SDO_DIM_ELEMENT名称                                     是否为空?类型----------------------------------------- -------- ------------------------SDO_DIMNAME                                    VARCHAR2(64)SDO_LB                                            NUMBERSDO_UB                                            NUMBERSDO_TOLERANCE                                   NUMBER

SDO_DIM_ARRAY是一个可变长度的SDO_DIM_ELEMENT类型的数组。
每一个SDO_DIM_ELEMENT类型存储一个指定维度的信息
容差和容差值
容差值应该被设置为应用程序中的最小可区别的距离

4.
点:可以用来存储实体的位置坐标
线串:用来存贮某一路段的位置及形状
多边形:用来存储城市的边界,商业区等
复杂的几何体:多重多边形

点事最简单的几何体
一个线串连接多个不同的点
元素数组描述了SDO_GEOMETRY对象的形状和位置。这个元素组构成了SDO_GEOMETRY对象。

SQL> conn mvdemo/spatial@QILIN
已连接。
SQL> desc sdo_geometry;名称                                     是否为空?类型----------------------------------------- -------- ---------------------------SDO_GTYPE                                         NUMBERSDO_SRID                                          NUMBERSDO_POINT                                         MDSYS.SDO_POINT_TYPESDO_ELEM_INFO                                     MDSYS.SDO_ELEM_INFO_ARRAYSDO_ORDINATES                                     MDSYS.SDO_ORDINATE_ARRAY

SDO_GTYPE属性:表示几何体实际形状的类型(点,线串,多边形,集合,多重点,多重线串或多重多边形)
SDO_SRID属性:指定空间参考系的ID

SDO_GTYPE是一个4位的数字,结构为D00T。第一位和最后一位根据几何体的维数和形状采用不同的值。第二位和第三位通常被设置成0
•        SDO_POINT:如果几何体是一个点,可以把它的坐标存储到SDO_GEOETRY的SDO_POINT属性中
•        如果几何体是一个任意形状(如街区网络和城市边界),则可以把它的坐标存储到SDO_ORDINATES和SDO_ELEM_INFO数组属性:
SDO_ORDINATES:存储所有几何体元素的坐标
SDO_ELEM_INFO:规定在SDO_ORDINATES数组中,一个新的元素从什么地方开始,怎么连接,是点,线串还是多边形

D在D00T中用来存储几何体对象的维度。可以表示从2维到4维的空间对象
SDO_GTYPE中的T规定了几何体的类型和形状


在一个特定的基础上,通过坐标来定位地球表面上的数据,被称为大地坐标系或是大地空间参考系
等积投影保留了物体的面积,但是方向和距离都不再被保持。
等距投影在测量由投影区域中心到远处目的的距离有较大优势
通过选择合适的投影技术和三维参考基准,地球表面的位置能够在二维平面中表示,这种使用特定基准和合适投影的参考,被称为投影坐标系或是投影空间参考系

SQL> desc mdsys.cs_srs;
名称                                     是否为空?类型
---------------------------------------- -------- ----------------
CS_NAME                                 VARCHAR2(80)
SRID                                      NOT NULL NUMBER(38)
AUTH_SRID                               NUMBER(38)
AUTH_NAME                              VARCHAR2(256)
WKTEXT                                 VARCHAR2(2046)
CS_BOUNDS                              MDSYS.SDO_GEOMETRY
WKTEXT3D                               VARCHAR2(4000)

EPSG坐标系的类型:
SQL> select distinct coord_ref_sys_kind from sdo_coord_ref_sys;
COORD_REF_SYS_KIND
------------------------
PROJECTED
GEOGRAPHIC2D
GEOCENTRIC
VERTICAL
ENGINEERING
COMPOUND
GEOGENTRIC
GEOGRAPHIC3D

已选择8行。

一维坐标系
二维坐标系
3D坐标系
本地坐标系

SQL> select sdo_cs.find_proj_crs(41155,'FALSE') epsg_srid from dual;
EPSG_SRID
----------------------------------------------------
SDO_SRID_LIST(32041)
SDO_PINT仅能够存储三个坐标。也就是说在数据是三维或是低于三维的时候才合适。对于四维的点,只能使用SDO_ELEM_INFO和SDO_ORDINATES的属性
SDO_POINT属性
SQL> desc sdo_point_type;
名称                                     是否为空?类型
----------------------------------------- -------- ----------------
X                                                 NUMBER
Y                                                 NUMBER
Z                                                 NUMBER
SDO_ORDINATES存贮几何体中所有元素的顶点,而SDO_ELEM_INFO存储的是上述元素的类型和在SDO_ORDINATES中的起始地址
当SRID对应于一个大地坐标系的时候,你不能指定园或弧。园和弧只在投影或本地坐标系中有效。在大地坐标系中,可以通过增加圆周上点的密度和用SDO_UTIL.ARC_DENSIFY函数把这些点表示为线性多边形来近似表示圆和弧。
Mapinfo地图在ORACLE中的存储和管理方式
ORACLE为管理空间数据库提供了对象管理模式SDO(SPATIAL DATA OBJECT),同时提供优秀的空间索引机制
 MDSYS是ORACLE SPATIAL的管理用户
 MDSYS方案中,表SDOGEOM-METADATA-TABLE存储所有上传到ORACLE中的MAPINFO地图信息,
               表SDO-INDEX-METADATA-TABLE存储与索引相关的信息
上传到ORACLE中的每一个地图由两个表表示,
一个与该地图空间索引方式相关的表,叫做索引表,
另一个用来存储地图属性数据和空间数据,称为数据表。
MAPX控件有两种方式访问ORACLE中的空间数据,一种为ODBC方式,一种为OCI方式。
ODBC方式的缺点是通用接口,速度慢,需要配置数据源DNS.
OCI方式的优点是底层接口,速度快。
一个典型的MapInfo表是由5文件组成
n      TAB–确定表的结构,如字段名、排序、长度和类型
n      DAT–包含表中每一个字段的数据
n      MAP–描述图形对象
n      ID–联接表和图形数据的对照表文件
n      IND–包含表中索引字段信息,索引字段可以利用“查询>查找”命令

空间索引
l      空间索引能加快空间操作符在ORACLE表的SDO_GEOMETRY列上的执行速度
l      在创建空间索引之前必须要为空间层(table_name,column_table)插入元数据
l      空间索引的元数据存储在视图USER_SDO_INDEX_METADATA中,本视图中存储空间索引名称(SDO_INDEX_NAME),存放索引的表(SDO_INDEX_TABLE)

SQL> desc user_sdo_index_info;
SQL> desc user_sdo_index_metadata;
SQL> desc sdo_index_metadata;
1建立索引之前为空间层插入元数据
SQL> desc user_sdo_geom_metadata;
名称                                     是否为空?类型
----------------------------------------- -------- ----------------------------
TABLE_NAME                                NOT NULL VARCHAR2(32)
COLUMN_NAME                              NOT NULL VARCHAR2(1024)
DIMINFO                                     MDSYS.SDO_DIM_ARRAY
SRID                                              NUMBER
SQL> select * from user_sdo_geom_metadata;
TABLE_NAME               COLUMN_NAME                   DIMINFO      SRID
----------               ----------------------------- -------       ----------
CUSTOMERS                       LOCATION               <Object      8307
GC_ROAD_SEGMENT_US              GEOMETRY               <Object      8307
US_RESTAURANTS                  LOCATION               <Object      8307
US_INTERSTATES                  GEOM                   <Object      8307

为对应于customer表的LOCATION列的空间层插入元数据
user_sdo_geom_metadata是个视图
INSERT INTO user_sdo_geom_metadata
(table_name, column_name, srid, diminfo)
VALUES
(
'CUSTOMERS', -- TABLE_NAME
'LOCATION', -- COLUMN_NAME
8307, -- SRID specifying a geodetic coordinate system
SDO_DIM_ARRAY -- DIMINFO attribute for storing dimension bounds, tolerance
(
  SDO_DIM_ELEMENT
  (
    'LONGITUDE', -- DIMENSION NAME for first dimension
    -180, -- SDO_LB for the dimension: -180 degrees
    180, -- SDO_UB for the dimension: 180 degrees
    0.5 -- Tolerance of 0.5 meters (not 0.5 degrees: geodetic SRID)
  ),
  SDO_DIM_ELEMENT
  (
    'LATITUDE', -- DIMENSION NAME for second dimension
    -90, -- SDO_LB for the dimension: -90 degrees
    90, -- SDO_UB for the dimension: 90 degrees
    0.5 -- Tolerance of 0.5 meters (not 0.5 degrees: geodetic SRID)
  )
)

);

DIMINFO域为每个维定义了边界和容差(TOLERANE).它的值被设置为一个含有两个元素的SDO_DIM_ARRAY对象.

2创建空间索引
l      首先删除索引:
DROP INDEX CUSTOMERS_SIDX;
DROP INDEX CUSTOMERS_SIDX FORCE;(强力删除空间索引,由于该空间索引正在使用,需要强迫删除它)
l      其次创建索引:

CREATE INDEX CUSTOMERS_SIDX ON CUSTOMERS(LOCATION) INDEXTYPE IS MDSYS.SPATIAL_INDEX;
l      验证空间索引是否创建成功:主要查看视图user_indexes中字段domidx_statUs

SQL> select domidx_statUs,taBLE_name from user_indexes where table_name='SPOT_CDMA';
DOMIDX_STATUS TABLE_NAME
------------ ------------------------------
VALID        SPOT_CDMA
            SPOT_CDMA
            SPOT_CDMA
            SPOT_CDMA

l      重命名空间索引:索引名称不能超过18位
ALTER INDEX OLDINDEX RENAME TO NEWINDEX
SQL> SELECT SDO_INDEX_TABLE FROM USER_SDO_INDEX_INFO WHERE TABLE_NAME='SPOT_CDMA' AND COLUMN_NAME='GEOLOC';
SDO_INDEX_TABLE
--------------------------------
MDRT_1F7B5$
SDO_INDEX_TABLE(即空间索引表)的名称为MDRT_1F7B5$。所有空间索引表的的明长城都是以前缀MDRT开头的。
SQL> SELECT SDO_INDEX_TABLE FROM USER_SDO_INDEX_INFO;
SDO_INDEX_TABLE
--------------------------------
MDRT_1F0B4$
MDRT_1F0AA$
MDRT_1F0A1$
MDRT_1F097$
MDRT_1F08D$
MDRT_1F083$
MDRT_1F079$
MDRT_1F072$
MDRT_1F068$
MDRT_1F05E$
MDRT_1F054$
MDRT_1F04A$
MDRT_1F040$
MDRT_1F039$
MDRT_1F032$
MDRT_1F029$
MDRT_1F01F$
MDRT_1F7B5$
MDRT_1EFDB$

19 rows selected

通过查询USER_SDO_INDEX_INFO视图的SDO_INDEX_TABLE列。可以得到所有的空间索引表。

3空间索引的参数信息

创建空间索引的语法:
CREATE INDEX <indexname> ON <tablename>(<columnname>)
INDEXTYPE IS MDSYS.SPATIAL_INDEX
PARAMETERS ('parameter_string');
l      TABLSPACE参数
通过这个参数,可以指定用哪个表空间来存储空间索引表。EG:tablesspace= TBS_3会将空间索引表存储在空间表空间TBS_3中
CREATE INDEX customers_sidx ON customers(location)
INDEXTYPE IS MDSYS.SPATIAL_INDEX
PARAMETERS ('TABLESPACE=TBS_3');
l      WORK_TABLSPACE参数
创建和删除大量不同大小的表会使表空间产生很多的空间碎片。为了避免这种情况,可以使用WORK_TABLSPACE参数来为这些工作表指定一个单独的表空间
CREATE INDEX customers_sidx ON customers(location)
INDEXTYPE IS MDSYS.SPATIAL_INDEX
PARAMETERS ('WORK_TABLESPACE= TBS_4');
l      SDO_DML_BATCH_SIZE参数
在含有空间索引的表的插入和删除操作并未直接纳入该空间索引。相反,他们是在事务提交时被批量的纳入该索引中。这个参数用于指定一个事务中批量插入删除更新时的批量大小(对有大量插入的事务,该参数应该设置为50000或是10000)。
CREATE INDEX customers_sidx ON customers(location)
INDEXTYPE IS MDSYS.SPATIAL_INDEX
PARAMETERS ('SDO_DML_BATCH_SIZE=5000');
4 USER_SDO_INDEX_METADATA视图
SQL> desc user_sdo_index_metadata;
名称                                     是否为空?类型
----------------------------------------- -------- -------------------
SDO_INDEX_OWNER                                   VARCHAR2(32)
SDO_INDEX_TYPE                                    VARCHAR2(32)
SDO_LEVEL                                         NUMBER
SDO_NUMTILES                                      NUMBER
SDO_MAXLEVEL                                      NUMBER
SDO_COMMIT_INTERVAL                               NUMBER
SDO_INDEX_TABLE                                   VARCHAR2(32)
SDO_INDEX_NAME                                    VARCHAR2(32)
SDO_INDEX_PRIMARY                                 NUMBER
SDO_TSNAME                                        VARCHAR2(32)
SDO_COLUMN_NAME                                 VARCHAR2(2048)
SDO_RTREE_HEIGHT                                  NUMBER
SDO_RTREE_NUM_NODES                               NUMBER
SDO_RTREE_DIMENSIONALITY                          NUMBER
SDO_RTREE_FANOUT                                  NUMBER
SDO_RTREE_ROOT                                    VARCHAR2(32)
SDO_RTREE_SEQ_NAME                                VARCHAR2(32)
SDO_FIXED_META                                    RAW(255)
SDO_TABLESPACE                                    VARCHAR2(32)
SDO_INITIAL_EXTENT                                VARCHAR2(32)
SDO_NEXT_EXTENT                                   VARCHAR2(32)
SDO_PCTINCREASE                                   NUMBER
SDO_MIN_EXTENTS                                   NUMBER
SDO_MAX_EXTENTS                                   NUMBER
SDO_INDEX_DIMS                                    NUMBER
SDO_LAYER_GTYPE                                   VARCHAR2(32)
SDO_RTREE_PCTFREE                                 NUMBER
SDO_INDEX_PARTITION                               VARCHAR2(32)
SDO_PARTITIONED                                   NUMBER
SDO_RTREE_QUALITY                                 NUMBER
SDO_INDEX_VERSION                                 NUMBER
SDO_INDEX_GEODETIC                                VARCHAR2(8)
SDO_INDEX_STATUS                                  VARCHAR2(32)
SDO_NL_INDEX_TABLE                                VARCHAR2(33)
SDO_DML_BATCH_SIZE                                NUMBER
SDO_RTREE_ENT_XPND                                NUMBER
SDO_ROOT_MBR                                      MDSYS.SDO_GEOMETRY

可以查询参数信息

SQL> select sdo_tablespace from user_sdo_index_metadata;

5空间索引大小需求确定
SELECT sdo_tune.estimate_rtree_index_size
(
'SPATIAL', -- schema name
'CUSTOMERS', -- table name
'LOCATION' -- column name on which the spatial index is to be built
) sz
FROM dual;
6向表中添加位置信息
第一:创建普通表
CREATE TABLE customers
(id NUMBER,
datasrc_id NUMBER,
name VARCHAR2(35),
category VARCHAR2(30),
street_number VARCHAR2(5),
street_name VARCHAR2(60),
city VARCHAR2(32),
postal_code VARCHAR2(16),
state VARCHAR2(32),
phone_number VARCHAR2(15),
customer_grade VARCHAR2(15)
);


第二向创建好的表中插入数据
INSERT INTO customers VALUES
(1, -- id
1, -- datasrc_id
'Pizza Hut' , -- name
'Restaurant', -- restaurant
'134', -- street_number
'12TH STREET', -- street_name
'WASHINGTON', -- city
'20003', -- postal_code
'DC', -- state
NULL, -- phone_number
'GOLD' -- customer_grade’
);


第三向刚才创建好的普通表上添加位置信息
SQL> alter table customers add (location sdo_geometry);
表已更改。
SQL> desc customers;
名称                                     是否为空? 类型
---------------------------              --------     ---------------------
ID                                                NUMBER
DATASRC_ID                                        NUMBER
NAME                                              VARCHAR2(35)
CATEGORY                                          VARCHAR2(30)
STREET_NUMBER                                    VARCHAR2(5)
STREET_NAME                                       VARCHAR2(60)
CITY                                              VARCHAR2(32)
POSTAL_CODE                                        VARCHAR2(16)
STATE                                             VARCHAR2(32)
PHONE_NUMBER                                      VARCHAR2(15)
CUSTOMER_GRADE                                    VARCHAR2(15)
LOCATION                                             PUBLIC.SDO_GEOMETRY

有了LOCATION列插入数据
INSERT INTO customers
(ID,
DATASRC_ID,
NAME,
CATEGORY,
STREET_NUMBER,
STREET_NAME,
CITY,
POSTAL_CODE,
STATE,
PHONE_NUMBER,
CUSTOMER_GRADE
)
VALUES
(
1, -- id
1, -- datasrc_id
'Pizza Hut' , -- name
'Restaurant', -- restaurant
'134', -- street_number
'12TH STREET', -- street_name
'WASHINGTON', -- city
'20003', -- postal_code
'DC', -- state
NULL, -- phone_number
'GOLD' -- customer_grade’
);


第四查询customers;表中的具体客户的地址信息
SQL> select street_number,street_name,city,state,postal_code from customers where id=1;
STREET_NUMBER    STREET_NAME     CITY                            STATE                           POSTAL_CODE
-------------    --------------  ------------------              -----------------               ------------
134          12TH STREET         WASHINGTON                      DC                              20003
第五修改地理编码地址以获得显示的空间信息
UPDATE customers
SET location =SDO_GCDR.GEOCODE_AS_GEOMETRY
(
'SPATIAL',

SDO_KEYWORDARRAY

(
street_number || '' || street_name, -- add whitespace between street_number and street_name
city || ',' || state || ' ' || postal_code

),

'US'

) ;

ORACLE SPATIAL使你能够转换地址(street_number, street_name, city和postal_code)为一个在地球表面上的二维点位置

SDO_GCDR.GEOCODE_AS_GEOMETRY这个函数分别采用模式名称和地理编码数据集名称作为第一个和最后一个参数

第二个参数是一个SDO_KEYWORDARRAY对象,由地址部件street_number, street_name, city和postal_code构成


第六查询显示的结果

SQL> SELECT location;
2 FROM customers
3 WHERE id=1;


LOCATION(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)

--------------------------------------------------------------------------------

SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE(-77.01324, 38.8936, NULL), NULL, NULL)


第七使用SDO_GEOMETRY构造函数更新LOCATION列

UPDATE customers

SET location =

SDO_GEOMETRY

(

2001, -- Specify that location is a point

8307, -- Specify coordinate system id

SDO_POINT_TYPE(-77.06, 38.94, NULL), -- Specify coordinates here

NULL,

NULL

)

WHERE id=1;


第八为CUSTOMERS表的LOCATION列相对应的空间层插入元数据

INSERT INTO USER_SDO_GEOM_METADATA VALUES

(

'CUSTOMERS', -- TABLE_NAME

'LOCATION', -- COLUMN_NAME

SDO_DIM_ARRAY -- DIMINFO attribute for storing dimension bounds, tolerance

(
SDO_DIM_ELEMENT
(
'LONGITUDE', -- DIMENSION NAME for first dimension
-120, -- SDO_LB for the dimension
120, -- SDO_UB for the dimension
0.5 -- Tolerance of 0.5 meters
),
SDO_DIM_ELEMENT
(
'LATITUDE', -- DIMENSION NAME for second dimension
-70, -- SDO_LB for the dimension
70, -- SDO_UB for the dimension
0.5 -- Tolerance of 0.5 meters
)

),

8307 -- SRID value for specifying a geodetic coordinate system

);


第九

SQL> DESC SDO_GEOMETRY;
名称                                     是否为空?类型
----------------------------------------- -------- -------------------------

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

SDO_POINT仅能够存储三个坐标(X,Y和Z).这就是说在数据是三维或低于三维的时候才适合。对于四维的点,只能使用SDO_ELEM_INFO和SDO_ORDINATES属性。


l        查询CUSTOMER表中LOCATION列的SDO_GTYPE

SQL> select ct.location.sdo_gtype from customers ct ;


LOCATION.SDO_GTYPE

------------------
            2001

l        SDO_SRID这个属性为几何体规定了空间参考系或是坐标系,选择一个合适的坐标系需要看以下的表

SQL> desc mdsys.cs_srs;
名称                                     是否为空?类型
----------------------------------------- -------- ---------------------

CS_NAME                                           VARCHAR2(80)
SRID                                     NOT NULL NUMBER(38)
AUTH_SRID                                         NUMBER(38)
AUTH_NAME                                         VARCHAR2(256)
WKTEXT                                            VARCHAR2(2046)
CS_BOUNDS                                         MDSYS.SDO_GEOMETRY
WKTEXT3D                                          VARCHAR2(4000)

l        SDO_POINT这个属性定义了点的坐标,例如客户的位置。这个属性的类型是另一种对象类型SDO_POINT_TYPE.

SQL> DESC SDO_POINT_TYPE;
名称                                     是否为空?类型
----------------------------------------- -------- ---------

X                                                 NUMBER
Y                                                 NUMBER
Z                                                 NUMBER


n      构造简单二维几何体的案例来插入数据(充分使用SDO_ELEM_INFO和SDO_ORDINATES属性)

第一:创建一个存储所有几何示例的表

CREATE TABLE geometry_examples

(

name VARCHAR2(100),

description VARCHAR2(100),

geom SDO_GEOMETRY

);

SQL> desc geometry_examples;
名称                                     是否为空?类型
----------------------------------------- -------- --------------------

NAME                                              VARCHAR2(100)
DESCRIPTION                                       VARCHAR2(100)
GEOM                                              PUBLIC.SDO_GEOMETRY

第二:插入数据

INSERT INTO geometry_examples (name, description, geom) VALUES

(
'POINT',
'2-dimensional Point at coordinates (-79,37) with srid set to 8307',
SDO_GEOMETRY
(
  2001, -- SDO_GTYPE format: D00T. Set to 2001 for a 2-dimensional point
  8307, -- SDO_SRID (geodetic)
  SDO_POINT_TYPE
  (
    -79, -- ordinate value for Longitude
    37, -- ordinate value Latitude
    NULL -- no third dimension (only 2 dimensions)
  ),
  NULL,
  NULL
)

);

ORACLE SPATIAL要求经度坐标放在第一位,维度坐标放在第二维。

第三:用熟知文本(SQL/MM)来构造一个点几何体

SELECT SDO_GEOMETRY(' POINT(-79 37) ', 8307) geom FROM DUAL;

GEOM(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)

----------------------------------------------------------------------------

SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE(-79, 37, NULL), NULL, NULL)

第四:在SDO_ORDINATES数组中(而不是SDO_POINT中)存储点坐标
INSERT INTO geometry_examples VALUES
(
'2-D POINT stored in SDO_ORDINATES',
'2-dimensional Point at coordinates (-79, 37) with srid set to 8307',
SDO_GEOMETRY
(
  2001, -- SDO_GTYPE format: D00T. Set to 2001 for as a 2-dimensional point
  8307, -- SDO_SRID
  NULL, -- SDO_POINT attribute set to NULL
  SDO_ELEM_INFO_ARRAY -- SDO_ELEM_INFO attribute (see Table 4-2 for values)
  (
    1, -- Offset is 1
    1, -- Element-type is 1 for a point
    1 -- Interpretation specifies # of points. In this case 1.
  ),
  SDO_ORDINATE_ARRAY -- SDO_ORDINATES attribute
  (
    -79, -- Ordinate value for Longitude
    37 -- Ordinate value for Latitude
  )
)

);

Offset:永远设置为1,因为在SDO_ORDINATES中只有一个元素

Element-type:与几何体的SDO_GTYPE类型中的T值直接对应

Interpretation:表示一个元素更细微的信息


第五:认识SDO_ELEM_INFO和SDO_ORDINATES属性

SDO_ELEM_INFO属性是SDO_ELEM_INFO_ARRAY类型的,这个类型同样是一个数字型VARRAY,最大容量是1048576个数字。

SDO_ORDINATES属性是SDO_ORDINATE_ARRAY类型的,这个想是一个数字型VARRAY(可变长度数组)


第五:了解存储四维点的案例

INSERT INTO geometry_examples VALUES

(
'4-D POINT',
'4-dimensional Point at (Xa=>2, Ya=>2, Za=>2, La=>2) with srid set to NULL',
SDO_GEOMETRY
(
  4001, -- SDO_GTYPE: D00T. Set to 4001 as it is a 4-dimensional point
  NULL, -- SDO_SRID
  NULL, -- SDO_POINT_TYPE is null
  SDO_ELEM_INFO_ARRAY(1,1,1), -- Indicates a point element
  SDO_ORDINATE_ARRAY(2,2,2,2) -- Store the four ordinates here
)

);


n      通过直线连接的线串(充分使用SDO_ELEM_INFO和SDO_ORDINATES属性)

为二维的线串插入值

INSERT INTO geometry_examples VALUES
(
'LINE STRING',
'2-D line string connecting A(Xa=>1,Ya=>1),B(Xb=>2, Yb=>2), C(Xc=>2,Yc=>1)',
SDO_GEOMETRY
(
  2002, -- SDO_GTYPE: D00T. Set to 2002 as it is a 2-dimensional line string
  32774, -- SDO_SRID
  NULL, -- SDO_POINT_TYPE is null
  SDO_ELEM_INFO_ARRAY -- SDO_ELEM_INFO attribute (see Table 4-2 for values)
  (
    1, -- Offset is 1
    2, -- Element-type is 2 for a LINE STRING
    1 -- Interpretation is 1 if line string is connected by straight lines.
  ),
  SDO_ORDINATE_ARRAY -- SDO_ORDINATES attribute
  (
    1,1, -- Xa, Ya values
    2,2, -- Xb, Yb values
    2,1 -- Xc, Yc values
  )
)
);

n      通过弧线连接的线串(充分使用SDO_ELEM_INFO和SDO_ORDINATES属性)
为二维的弧线插入值

INSERT INTO geometry_examples VALUES
(
'ARCSTRING',
'2-D arc connecting A(Xa=>1,Ya=>1),B(Xb=>2, Yb=>2), C(Xc=>2,Yc=>1)',
SDO_GEOMETRY
(
  2002, -- SDO_GTYPE: D00T. Set to 2002 as it is a 2-dimensional line string
  32774, -- SDO_SRID
  NULL, -- SDO_POINT_TYPE is null
  SDO_ELEM_INFO_ARRAY -- SDO_ELEM_INFO attribute (see Table 4-2 for values)
  (
    1, -- Offset is 1
    2, -- Element-type is 2 for a LINE STRING
    2 -- Interpretation is 2 if line string is connected by ARCs.
  ),
  SDO_ORDINATE_ARRAY -- SDO_ORDINATES attribute
  (
    1,1, -- Xa, Ya values
    2,2, -- Xb, Yb values
    2,1 -- Xc, Yc values
  )
));

n      多边形,边界通过直线连接的环(充分使用SDO_ELEM_INFO和SDO_ORDINATES属性)
为直线连接的多边形插入值
INSERT INTO geometry_examples VALUES
(
'POLYGON',
'2-D polygon connecting A(Xa, Ya), B(Xb, Yb), C(Xc, Yc), D(Xd, Yd)',
SDO_GEOMETRY
(
  2003,  -- SDO_GTYPE: D00T. Set to 2003 as it is a 2-dimensional polygon
  32774, -- SDO_SRID
  NULL,  -- SDO_POINT_TYPE is null
  SDO_ELEM_INFO_ARRAY -- SDO_ELEM_INFO attribute (see Table 4-2 for values)
  (
    1,     -- Offset is 1
    1003,  -- Element-type is 1003 for an outer POLYGON element
    1      -- Interpretation is 1 if boundary is connected by straight lines.
  ),
  SDO_ORDINATE_ARRAY -- SDO_ORDINATES attribute
  (
    1,1,   -- Xa, Ya values
    2,-1,  -- Xb, Yb values
    3,1,   -- Xc, Yc values
    2,2,   -- Xd, Yd values
    1,1    -- Xa, Ya values : Repeat first vertex to close the ring
  )
));

n      圆(充分使用SDO_ELEM_INFO和SDO_ORDINATES属性)
为圆插入值
INSERT INTO geometry_examples VALUES
(
'CIRCLE POLYGON',
'2-D circle polygon with 3 boundary points A(Xa,Ya), B(Xb,Yb), C(Xc,Yc)',
SDO_GEOMETRY
(
  2003,    -- SDO_GTYPE: D00T. Set to 2003 as it is a 2-dimensional polygon
  32774,   -- SDO_SRID
  NULL,    -- SDO_POINT_TYPE is null
  SDO_ELEM_INFO_ARRAY -- SDO_ELEM_INFO attribute (see Table 4-2 for values)
  (
    1,     -- Offset is 1
    1003,  -- Element-type is 1003 for (an outer) POLYGON
    4      -- Interpretation is 4 if polygon is a CIRCLE
  ),
  SDO_ORDINATE_ARRAY -- SDO_ORDINATES attribute
  (
    1,1,   -- Xa, Ya values
    3,1,   -- Xb, Yb values
    2,2    -- Xc, Yc values
  )
));
查询相关属性值的内容

SQL> select ge.geom.sdo_elem_info from geometry_examples ge;
GEOM.SDO_ELEM_INFO
--------------------------------------------------------------------------------
SDO_ELEM_INFO_ARRAY(1, 1, 1)
SDO_ELEM_INFO_ARRAY(1, 1, 1)
SDO_ELEM_INFO_ARRAY(1, 2, 1)
SDO_ELEM_INFO_ARRAY(1, 2, 2)
SDO_ELEM_INFO_ARRAY(1, 1003, 1)
SDO_ELEM_INFO_ARRAY(1, 1003, 4)
已选择7行。
SQL> select ge.geom.sdo_ordinates from geometry_examples ge;
GEOM.SDO_ORDINATES
--------------------------------------------------------------------------------
SDO_ORDINATE_ARRAY(-79, 37)
SDO_ORDINATE_ARRAY(2, 2, 2, 2)
SDO_ORDINATE_ARRAY(1, 1, 2, 2, 2, 1)
SDO_ORDINATE_ARRAY(1, 1, 2, 2, 2, 1)
SDO_ORDINATE_ARRAY(1, 1, 2, -1, 3, 1, 2, 2, 1, 1)
SDO_ORDINATE_ARRAY(1, 1, 3, 1, 2, 2)
已选择7行。

SQL> select ge.geom.sdo_point from geometry_examples ge;
GEOM.SDO_POINT(X, Y, Z)
--------------------------------------------------------------------------------
SDO_POINT_TYPE(-79, 37, NULL)
已选择7行。

SQL> select ge.geom.sdo_srid from geometry_examples ge;
GEOM.SDO_SRID
-------------
       8307
       8307

      32774
      32774
      32774
      32774
已选择7行。

SQL> select ge.geom.sdo_gtype from geometry_examples ge;
GEOM.SDO_GTYPE

--------------
        2001
        2001
        4001
        2002
        2002
        2003
        2003

已选择7行。

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函数来指定其它的公差值。
获取2001后面最后一位的数字,使用GET_GTYPE方法

SQL> select ge.geom.get_gtype() from geometry_examples ge;。
获取2001后面第一位的数字,使用get_lrs_dim()方法。该方法用来获取一个空间对象的维度数,比如2维,3维等

SQL> select ge.geom.get_dims() from geometry_examples ge;
获取2001后面第二位的数字,使用get_lrs_dim()方法

SQL> select ge.geom.get_lrs_dim() from geometry_examples ge;
获取坐标维度 与Get_Dims返回相同的结果
selectge.geom.st_coorddim()fromgeometry_examples ge;

获取地理对象的有效返回值

selectge.geom.st_isvalid()fromgeometry_examples ge;
selectge.geom.Get_WKT()fromgeometry_examples gewherename='POINT';
selectTO_CHAR(ge.geom.Get_WKT())fromgeometry_examples gewherename='POINT';
selectge.geom.Get_WKB()fromgeometry_examples gewherename='POINT';


修改相关属性值的内容

调试空间数据库运用的函数
Getnumelem
Getnumverticces
Getvertices
SELECT SDO_UTIL.GETNUMELEM(geom) nelem
FROM sales_regions
WHERE id=10000;
SELECT SDO_UTIL.GETNUMVERTICES(geom) nverts
FROM sales_regions
WHERE id=10000;


查询相关的内容
Sdo_geometry类型,属性和值

SQL> desc 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      

l      SDO_GTYPE属性
SQL> select tb.geoloc.SDO_GTYPE from tbgrid tb;
SQL> select distinct tb.geoloc.SDO_GTYPE from tbgrid tb;

GEOLOC.SDO_GTYPE

----------------
          2003

2003表示是一个2维多重面或是多重边

l      SDO_SRID属性

SQL> select distinct tb.geoloc.SDO_SRID from tbgrid tb;
GEOLOC.SDO_SRID
---------------
         8307
8307表示是大地坐标系,是一个固定的值
l      SDO_POINT属性
SQL> desc sdo_point_type
名称                                     是否为空?类型
X                                                 NUMBER
Y                                                 NUMBER
Z                                                 NUMBER

SQL>select tb.geoloc.SDO_POINTfromtbgrid tb;
SQL>select tb.geoloc.SDO_POINT.xfromtbgrid tb;
SQL>select tb.geoloc.SDO_POINT.yfromtbgrid tb;
SQL>select tb.geoloc.SDO_POINT.zfromtbgrid tb;

SDO_ELEM_INFO属性

SQL> desc sdo_elem_info_array;
SDO_ELEM_INFO_ARRAY VARRAY(1048576) OF NUMBER

SQL>select tb.geoloc.SDO_ELEM_INFO fromtbgrid tb;
SDO_ORDINATES属性

SQL> desc sdo_ordinate_array;
SDO_ORDINATE_ARRAY VARRAY(1048576) OF NUMBER

SQL>selecttb.geoloc.SDO_ORDINATES fromtbgrid tb;
SQL>select to_char(tb.geoloc.GET_WKT()) fromtbgrid tbwheremi_prinx=1217597;
SQL>select tb.geoloc.GET_WKB() fromtbgrid tbwheremi_prinx=1217597;

空间操作符
SDO_WITHIN_DISTANCE操作符

语法:
SDO_WITHIN_DISTANCE
(Table_geom   in sdo_geometry,
Query_geom  in sdo_geometry
Parameter_string in varchar2
)=’TRUE’

Table_geom为被检索表的SDO_GEOMETRY列
Query_geom为指定查询位置的SDO_GEOMETRY,它可以是另外一个表的一列一个绑定变量,或一个动态构造的对象
Parameter_string指定参数DISTANCE及可选参数UNIT(对应于指定的距离)


SDO_WITHIN_DISTANCE操作符,获取在一个竞争对手商店的0.25英里范围内的所有客户:
select ct.id, ct.name from competitors comp, customers ct
 where comp.id =1
  and SDO_WITHIN_DISTANCE(ct.location,comp.location,
                          'DISTANCE=0.25 UNIT=MILE') ='TRUE'
 ORDERBYct.id;

SDO_WITHIN_DISTANCE操作符,获取在一个竞争对手商店的0.25英里范围内的所有客户,并返回他们与该商店的距离:
SELECTct.id, ct.name,SDO_GEOM.SDO_DISTANCE(ct.location, comp.location,0.5,' UNIT=YARD ') dist
 FROM competitors comp, customers ct
 WHERE comp.id =1
  AND SDO_WITHIN_DISTANCE(ct.location,comp.location,
                          'DISTANCE=0.25 UNIT=MILE') ='TRUE'
 ORDER BY ct.id;

获取竞争对手商店周围0.25英里内的街道名,并且返回街道最小为200米的街道:
selects.street_name
 from competitors comp, map_streets s
 where comp.id =1
  and SDO_WITHIN_DISTANCE(s.geometry,comp.location,
           'DISTANCE=0.25 UNIT=MILE min_resolution=200') ='TRUE'
 order by s.street_name;

获取竞争对手商店周围0.25英里内的街道名,并且返回街道最小为200米的街道,同时返回街道最大为500米的街道:
selects.street_name
 from competitors comp, map_streets s
 where comp.id =1
  and SDO_WITHIN_DISTANCE(s.geometry,
                          comp.location,
           'DISTANCE=0.25 UNIT=MIL Emin_resolution=200 max_resolution=500') ='TRUE'
 orderbys.street_name;
参数min_resolution和max_resolution仅用于SDO_FILTER,SDO_WITHIN_DISTANCE和SDO_RELATE操作符。而不能用于SDO_NN操作符
空间操作符

SDO_NN(
Table_geom   in sdo_geometry,
Query_geom  in sdo_geometry
[, Parameter_string in varchar2
[,TAG     in varchar2]]
)=’TRUE’

l       SDO_NN操作符 :获取离指定竞争对手最近的5个客户
selectct.id, ct.name, ct.customer_grade
 from competitors comp, customers ct
wherecomp.id =1
  and SDO_NN(ct.location, comp.location) ='TRUE'
  and rownum<=5
orderbyct.id;

l       SDO_NN操作符 :获取离指定竞争对手最近的5个GOLD客户

selectct.id, ct.name, ct.customer_grade
 fromcompetitors comp, customers ct
wherecomp.id =1
  and ct.customer_grade = 'GOLD'
  and SDO_NN(ct.location, comp.location) = 'TRUE'
  and rownum <= 5
orderbyct.id;

l       SDO_NN操作符 :获取离指定竞争对手最近的5个GOLD客户,使用性能调优参数sdo_batch_size

selectct.id, ct.name, ct.customer_grade
 fromcompetitors comp, customers ct
wherecomp.id =1
  andct.customer_grade ='GOLD'
  andSDO_NN(ct.location, comp.location,'sdo_batch_size=100') ='TRUE'
  andrownum<=5
orderbyct.id;


 SDO_NN操作符 :获取离指定竞争对手最近的5个客户,使用性能调优参数sdo_num_res
selectct.id, ct.name, ct.customer_grade
 fromcompetitors comp, customers ct
wherecomp.id =1
  andSDO_NN(ct.location, comp.location,'sdo_num_res=5') ='TRUE'
orderbyct.id;

SELECT COUNT(DISTINCT ct.id)
FROM competitors comp, customers ct,
TABLE
(
SDO_JOIN
(
  'competitors', 'location', -- first table and the SDO_GEOMETRY column
  'customers', 'location',   -- second table and the SDO_GEOMETRY column
  'DISTANCE=200 UNIT=METER'  -- specify mask relationship
)
) jn
WHERE ct.rowid=jn.rowid2
AND comp.rowid = jn.rowid1;
SDO_JOIN函数的执行速度比与之等价的SDO_RELATE和SDO_WITHIN_DISTANCE操作符要快,因为它使用了两个空间索引。
alter index customers_sidx rebuild parameters('layer_gtype=POINT');
当对一个含有空间索引的表如CUSTOMERS进行大量的(典型值为30%)删除操作后,对相关空间索引进行重建将使得该索引相对紧凑,从而可以更加有效的服务随后的查询。
SQL> alter index customers_sidx rebuild parameters('layer_gtype=POINT');
索引已更改。

SQL>SELECT SDO_INDEX_NAME,sdo_index_type,SDO_INDEX_TABLE,SDO_NL_INDEX_TABLE FROM USER_SDO_INDEX_METADATA WHERE SDO_INDEX_NAME='CUSTOMERS_SIDX';
SDO_INDEX_NAME  SDO_INDEX_ SDO_INDEX_TABLE SDO_NL_INDEX_T
---------------- ---------- ---------------- --------------
CUSTOMERS_SIDX  RTREE     MDOT_1472C$     MDOT_1472C$

SQL> alter index customers_sidx rebuild ONLINE parameters('layer_gtype=POINT');
索引已更改。
一个可使查询在索引重建时不被阻塞的方法是,在ALTER INDEX….REBUILD语句中指定关键词ONLINE.随后的重建可将索引表从MDOT前缀转回为MDRT前缀。当重建一个空间列上的索引并指定哦关键词ONLINE时,这个特性确保查询永远不会被阻塞。
l       把SDO_GEOMETRY转换成WKT格式
SQL> select t.location.GET_WKT() wkt from customers t where id=1;
WKT
--------------------------------------------------------------------------------
POINT (-76.9773898 38.8886508)
l       使用TO_WKTGEOMETRY把SDO_GEOMETRY转换成WKT格式

SQL> select sdo_util.to_wktgeometry(a.location) wkt from customers a where id=1;
WKT
--------------------------------------------------------------------------------
POINT (-76.9773898 38.8886508)

空间层:要对每个空间层进行验证,创建索引和查询,需要为每个层指定适当的元数据,该元数据包含如下内容:
1维数
2每个维度的边界
3每个维度的容差
4坐标系

添加空间数据列
ALTER TABLE CUSTOMERS ADD (LOCATION SDO_GEOMETRY):

对地址进行地理编码
UPDATE branches
SET location = SDO_GCDR.GEOCODE_AS_GEOMETRY
('SPATIAL',
SDO_KEYWORDARRAY
( street_number || ' ' || street_name, city || ' ' || state || ' '
  || postal_code),'US'
);
COMMIT;
from:space. . itpub . net / ?uid -20976446 -action -viewspace -itemid -721049

评论

此博客中的热门博文

XML, XSL, HTML

Input in element.eleme.io

Data URI是由RFC 2397 ACE