从ArcSDE的Post Installation就可以看到,ArcSDE支持多种数据存储方式,不但支持ESRI自身的ST_GEOMETRY,也支持BLOB和SDO_GEOMETRY类型。
图 3 ArcSDE支持的存储格式
ArcSDE中的ST_GEOMETRY和Oracle Spatial中基于SDO_GEOMETRY的ST_GEOMETRY完全是不相干的两个东西。首先让我们来看一下ArcSDE中ST_GEOMETRY类型的定义:
CREATE OR REPLACE
Type st_geometry Authid current_user AS object
(entity integer,numpts integer,minx float(64),
miny float(64),maxx float(64),maxy float(64),
minz float (64),maxz float(64),minm float(64),
maxm float(64),area float(64),len float(64),
srid integer,points blob,
constructor Function st_geometry(geom_str clob,srid number) Return self AS result deterministic,
member Function st_area Return number,
member Function st_len Return number,
member Function st_length Return number,
member Function st_entity Return number,
member Function st_numpts Return number,
member Function st_minx Return number,
member Function st_maxx Return number,
member Function st_miny Return number,
member Function st_maxy Return number,
member Function st_minm Return number,
member Function st_maxm Return number,
member Function st_minz Return number,
member Function st_maxz Return number,
member Function st_srid Return number,
static Function get_release Return number) NOT final;
可见,一个ST_GEOMETRY中包含了一个几何对象的x、y、z、m坐标的范围、空间参考id、实体个数和点个数、几何对象的面积和长度、具体的节点坐标等信息。其中,节点坐标属性points比较特殊,这是一个blob类型的值。
让我们打开ST_GEOMETRY类型的构造函数就可以发现,事实上对几何对象的构造是通过ST_GEOMETRY_SHAPELIB_PKG这个包进行处理的,而这个包事实上会调用ESRI的ST_SHAPELIB这个外部动态链接库,我们可以看一下ST_GEOMETRY_SHAPELIB_PKG包里的geometryfromtext这个存储过程,这个过程在ST_GEOMETRY的构造函数中被调用了:
Procedure geometryfromtext (shptxt IN clob,
…,
points IN Out blob )
AS
language c
name "GeometryFromText"
library st_shapelib
WITH CONTEXT
parameters (
CONTEXT,
shptxt ociloblocator, shptxt Indicator short,
…,
points ociloblocator, points Indicator short
);
再具体一点,比如我们创建了一个ST_POINT对象,我们可能比较关心在Oracle的层面到底上发生了些什么事情?比如我们通过SQL执行了这样一条语句:
SQL> select sde.st_point(1,1,0) from dual;
显然,它会调用ST_POINT的构造函数,这个构造函数大体是这个样子的:
constructor Function st_point(pt_x number,pt_y number,srid number)
Return self AS result
IS
…;
Begin
…;
geom_clob := 'POINT('||pt_x||' '||pt_y||')';
SDE.st_geometry_shapelib_pkg.geometryfromtext(geom_clob,spref_r.srid,spref_r.x_offset,spref_r.y_offset,spref_r.xyunits, spref_r.z_offset,spref_r.z_scale,spref_r.m_offset,spref_r.m_scale, spref_r.Definition,geom_type,shape.numpts,shape.entity,shape.minx,shape.miny, shape.maxx,shape.maxy,shape.minz,shape.maxz,shape.minm,shape.maxm, shape.area,shape.len,shape.points);
…;
End;
这个构造函数做了2件事情:一是通过参数构造了一个WKT[1] 表述的几何对象字符串;二是通过调用ST_SHAPELIB链接库实现了从字符串到几何对象的转化,返回的一系列值构成了ST_POINT对象。最后存在Oracle中的实际上是二进制对象:
SQL> select sde.st_point(1,1,0) from dual;
SDE.ST_POINT(1,1,0)(ENTITY, NUMPTS, MINX, MINY, MAXX, MAXY, MINZ, MAXZ, MINM, MAXM, AREA, LEN, SRID, POINTS)
------------------------------------------------------------------------------------------------------------------------
ST_POINT(1, 1, 1, 1, 1, 1, NULL, NULL, NULL, NULL, 0, 0, 0, '0C0000000100000080A8B3D7AB1780A8B3D7AB17')
[1] http://en.wikipedia.org/wiki/Well-known_text