Oracle Spatial中上傳GIS空間資料方法研究 摘)

來源:互聯網
上載者:User

Oracle Spatial中上傳GIS空間資料方法研究 (轉摘)

 

 來源:http://blog.sina.com.cn/s/reader_45f260910100999x.html

 

 

摘  要:採用Oracle Spatial 儲存、管理空間資料,易於解決資料共用、分散式處理、網路通訊、開放式開發、並發控制、網路化整合、跨平台運行及資料安全恢複機制等方面的難題,因而成為 了目前的一種應用趨勢。而如何將現有GIS軟體中產生的空間資料匯入該資料庫中成為該技術應用的首要關鍵環節。本文以此為出發點,在探討了向Oracle Spatial 上傳GIS的空間資料的基本原理的基礎上,較全面地介紹了在Oracle Spatial中上傳向量資料與柵格資料的各種方法,重點介紹了使用 Microsoft的ADO介面、Oracle Spatial的Java API及OCCI介面等手工方式上傳程式的實現過程。最後,給出了全文的結論及相關的建議。

1引言

空間資料是GIS的血液,對空間資料的管理的好壞將直接影響到GIS系統品質的高低。GIS空間資料的管理經過了純檔案方式管理圖形資料與屬性資料、圖形資料檔案方式管理與屬性資料關係型資料庫管理、空間資料與屬性資料一體化的管理方式三個階段。目前,大多數GIS 軟體都逐漸傾向於採用第三種管理方式,也就是圖形資料與屬性資料都採用資料庫管理的方式。例如,採用Oracle Spatial、DB2 Spatial Extender、Informix Spatial DataBlade(目前Informix已經被IBM收購)以及ArcSDE資料庫引擎、MapGIS MapORA引擎等等。

Oracle Spatial提供了對象-關係模式和關係模式兩種方式來儲存空間資料。前者的特徵是空間表中有一個類型為MDSYS.SDO_GEOMETRY的欄位,後者也就是Spatial的早期版本空間資料暗盒(Spatial Cartridge),其特徵是每一個空間幾何圖層對應四個表,分別為_SDOLAYER、_SDODIM、_SDOGEOM與_

SDOINDEX。這些表並不包括屬性資料,屬性資料需建立串連。目前許多GIS軟體公司都提供了對Oracle Spatial的支援,比如Intergraph的GeoMedia 4.0、MapInfo的MapInfo 6.0、AutoDesk的MapGuide 6.0、ESRI的ArcSDE、ArcGIS以及國內中地公司的MapGIS 6.5等。

本文主要研究上傳GIS的向量資料和柵格資料到Oracle Spatial的原理與具體的各種實現方法,並在編程實踐的基礎上比較幾種上傳方法的優點與不足。

2 向Oracle Spatial上傳GIS空間資料的原理

向Oracle Spatial上傳GIS空間資料,其實質也就是把空間資料的圖形資料(包括向量資料與柵格資料)與相應的屬性資料寫入資料庫的表格中。因此,在上傳前必須清楚GIS空間資料的資料格式與Oracle Spatial中空間資料是如何儲存的。

每個GIS軟體擁有自己的內部資料格式和資料存放區方式,大部分GIS軟體並不向使用者直接提供讀寫內部資料的函數。為了與其它軟體進行資料轉換,通常定義一 種外部資料交換格式,如MapInfo的*.mif/*.mid、MapGIS的明碼格式與ESRI的Shape格式(非ASCII碼格式)等等。這些外 部交換格式大部分為ASCII碼檔案,關於這些交換格式的資料結構的詳細請參閱其公司發布的說明文檔。

Oracle Spatial是一個對象-關聯式資料庫,提供儲存空間資料的類型是SDO_GEOMETRY。隨著Oracle 10g的推出,又給Spatial擴充了拓撲資料模型、網路資料模型與柵格資料模型,每種資料模型都有其各自的資料類型,比如類型SDO_TOPOGEOMETRY用來儲存拓撲資料等。在上傳前一定要清楚這些資料類型的屬性與方法,詳細資料請參考文獻1、2、3。

3 向Oracle Spatial上傳GIS空間資料的方法

上傳空間資料的方法,總的來說可以分為使用GIS軟體公司提供的工具與手工的方式上傳兩種方法。本節主要介紹向量資料與柵格資料的各種上傳方法及其具體的實現過程。

3.1     向量資料的上傳方法

3.1.1    使用手工的方式實現上傳

使用者可以使用互動SQL語句上傳GIS空間資料,使用這種方法也就是使用各種API(如ADO、ODBC等等)來上傳,使用者可以以自己的應用需要為導向使用開發語言調用這些介面開發出各種各樣的上傳工具,即實現手工方式的載入。本小節介紹了重點介紹使用 Microsoft的ADO介面以及Oracle Spatial的Java API和OCCI介面實現空間資料的上傳的實現過程。

3.1.1.1   使用Java API上傳

Oracle Spatial的Java API(Application Programing Interface)提供了3個類,即JGeometry、JGeometry.Point與DataException。JGeometry類對應於Oracle Spatial的物件類型MDSYS.SDO_GEOMETRY,JGeometry.Point類對應於物件類型MDSYS.SDO_POINT_TYPE, DataException類表示異常。下面的樣本示範了如何使用Java API實現將GIS的空間資料寫入Oracle Spatial中:

/// 從資料庫中讀取空間資料

ResultSet rs = statement.executeQuery("SELECT geoloc FROM countries where name='China'");

STRUCT st = (oracle.sql.STRUCT) rs.getObject(1);

//把結構體轉換為geometry 對象

JGeometry j_geom = JGeometry.load(st);

// ... 在空間對象上執行空間操作或者建立新的空間對象 ...

/// 向資料庫中儲存空間對象

PreparedStatement ps = connection.prepareStatement("UPDATE countries set geometry=? where name=' China '");

//把JGeometry對象轉換為資料庫的結構體。

STRUCT obj = JGeometry.store(j_geom, connection);

ps.setObject(1, obj);

ps.execute();

3.1.1.2          OCCI上傳樣本

該上傳樣本是使用OCCI(Oracle C++ Call Interface)上傳空間資料的完整樣本程式。首先使用Oracle資料庫資料類型翻譯工具OTT(Oracle Type Translator)翻譯類型MDSYS.SDO_POINT_TYPE與類型MDSYS.SDO_GEOMETRY,在命令列下輸入,

ott attraccess=private code=cpp cppfile=spatial_classeso.cpp hfile=spatial_classesh.h intype=spatial_types.typ mapfile=spatial_classesm.cpp mapfunc=RegisterClasses userid=scott/tiger@gis

命令成功執行以後,就會產生4個檔案,分別為spatial_classesh.h、spatial_classeso.cpp、 spatial_classesm.h、與 spatial_classesm.cpp;

然後,在scott使用者模式下建立空間表格(即儲存空間資料的表格)spatial,實現的SQL語句如下:

CREATE TABLE spatial(geoloc MDSYS.SDO_GEOMETRY);

最後,利用VC++建立一個工程,把前面翻譯的檔案spatial_classesh.h、spatial_classeso.cpp、 spatial_classesm.h、與 spatial_classesm.cpp添加到工程中。主檔案的內容為,

#include

#include

#include

#include

#include "spatial_classesh.h"

#include "spatial_classesm.h"

using namespace std;

using namespace oracle::occi;

const int SDO_GTYPE_2DPOINT = 2001;

const int SDO_GTYPE_2DPOLYGON = 2003;

const int SDO_ETYPE_POLYGON = 1003;

const int SDO_INTERPRETATION_RECTANGLE = 3;

void main()

{try

  {//以OBJECT模式初始化環境變數

    Environment *env = Environment::createEnvironment(Environment::OBJECT);

    RegisterClasses(env);//註冊類型函數

    Connection *conn = env->createConnection("scott","tiger","gis");

   try

   { Statement *stmt = conn->createStatement("Insert Into spatial(geoloc) VALUES (:1)");

 

  • //儲存空間對象

        Number srid_null;

        SDOPointType *point_null = new SDOPointType();

        point_null->setNull();

        SDOGeometry *spatial_obj = new SDOGeometry();//建立對象

        spatial_obj->setSdo_gtype(SDO_GTYPE_2DPOLYGON);

        spatial_obj->setSdo_srid(srid_null);//不設定座標系

        spatial_obj->setSdo_point(point_null);//設定點對象為null

        vector elem_info, ordinates;

        elem_info.clear();//清空elem_info

        ordinates.clear();//清空ordinates

        //儲存elem_info對象

    elem_info.push_back(1);elem_info.push_back(SDO_ETYPE_POLYGON);

        elem_info.push_back(SDO_INTERPRETATION_RECTANGLE);

        spatial_obj->setSdo_elem_info(elem_info);

    //儲存矩形,利用ordinates可以儲存大於4000個字元的參數,ADO則小於4000

        ordinates.push_back(1);ordinates.push_back(1);// (1,1)

        ordinates.push_back(5);ordinates.push_back(7);// (5,7)

        spatial_obj->setSdo_ordinates(ordinates);

        stmt->setObject(1, spatial_obj);

        stmt->executeUpdate();

        delete spatial_obj;//釋放對象

        conn->terminateStatement(stmt);}

       catch (SQLException &ex)

       {env->terminateConnection(conn);

        Environment::terminateEnvironment(env);

        throw; }

        env->terminateConnection(conn);

        Environment::terminateEnvironment(env); }

      catch (SQLException &ex)

      {cout << "Error running Demo : " << ex.getMessage() << endl; }}

    編譯成功之後,該工程就向Oracle Spatial的spatial表格中儲存了一個矩形。使用者可以擴充該工程,向資料庫中儲存以ASCII碼錶示的GIS軟體的公開格式,比如MapInfo的*.mif/*.mid格式,MapGIS的點、線、地區、網路檔案的明碼資料等。

    3.1.1.3          使用VB與ADO上傳

    各種應用程式介面也是有區別的,如果使用ADO的話,有可能會出現參數傳遞不能滿足要求的情況,例如下面在VB6.0中使用ADO的語句,

    Set adoCommand = Nothing

    adoCommand.CommandType = adCmdText

    adoCommand.CommandText = “Insert into SpatialTable_name(Spatial_column) values” & SpatialData

    adoCommand.ActiveConnection = adoConnection

    adoCommand.Execute

    由於ADO Command對象的CommandText屬性的長度如果超過4000個字元將不能進行值的傳遞。因此,對於較長的空間對象就需要被截斷,所以,採用 ADO介面進行上傳不是最佳的選擇。如果選擇Oracle提供的API(除了,前面提到的還可以使用OO4O、OCI等)就不會出現這種問題。 因此建議採用Oracle提供的API開發上傳程式。

    3.1.2              直接使用工具實現上傳

    目前許多GIS軟體公司都提供了上傳空間資料到Oracle Spatial中的工具,比如EasyLoader、ArcSDE、MapGIS等等。

    3.1.2.1          EasyLoader

    Easyloader是MapInfo公司提供的上傳工具,不過該工具只支援上傳MapInfo格式的*.tab資料。該工具提供了命令列上傳與視窗上傳兩種方法。該工具在底層通過調用OCI(Oracle Call Interface)把資料寫入資料庫。使用EasyLoader上傳空間資料到Oracle Spatial中,最大的優點就是上傳的空間資料使用對象-關係模式儲存的,可以完全利用Oracle Spatial的對象-關係模式的優點。在安裝了MapInfo Professional以後,就預設安裝了該工具,可以%MAPINFO%"Tools目錄下找到該工具;此外,MapInfo的官方網站上也提供本免費工具的下載。

    3.1.2.2          SQL*Loader與Shp2SDO

    SQL*Loader根據從控制檔案接受的指令讀取ASCII碼資料,並將資料放入Oracle資料庫中。控制檔案通知SQL*Loader資料應放在何 處,並描述裝入Oracle資料庫中的各類資料。SQL*Loader還能過濾資料(即不裝入那些不適合的資料),同時可以將資料裝載進多個表,並在將數 據放入Oracle表之前產生唯一關鍵字或操作資料。

    Shp2SDO是Oracle公司提供的,用來把ESRI的*.shp檔案轉換為可以使用SQL*Loader的控制檔案與資料檔案的一個命令列工具。該 工具不僅可以把*.shp轉換為對象-關係的格式,也可以轉換為關係格式。該工具可以從Oracle公司的網站上免費下載。

    配合使用SQL*Loader與Shp2SDO就可以把ESRI的Shape檔案上傳到Oracle Spatial中。

    3.1.2.3          ArcSDE與MapGIS提供的工具

    如果購買了ESRI的ArcSDE,就可以使用ArcToolbox工具通過ArcSDE空間資料庫引擎來上傳ESRI格式的資料。與ArcMap或者 ArcCatalog一樣,ArcToolbox是ArcGIS家族的一個重要的成員,專門負責資料的匯入匯出工作。除了ESRI格式的資料以外(如 ShapeFile、Covage檔案),ArcToolbox還提供了E00、DWG等熱門檔案格式的資料轉換工作。在進行資料轉換的時候,使用者可以根 據實際的需要設定轉換的參數,如空間資料表的欄位名稱,空間索引座標的最值等。ArcToolbox給我們提供了良好的資料轉換工具。同樣,如果使用的 MapGIS是6.5或者其更高版本的話,就可以使用MapGIS的屬性庫管理子系統、編輯子系統所提供的工具來上傳MapGIS空間資料。雖然 ArcSDE從邏輯上看是物件導向儲存的,但是物理上使用的還是Oracle的純關係表格。因此,這兩個工具目前的版本只支援關係模式,也就是 Spatial Cartridge的模式。

    3.2     柵格資料的上傳方法

    從Oracle 10g開始,Oracle Spatial中增加了儲存柵格資料的模組,同時還提供了上傳柵格資料的Java API、PL/SQL API以及上傳工具GeoRasterLoader。下面給出了使用GeoRasterLoader上傳柵格資料的過程:

    1)       CREATE TABLE jpegs (jpg MDSYS.SDO_GEORASTER);

    2)       CALL sdo_geor_utl.createDMLtrigger(‘jpegs', 'jpg');

    3)       CREATE TABLE rdt1 of MDSYS.SDO_RASTER (primary key (rasterId, pyramidLevel,bandBlockNumber, rowBlockNumber, columnBlockNumber));

    4)       INSERT INTO jpegs VALUES(MDSYS.SDO_GEOR.init('rdt1'));

    5)       SELECT jpg FROM jpegs;

    傳回值為SDO_GEORASTER(NULL, NULL, 'RDT1', 22, NULL)

    6)       COMMIT;

    7)       在作業系統的命令列工具使用下面的命令來上傳柵格映像"C:"TEST.jpg",

    java GeoRasterLoader gis01 gis 1521 scott tiger thin 32 T jpegs jpg "blocking=true,blocksize=(256,256,1)" "C:"TEST.jpg,22,rdt1";

    8)       上傳成功以後,還可以使用GeoRasterViewer來瀏覽柵格映像,在作業系統的命令列工具下輸入下面的命令,

    java GeoRasterLoader gis01 gis 1521 scott tiger thin 32 T;

    在上傳柵格資料的時候,由於目前的Oracle10.1.2版本所採用柵格資料模型不支援中文字元,所以使用者在安裝Oracle 10g的時候,必須選擇使用英語,而不能預設使用中文。

    4         結論

    (1) 採用Oracle Spatial 儲存、管理空間資料,易於解決資料共用、分散式處理、網路通訊、開放式開發、並發控制、網路化整合、跨平台運行及資料安全恢複機制等方面的難題,因而成為了目前的一種應用趨勢。而如何將現有GIS軟體中產生的空間資料匯入該資料庫中成為該技術應用的首要關鍵環節。

    (2) 向Oracle Spatial上傳GIS空間資料,其實質也就是把空間資料的圖形資料(包括向量資料與柵格資料)與相應的屬性資料寫入資料庫的表格中。而充分理解所匯入的GIS資料的儲存方式以及Oracle Spatial的資料類型及其對象的屬性與方法是上傳程式實現的工作基礎。

    (3) 在上傳的實現方式上可以使用GIS件公司提供的工具或手工編寫程式進行上傳。在具體方式的選擇上:如果GIS軟體提供了相應的上傳工具的話,建議採用這些工具上傳,因為這樣就可以利用相應的二次開發組件開發基於Oracle Spatial的應用程式(例如,使用Easyloader上傳了*.tab檔案後,就可以在MapInfo的MapX以及MapXtreme for Java中使用Oracle Spatial資料來源);如果沒有相應的上傳工具,就使用者可以通過ADO、OCI、OCCI、OO4O、Java API等介面自行開發上傳工具。

    (4) 在本文介紹的Java API、OCCI、ADO三種介面的實現過程中,由於ADO介面的 Command對象在CommandText屬性的長度超過4000個字元的情況下不能進行值的傳遞,較長的空間對象會被截斷。因此建議採用Oracle提供的Java API和OCCI介面來開發上傳程式。

    (5)Oracle10g 的Oracle Spatial選件中增加了儲存柵格資料的模組,同時還提供了上傳柵格資料的Java API、PL/SQL API以及上傳工具GeoRasterLoader。使用GeoRasterLoader可以實現柵格資料的上傳,但是由於目前的Oracle10.1.2版本所採用柵格資料模型不支援中文字元,所以建議在安裝時的語言的選項上不採用預設的中文而選擇使用英語。

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.