|
|
|

Oracle Spatial中上载GIS空间数据方法研究

摘 要:采用Oracle Spatial 存储、管理空间数据,易于解决数据共享、分布式处理、网络通信、开放式开发、并发控制、网络化集成、跨平台运行及数据安全恢复机制等方面的难题,因而成为 了目前的一种应用趋势。而如何将现有GIS软件中产生的空间数据导入该数...

作者:佚名来源:博客中国|2006年08月24日

要:采用Oracle Spatial 存储、管理空间数据,易于解决数据共享、分布式处理、网络通信、开放式开发、并发控制、网络化集成、跨平台运行及数据安全恢复机制等方面的难题,因而成为 了目前的一种应用趋势。而如何将现有GIS软件中产生的空间数据导入该数据库中成为该技术应用的首要关键环节。本文以此为出发点,在探讨了向Oracle Spatial 上载GIS的空间数据的基本原理的基础上,较全面地介绍了在Oracle Spatial中上载矢量数据与栅格数据的各种方法,重点介绍了使用 MicrosoftADO接口、Oracle SpatialJava APIOCCI接口等手工方式上载程序的实现过程。最后,给出了全文的结论及相关的建议。

1
引言

空间数据是GIS的血液,对空间数据的管理的好坏将直接影响到GIS系统质量的高低。GIS空间数据的管理经过了纯文件方式管理必威现金回扣形数据与属性数据、必威现金回扣形 数据文件方式管理与属性数据关系型数据库管理、空间数据与属性数据一体化的管理方式三个阶段。目前,大多数GIS 软件都逐渐倾向于采用第三种管理方式,也就是必威现金回扣形数据与属性数据都采用数据库管理的方式。例如,采用Oracle SpatialDB2 Spatial ExtenderInformix Spatial DataBlade(目前Informix已经被IBM收购)以及ArcSDE数据库引擎、MapGIS MapORA引擎等等。

Oracle Spatial
提供了对象-关系模式和关系模式两种方式来存储空间数据。前者的特征是空间表中有一个类型为MDSYS.SDO_GEOMETRY的字段, 后者也就是Spatial的早期版本空间数据暗盒(Spatial Cartridge),其特征是每一个空间几何必威现金回扣层对应四个表,分别为_SDOLAYER_SDODIM_SDOGEOM_

SDOINDEX
。这些表并不包括属性数据,属性数据需建立连接。目前许多GIS软件公司都提供了对Oracle Spatial的支持,比如IntergraphGeoMedia 4.0MapInfoMapInfo 6.0AutoDeskMapGuide 6.0ESRIArcSDEARCGIS以及国内中地公司的MapGIS 6.5等。


本文主要研究上载GIS的矢量数据和栅格数据到Oracle Spatial的原理与具体的各种实现方法,并在编程实践的基础上比较几种上载方法的优点与不足。

2
Oracle Spatial上载GIS空间数据的原理

Oracle Spatial上载GIS空间数据,其实质也就是把空间数据的必威现金回扣形数据(包括矢量数据与栅格数据)与相应的属性数据写入数据库的表格中。因此,在上载前必须清楚GIS空间数据的数据格式与Oracle Spatial中空间数据是如何存储的。

每个GIS软件拥有自己的内部数据格式和数据存储方式,大部分GIS软件并不向用户直接提供读写内部数据的函数。为了与其它软件进行数据转换,通常定义一 种外部数据交换格式,如MapInfo*.mif/*.midMapGIS的明码格式与ESRIShape格式(非ASCII码格式)等等。这些外 部交换格式大部分为ASCII码文件,关于这些交换格式的数据结构的详细请参阅其公司发布的说明文档。

Oracle Spatial
是一个对象-关系数据库,提供存储空间数据的类型是SDO_GEOMETRY。随着Oracle xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />10g的推出,又给Spatial扩充了拓扑数据模型、网络数据模型与栅格数据模型,每种数据模型都有其各自的数据类型,比如类型 SDO_TOPOGEOMETRY用来存储拓扑数据等。在上载前一定要清楚这些数据类型的属性与方法,详细信息请参考文献123

3
Oracle Spatial上载GIS空间数据的方法

上载空间数据的方法,总的来说可以分为使用GIS软件公司提供的工具与手工的方式上载两种方法。本节主要介绍矢量数据与栅格数据的各种上载方法及其具体的实现过程。

3.1
矢量数据的上载方法

3.1.1
使用手工的方式实现上载

用户可以使用交互式的SQL语句上载GIS空间数据,使用这种方法也就是使用各种应用程序编程接口(如ADOODBC等等)来上载,用户可以以自己的应 用需要为导向使用开发语言调用这些接口开发出各种各样的上载工具,即实现手工方式的加载。本小节介绍了重点介绍使用 MicrosoftADO接口以及Oracle SpatialJava APIOCCI接口实现空间数据的上载的实现过程。

3.1.1.1
使用Java API上载

Oracle Spatial
Java APIApplication Programing Interface)提供了3个类,即JGeometryJGeometry.PointDataExceptionJGeometry类对应于 Oracle Spatial的对象类型MDSYS.SDO_GEOMETRYJGeometry.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
上载示例

该上载示例是使用OCCIOracle C++ Call Interface)上载空间数据的完整示例程序。首先使用Oracle数据库数据类型翻译工具OTTOracle 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/tig

er@gis

命令成功执行以后,就会生成4个文件,分别为spatial_classesh.hspatial_classeso.cpp spatial_classesm.h、与 spatial_classesm.cpp

然后,在scott用户模式下创建空间表格(即存储空间数据的表格)spatial,实现的SQL语句如下:

CREATE TABLE spatial(geoloc MDSYS.SDO_GEOMETRY);

最后,利用VC++建立一个工程,把前面翻译的文件spatial_classesh.hspatial_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 Spatialspatial表格中存储了一个矩形。用户可以扩展该工程,向数据库中存储以ASCII码表示的GIS软件的公开格式,比如 MapInfo*.mif/*.mid格式,MapGIS的点、线、区域、网络文件的明码数据等。

3.1.1.3
使用VBADO上载

各种应用程序接口也是有区别的,如果使用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提供的应用程序编程接口(除了,前面提到的还可以使用OO4OOCI等)就不会出现这种问题。 因此建议采用Oracle提供的应用程序编程接口开发上载程序。

3.1.2
直接使用工具实现上载

目前许多GIS软件公司都提供了上载空间数据到Oracle Spatial中的工具,比如EasyLoaderArcSDEMapGIS等等。

3.1.2.1 EasyLoader

Easyloader
MapInfo公司提供的上载工具,不过该工具只支持上载MapInfo格式的*.tab数据。该工具提供了命令行上载与窗口上载 两种方法。该工具在底层通过调用OCIOracle 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*LoaderShp2SDO就可以把ESRIShape文件上载到Oracle Spatial中。

3.1.2.3 ArcSDE
MapGIS提供的工具

如果购买了ESRIArcSDE,就可以使用ArcToolbox工具通过ArcSDE空间数据库引擎来上载ESRI格式的数据。与ArcMap或者 ArcCatalog一样,ArcToolboxARCGIS家族的一个重要的成员,专门负责数据的导入导出工作。除了ESRI格式的数据以外(如 ShapeFileCovage文件),ArcToolbox还提供了E00DWG等常用文件格式的数据转换工作。在进行数据转换的时候,用户可以根 据实际的需要设置转换的参数,如空间数据表的字段名称,空间索引坐标的最值等。ArcToolbox给我们提供了良好的数据转换工具。同样,如果使用的 MapGIS6.5或者其更高版本的话,就可以使用MapGIS的属性库管理子系统、编辑子系统所提供的工具来上载MapGIS空间数据。虽然 ArcSDE从逻辑上看是面向对象存储的,但是物理上使用的还是Oracle的纯关系表格。因此,这两个工具目前的版本只支持关系模式,也就是 Spatial Cartridge的模式。

3.2
栅格数据的上载方法

Oracle 10g开始,Oracle Spatial中增加了存储栅格数据的模块,同时还提供了上载栅格数据的Java APIPL/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文件后,就可以在MapInfoMapX以及MapXtreme for Java中使用Oracle Spatial数据源);如果没有相应的上载工具,就用户可以通过ADOOCIOCCIOO4OJava API等接口自行开发上载工具。

(4)
在本文介绍的Java APIOCCIADO三种接口的实现过程中,由于ADO接口的 Command对象在CommandText属性的长度超过4000个字符的情况下不能进行值的传递,较长的空间对象会被截断。因此建议采用Oracle 提供的Java APIOCCI接口来开发上载程序。

5Oracle10g Oracle Spatial选件中增加了存储栅格数据的模块,同时还提供了上载栅格数据的Java APIPL/SQL API以及上载工具GeoRasterLoader。使用GeoRasterLoader可以实现栅格数据的上载,但是由于目前的 Oracle10.1.2版本所采用栅格数据模型不支持中文字符,所以建议在安装时的语言的选项上不采用默认的中文而选择使用英语。

上一篇:浅入浅出Oracle Spatial GeoRaster 10g影…

下一篇:浅谈优化空间数据库的几种方案