ArcSDE vs. Oracle Spatial 16

I. 线性参考

· Oracle Spatial

1. 创建线性参考的空间对象

image

图 15 一个线性参考空间对象的例子

对于如图 15的例子,Oracle Spatial中需要通过如下的SQL语句进行创建:

SQL> select SDO_GEOMETRY(3302, NULL, NULL,SDO_ELEM_INFO_ARRAY(1,2,1),SDO_ORDINATE_ARRAY(5,10,0, 20,5,NULL, 35,10,NULL, 55,10,100)) shape from dual;

SHAPE(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)

------------------------------------------------------------------------------------------------------------------------

SDO_GEOMETRY(3302, NULL, NULL, SDO_ELEM_INFO_ARRAY(1, 2, 1), SDO_ORDINATE_ARRAY(5, 10, 0, 20, 5, NULL, 35, 10, NULL, 55, 10, 100))

同时,如果要在Oracle Spatial中可以使用这个空间数据,除了在相应的空间表中插入这些记录之外,还需要在元数据表中插入相关记录,插入元数据信息示例如下:

INSERT INTO user_sdo_geom_metadata(TABLE_NAME,COLUMN_NAME,DIMINFO,SRID)

VALUES('SDO_TEST,'SHAPE',

SDO_DIM_ARRAY (

SDO_DIM_ELEMENT('X', 0, 20, 0.005),

SDO_DIM_ELEMENT('Y', 0, 20, 0.005),

SDO_DIM_ELEMENT('M', 0, 100, 0.005)),

NULL);

正常情况下,在USER_SDO_GEOM_METADATA表中可以查到相关的信息(关于USER_SDO_GEOM_METADATA表的作用及定义可以回顾《II.1索引类型SPATIAL_INDEX》):

SQL> select * from user_sdo_geom_metadata where table_name='SDO_ROUTES';

TABLE_NAME COLUMN_NAME

-------------------------------------

DIMINFO(SDO_DIMNAME, SDO_LB, SDO_UB, SDO_TOLERANCE) SRID

------------------------------------------------------------------------------------------------------------------------

SDO_ROUTES SHAPE

SDO_DIM_ARRAY(SDO_DIM_ELEMENT(NULL, 2389694, 2569011.02, .0000005), SDO_DIM_ELEMENT(NULL, 581586.917, 760268.123, .0000005), SDO_DIM_ELEMENT('M', -1000, 267435.456, .0000005))

2. 根据线性参考定位点

对于线性参考的空间对象,就可以根据线性参考来定位对象上的点,比如上述例子中图 15的对象,如果我们要获得在线方向上位于中点的点坐标,我们可以这样做:

SQL> select SDO_LRS.LOCATE_PT(SDO_GEOMETRY(3302, NULL, NULL,SDO_ELEM_INFO_ARRAY(1,2,1),SDO_ORDINATE_ARRAY(5,10,0, 20,5,NULL, 35,10,NULL, 55,10,100)), 50) from dual;

SDO_LRS.LOCATE_PT(SDO_GEOMETRY(3302,NULL,NULL,SDO_ELEM_INFO_ARRAY(1,2,1),SDO_ORDINATE_ARRAY(5,10,0,20,5,NULL,35,10,NULL,

------------------------------------------------------------------------------------------------------------------------

SDO_GEOMETRY(3301, NULL, NULL, SDO_ELEM_INFO_ARRAY(1, 1, 1), SDO_ORDINATE_ARRAY(29.486833, 8.16227766, 50))

image

图 16 线性参考的线中点

其中SDO_LRS包的LOCATE_PT函数原型如下:

SDO_LRS.LOCATE_PT(

geom_segment IN SDO_GEOMETRY,

measure IN NUMBER

[, offset IN NUMBER

) RETURN SDO_GEOMETRY;

注意到这里还可以指定一个offset值,这个值代表查找的定位点可以和线性参考的几何对象有一定的偏移。比如,如果上面的例子中这条线代表一条公路,现在我们想找到离公路中点一边(沿线的右手边)距离为5的某个点,那就可以使用这个offset值,注意,沿线左侧为正、右侧为负:

SQL> select SDO_LRS.LOCATE_PT(SDO_GEOMETRY(3302, NULL, NULL,SDO_ELEM_INFO_ARRAY(1,2,1),SDO_ORDINATE_ARRAY(5,10,0, 20,5,NULL, 35,10,NULL, 55,10,100)), 50, -5) from dual;

SDO_LRS.LOCATE_PT(SDO_GEOMETRY(3302,NULL,NULL,SDO_ELEM_INFO_ARRAY(1,2,1),SDO_ORDINATE_ARRAY(5,10,0,20,5,NULL,35,10,NULL,

------------------------------------------------------------------------------------------------------------------------

SDO_GEOMETRY(3301, NULL, NULL, SDO_ELEM_INFO_ARRAY(1, 1, 1), SDO_ORDINATE_ARRAY(31.0679718, 3.41886117, 50))

image

图 17 线性参考的线中点右侧距离5的点

· ArcSDE

1. 创建线性参考的空间对象

对于如图 15的例子,ArcSDE中如果需要通过SQL语句进行创建可以采用以下的方式:

SQL> select sde.st_astext(sde.st_geometry ('linestring m(5 10 0, 20 5 16.67, 35 10 33.33, 55 10 53.33)', 0)) from dual;

SDE.ST_ASTEXT(SDE.ST_GEOMETRY('LINESTRINGM(5100,20516.67,351033.33,551053.33)',0

--------------------------------------------------------------------------------

LINESTRING M ( 5.00000000 10.00000000 0.00000000, 20.00000000 5.00000000 16.67000000, 35.00000000 10.00000000 33.33000000, 55.00000000 10.00000000 53.33000000)

2. 根据线性参考定位点

ArcSDE对线性参考几何对象的操作并不在数据库层面实现,而是在各种ArcGIS的产品中的ArcObjects进行操作,下面演示了采用ArcGIS Server的ArcObjects进行同上定位的操作:

ServerConnection conn = new ServerConnection();

conn.connect("localhost", "*", "arcgismanager", "passwd");

IServerObjectManager som = conn.getServerObjectManager();

IServerContext serverContext = som.createServerContext(null , null );

try {

Polyline pl = (Polyline)serverContext.createObject(Polyline.getClsid ());

Point pt = null ;

pt = (Point) serverContext.createObject(Point.getClsid ());

pt.setX(5); pt.setY(10); pt.setM(0);

pl.addPoint(pt, null , null );

pt = (Point) serverContext.createObject(Point.getClsid ());

pt.setX(20); pt.setY(5); pt.setM(16.67);

pl.addPoint(pt, null , null );

pt = (Point) serverContext.createObject(Point.getClsid ());

pt.setX(35); pt.setY(10); pt.setM(33.33);

pl.addPoint(pt, null , null );

pt = (Point) serverContext.createObject(Point.getClsid ());

pt.setX(55); pt.setY(10); pt.setM(53.33);

pl.addPoint(pt, null , null );

pl.setMAware(true );

Multipoint mp = (Multipoint)pl.getPointsAtM(26.67, 0);

IPoint ptM = mp.getPoint(0);

System.out .println(ptM.getX() + "," + ptM.getY());

} catch (Exception ex) {

ex.printStackTrace();

} finally {

serverContext.releaseContext();

}

这样的代码可以得到中点的坐标(29.0036,8.0012),这个结果和Oracle Spatial中基本相符(这里为了简便采用了0-16.67-33.33-53.33这样不同的分段)。下面通过修改getPointsAtM()方法的参数查找线中点一边距离为5的点,btw,这里的offset参数的正负规则和Oracle Spatial中是恰恰相反的:

Multipoint mp = (Multipoint)pl.getPointsAtM(26.67, 5);

这样可以得到结果坐标为(30.5847,3.2578)。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(ArcSDE vs. Oracle Spatial 16)