完全轉自:http://blog.sina.com.cn/s/blog_439d2cef01009c4a.html
一、Oracle Spatial簡介
Oracle 支持自定義的數據類型,可以用數組,結構體或者帶有構造函數,功能函數的類來定義自己的對象類型。這樣的對象類型可以用於屬性列的數據類型,也可以用來創建對象表。而Oracle Spatial也正是基於此種特性所開發的一套空間數據處理系統。
Spatial 的自定義數據類型有很多,全部在MDSYS方案下,經常使用到的是SDO_GEOMETRY類型。SDO_GEOMETRY表示一個幾何對象,可以是點、線、面、多點、多線、多面或混合對象。
Spatial 在此數據類型的基礎上,實現了R樹空間索引和四叉樹空間索引,還以SQL函數的形式實現了多種空間分析功能。
二、測試表的建立與應用(點類型)
| -- 創建測試用表 CREATE TABLE "SPATIALTEST" ( "ID" VARCHAR2(20) NOT NULL, "NAME" VARCHAR2(100), "ADDRESS" VARCHAR2(200), "TELEPHONE" VARCHAR2(50), "LOCATION" "MDSYS"."SDO_GEOMETRY" )LOGGING; |
| -- 創建主鍵約束 ALTER TABLE "SPATIALTEST" ADD CONSTRAINT "PK_SPATIAL" PRIMARY KEY("ID"); |
| -- 根據用戶表填寫空間元數據 INSERT INTO USER_SDO_GEOM_METADATA VALUES( 'SPATIALTEST', 'location', MDSYS.SDO_DIM_ARRAY( MDSYS.SDO_DIM_ELEMENT('Longitude',-180,180,10), MDSYS.SDO_DIM_ELEMENT('Latitude',-90,90,10) ), 8307 ); |
| -- 建立空間索引 CREATE INDEX SPATIAL_IDX ON SPATIALTEST(location) INDEXTYPE IS MDSYS.SPATIAL_INDEX; |
| -- 導入測試數據
--其他 INSERT INTO cola_markets VALUES( |
| -- 屬性信息查詢 SQL> select location from spatialtest; LOCATION(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES) SQL> select s.location.SDO_POINT.x langtitude from spatialtest s; LANGTITUDE |
| -- 空間分析查詢(113.2359818,23.16937253)周邊十公里信息5條 SELECT B.id id, B.name name, B.dist dist FROM ( SELECT A.id id, A.name name, SDO_GEOM.SDO_DISTANCE(A.location,MDSYS.SDO_GEOMETRY(2001,8307,MDSYS.SDO_POINT_TYPE(113.2359818,23.16937253,0),NULL,NULL),1) dist FROM spatialtest A WHERE SDO_WITHIN_DISTANCE(A.LOCATION,MDSYS.SDO_GEOMETRY(2001,8307,MDSYS.SDO_POINT_TYPE(113.2359818,23.16937253,0),NULL,NULL),'distance=10000') = 'TRUE' ORDER BY A.name ) B WHERE ROWNUM <= 5 ; |
| -- 空間分析查詢(113.2359818,23.16937253)附近的5條信息 SELECT A.id id, A.name name,A.location.SDO_POINT.x langtitude, A.location.SDO_POINT.y latitude,MDSYS.SDO_NN_DISTANCE(1) distance FROM spatialtest A WHERE SDO_NN(A.LOCATION,MDSYS.SDO_GEOMETRY(2001,8307,MDSYS.SDO_POINT_TYPE(113.2359818,23.16937253,0),null,null),'SDO_NUM_RES=5',1) = 'TRUE' ; |
| -- Return the topological difference of two geometries. SELECT SDO_GEOM.SDO_DIFFERENCE(c_a.shape, m.diminfo, c_c.shape, m.diminfo) FROM cola_markets c_a, cola_markets c_c, user_sdo_geom_metadata m WHERE m.table_name = 'COLA_MARKETS' AND m.column_name = 'SHAPE' AND c_a.name = 'cola_a' AND c_c.name = 'cola_c'; |
三、MDYSYS.SDO_GEOMETRY結構
| CREATE TYPE SDO_GEOMETRY AS OBJECT( //它們都是NUMBER類型, //形成空間對象的邊界 |
MDSYS.SDO_GEOMETRY <--> OCCI 對照模型:
四、Oracle Spatial 幾個自定義函數(轉帖)
--------------------------------------
| --得到線對象的終止點X坐標
|
| --得到線對象的終止點的Y坐標
|
| --得到線對象的終止點坐標 X,Y 形式
|
| --得到線對象的起始點X坐標
|
| --得到線對象的起始點的Y坐標
|
| --得到線對象的起始點XY坐標
|
| --把X,Y坐標轉換成MDSYS.SDO_GEOMETRY的點對象 create or replace function To_Geomerty_Point(x in number,y in number ) return MDSYS.SDO_GEOMETRY is Result MDSYS.SDO_GEOMETRY; begin Result := MDSYS.SDO_GEOMETRY(2001, return(Result);
|
--------------------------------------------------------------------------
-------------------查詢 及測試語句---------------------------------------
| --求線路的長度 select c.routename, sdo_geom.sdo_length(c.geoloc,m.DIMINFO,'unit=KM') from tgs_route c,user_sdo_geom_metadata m select * from tg_routev2 select a.geoloc.SDO_ORDINATES from tgs_route a select GetStartNodeXY(a.geoloc.SDO_ORDINATES) from tgs_route a select GetEndNodeXY(a.geoloc.SDO_ORDINATES) from tgs_route a
|
| --計算線路的起始點和終止點坐標
|
| --更新tg_routev2 中的線起始點 終止點坐標 alter table routeNodeXY add primary key(routename) update (select a.*,b.* from tg_routev2 a,routeNodeXY b
|
| select sdo_geom.sdo_distance( from dual
|
| --node1距離物流中心的 “南北直角折線” 距離 select a.routename, (sdo_geom.sdo_distance(To_Geomerty_Point(a.node1x, a.node1y), To_Geomerty_Point(116.635056, a.node1y), 0.005, 'unit=KM') + sdo_geom.sdo_distance(To_Geomerty_Point(a.node1x, a.node1y), To_Geomerty_Point(a.node1x, 39.869170), 0.005, 'unit=KM')) dis1 from tg_routev2 a order by dis1
--node2距離物流中心的 “南北直角折線” 距離
|
| --更新node1Distance 和 node2Distance 即線路起始點、終止點距離物流中心的 “南北直角折線” 距離 tg_routev2 node1Distance = (sdo_geom.sdo_distance(To_Geomerty_Point(node1x, node1y), To_Geomerty_Point(116.635056, node1y), 0.005, 'unit=KM') + sdo_geom.sdo_distance(To_Geomerty_Point(node1x, node1y), To_Geomerty_Point(node1x, 39.869170), 0.005, 'unit=KM')), + sdo_geom.sdo_distance(To_Geomerty_Point(node2x, node2y), To_Geomerty_Point(node2x, 39.869170), 0.005, 'unit=KM')) node1Distance is null; |
-The End-

