张卓然
(湖南拓维软件工程公司,湖南 长沙 410082)
ArcSDE提供了空间数据在商用关系数据库管理系统中进行存储、访问、编辑的通道。ArcSDE的面向对象的数据存储模型使得开发人员将更多的精力应用在空间数据的应用层,而数据的存储、表达等比较底层的应用由ArcSDE所定义的规则去完成。
图3.4ArcSDE空间数据访问流
根据不同用户的需求,ArcSDE除支持多种服务器系统平台、多种数据库系统以外,在客户端,用户同样可以根据自己的需求来选择客户端应用软件。ArcSDE C API是提供给开发人员定制客户端定端软件的应用程序开发接口,ArcSDE通过提供空间约束对标准SQL进行了扩展,从而实现了带有空间约束条件的空间数据库的查询工作。其主要工作 流程如图3.4所示,通过查询(属性、空间)以后获取的结果存放在一个数据集中,用户可以顺序访问数据集中的数据。数据的类型可以是字符型、也可以是shape几何类型的数据。通过ArcSDE访问几何数据,一般要通过以下几个步骤:
1)空间数据库连接
不管是从ArcSDE中读取数据还是存储数据,都必须先建立与ArcSDE 服务器的连接。连接ArcSDE服务器的实质就是建立一个正确的 ArcSDE连接句柄,可以通过函数SE_connection_create来创建。其函数原型如下所示:
LONG SE_connection_create(const CHAR *server,const CHAR *instance,
const CHAR *database,const CHAR *username,const CHAR *password,
SE_ERROR *error,SE_CONNECTION *connection);
SE_CONNECTION Connection;
SE_ERROR Connect_error;
LONG rc;
CHAR*server, *instance, *database, *user, *passwd;
//创建数据库连接
rc = SE_connection_create(server, instance, database, user,
passwd,Connect_error,&Connection);
//进行错误检验,查看创建数据库连接是否成功
check_error (Connection, NULL, rc,"SE_connection_create");//进行数据库操作……//数据库连接释放,这个是空间数据库操作的最后一步,后文会描述
SE_connection_free(Connection);
2)数据流对象的创建
要实现数据库查询,首先要创建一个数据库流(SE_STREAM)对象,数据流对象用于实现客户端和服务器端的数据的访问、传输。类似于DBMS的游标对象,数据流对象使得用户可以循环的访问数据集对象,SE_stream_create()可以用来创建一个数据流对象,其函数原型:
LONG SE_stream_create (SE_CONNECTION Connection,SE_STREAM *Stream);
创建了一个数据流对象以后,当不需要这个对象时,就需要调用函数 SE_stream_free()将其释放,函数原型如下,参数含义同上:
LONG SE_stream_free (SE_STREAMstream);
创建数据流对象代码如下:
LONG rc;
SE_STREAMStream;//创建数据流对象
rc = SE_stream_create (Connection, &Stream);
//进行错误检验,查看创建数据流对象是否成功checke_error (Connection, NULL, rc,
"SE_stream_create");
//进行数据访问操作,访问的结果存放在SE_STREAM对象中
……
//释放数据流对象
rc = SE_stream_free (Stream);
3)空间数据查询
ArcSDE对标准SQL进行了空间扩展,使得其可以进行空间数据查询,而这样的扩展是通过SE_SQL_CONSTRUCT数据结构来完成的。
typedef struct {
LONGnum_tables;//表的数目CHAR**tables;//表名数组
CHAR*where;//SQL查询条件语句
} SE_SQL_CONSTRUCT;
在使用SE_SQL_CONSTRUCT对象之前,首先要调用SE_sql_construct_alloc来为其分配内存空间,参数意义同上。
LONG SE_sql_construct_alloc(LONG num_tables,
SE_SQL_CONSTRUCT
**constructor);
空间数据的查询包括属性条件查询和空间几何限制条件查询两个部分。属性条件查询条件通过SE_SQL_CONSTRUCT的where条件语句进行设置。而空间几何条件查询的条件通过SE_FILTER结构对象进行设置,主要用到了两个方法:SE_stream_query和
SE_stream_set_spatial_constraints,函数原型如下:
LONG SE_stream_query(SE_STREAM stream,SHORT
num_columns,
const CHAR **columns,const SE_SQL_CONSTRUCT*construct);
函数功能:设置空间数据查询的属性条件,参数意义如下:
construct属性查询数据结构
LONG SE_stream_set_spatial_constraints(SE_STREAM stream,SHORT search_order,
BOOL calc_masks,SHORT num_filters,const SE_FILTER*filters);
函数功能:设置空间数据查询的几何限制条件,各参数意义如下:
具体使用方法如下:
SE_FILTERfilter;
SE_SQL_CONSTRUCT*SQL=NULL;//属性查询条件的设置
rc = SE_sql_construct_alloc(1, &SQL);
SQL->where = (char*)malloc(20);
SQL->num_tables = 1;
strcpy(SQL->tables[0], strlyrName);
strcpy(SQL->where,"ObjectID>=1");
//设置属性查询条件
attrs1[0] = "Shape";//检索用图形字段
attrs1[1] = "ObjectID"; //检索用属性字段
//属性结果就是返回所有的记录数据
rc = SE_stream_query(stream, 2, (const char **)attrs1,SQL);
//设置空间过滤关系
strcpy(filter.table,strlyrName);
strcpy(filter.column, "Shape");
filter.filter_type = SE_SHAPE_FILTER;
filter.filter.shape = clipShp;
filter.truth = TRUE;
//SM_SC表示待查找的几何目标包含在结构体的shape几何对象中
filter.method = SM_SC ;
/
/设置空间几何过滤条件
rc=SE_stream_set_spatial_constraints(stream,
SE_SPATIAL_FIRST, FALSE, 1,&filter);
//执行查询,查询结果存储在stream对象里面
rc = SE_stream_execute(stream);
//处理获取的数据
……
//关闭、释放数据流对象
rc = SE_stream_close(stream,TRUE);
rc = SE_stream_free(stream);
//释放属性查询条件结构对象
free(SQL->where);
SE_sql_construct_free(SQL);
4)数据对象的访问
通过扩展的空间SQL访问数据库中的数据,得到的结果被存储在空间数据流对象(Stream)中,下面主要介绍对该数据流中的对象进行浏览、编辑、存储的方法。数据的查询返回的结果SE_STREAM,初始值是指向结果的第一个元素对象,SE_stream_fetch()函数主要用于数据集对象中数据的循环访问,每次返回游标所指向的一条数据记录,如果访问成功返回SE_SUCCESS,如果到达数据集的末尾,则返回SE_FINISHED,函数原型为:
LONG SE_stream_fetch (SE_STREAM stream);
数据集的访问伪代码如下:
while (RC == SE_SUCCESS)
{
//获取查询结果,循环逐一获取
RC = SE_stream_fetch(stream);
If (RC != SE_SUCCESS)
//错误处理
else
{
rc=SE_stream_get_integer(stream,2,&nObjectID);
if (rc !=SE_SUCCESS)
//错误处理
}
}
5)处理对象数据的释放
在C++中要求分配的内存空间在程序结束的时候要解释释放,同样ArcSDE C API要求开发人员在程序模块结束,将不再使用的数据对象所占据的内存空间进行手工的释放,在以上的事例代码中,大家已经看到了,空间数据据库连接对象在结束时通过SE_connection_free()释放了,而数据流对象也在访问之后被关闭,同时内存空间也得到了释放。
通过以上五个步骤,我们实现了空间数据库的访问,同样的道理,我们可以通过流程进行数据记录对象增加、修改和删除工作。
[3]刘恩林,石军南,罗鹏,雷平.Geodatabase 模型的版本控制原理及应用[J]. 西安文理学院学报:自然科学版. 2007,(1).
[4]宋杨,万幼川.一种新型空间数据模型Geodatabase[J] .测绘通报,2004,(11).