system: [SYSTEM]

user: 3. 功能实现 3.1. ARC SDE空间检索函数 st_geometry的存储格式是由ESRI(美国环境系统研究所公司，Environmental Systems Research Institute)提出的一种新空间数据存储标准，在空间数据检索效率、复杂空间数据的支持方面比oracle spatial表现更专业。要通过SQL函数访问存储在Oracle中的st_geometry类型的数据，需要通过扩展Oracle的external procedure agent或者extproc来实现 [ 5 ] 。 ARC SDE提供了一系列空间检索、数据操作和空间运算函数，本文仅关注实现World Wind Java空间数据检索操作相关部分方法。在空间检索过程中，系统最关注的是用户的点击位置检索、图元缓冲检索、用户指定位置和半径的范围检索以及用户指定区域的交叉检索(如矩形、多边形区域)，相关主要函数如表1所示。 根据不同用户的操作要求，使用st_intersects，或利用st_geometry构建空间图元作为指定的检索区域，也可以在前两者的基础上再使用st_buffer进行缓冲查询。ARC SDE提供了相当多的空间数据操作方法，但是只要掌握这几个方法就完全可以满足我们利用ARC SDE扩展World Wind Java空间检索能力的需要。 3.2. 空间检索效率分析 在实际应用中，为了提高数据检索效率，我们要针对不同的用户需求优化检索方法，尤其是面对海量空间数据操作时。尽管用户的空间检索包含了点、线、面和缓冲检索，归纳起来其实只有两种情况： (1) 用户指定的空间范围(线、面，含缓冲面)是否与数据表空间记录有交叉； (2) 用户指定的空间点是否在数据表空间记录的范围内； 前者只能使用使用st_intersects函数，后者还可以使用st_within函数和st_contains函数，三者的使用方法与效率存在一些差距。st_intersects函数和st_within函数是通过空间索引进行数据检索比对，效率相对较高，而st_contains函数则是利用全表扫描方式进行数据检索比对，效率相对较低。但st_intersects函数执行时会对后一个传入参数先进行全表扫描后再利用空间索引进行比对，所以应用该函数时应当将数据量小的参数作为后面的传入参数以提高检索效率。下面进行一些比较，假设在ARC SDE的空间数据库中已经存在空间数据类型为面图元的数据表TABLEA，记录约25万左右，表2分别列出了针对点、线、面的语句和运行时间。 由表2可以看到，实现相同功能的不同检索语句的执行时间效率差距巨大，有些空间检索甚至可以达到近2000倍，最少的也达到了160倍左右。oracle在执行SQL时，数据表是从后向前按顺序检索的。 Table 1 Spatial retrieve function of ARC SD 序号 方法－参数 方法说明 1. sde.st_intersects (g1， g2) 如果两个ST_Geometries的交集生成空集，则ST_Intersects 返回1或t，反之返回0或f 2. Sde.st_within (g1， g2) Sde.st_contains (g1， g2) 这是一对互补方法，如果g1包含于(st_within)g2或g1包含 (st_contains)g2则返回1或t，反之返回0或f 3. sde.st_buffer (g1， distance) ST_Buffer获取几何对象和距离，然后返回表示围绕源对象的 缓冲区的几何对象 4. sde.st_geometry (x， y， z， m， srid) sde.st_geometry (x， y， z， m， radius， numPts， srid) st_geometry通过文本表示构造几何，利用st_geometry可以 创建所有的ARC SDE支持的空间图元 表 1. ARC SDE空间检索相关函数表 Table 2 Efficiency of spatial retrieve function of ARC SD 类别 SQL语句 查询时间(秒) 点 SELECT COUNT(ID) FROM SDE.TABLEA A WHERE SDE.ST_INTERSECTS (A.SHAPE， SDE.ST_POINT (123.36， 39.15， 11)) = 1 0.062 SELECT COUNT (ID) FROM SDE.TABLEA A WHERE SDE.ST_INTERSECTS (SDE.ST_POINT (123.36， 39.15， 11)， A.SHAPE) = 1 122 SELECT COUNT (ID) FROM SDE.TABLEA A WHERE SDE.WITHIN (SDE.ST_POINT (123.36， 39.15，11)， A.SHAPE) = 1 0.062 SELECT COUNT (ID) FROM SDE.TABLEA A WHERE SDE.ST_CONTAINS (A.SHAPE， SDE.ST_POINT (123.36， 39.15， 11)) = 1 113 线 SELECT COUNT (ID) FROM SDE.TABLEA A WHERE SDE.ST_INTERSECTS (A.SHAPE， SDE.ST_LINEFROMTEXT ('LINESTRING (123.36 39.15， 122.53 37.55)'， 11)) = 1 1.201 SELECT COUNT (ID) FROM SDE.TABLEA A WHERE SDE.ST_INTERSECTS (SDE.ST_LINEFROMTEXT ('LINESTRING (123.36 39.15， 122.53 37.55)'， 11)， A.SHAPE) = 1 190.7 缓冲区(面) SELECT COUNT (ID) FROM SDE.TABLEA A WHERE SDE.ST_INTERSECTS (A.SHAPE， SDE.ST_BUFFER (SDE.ST_POINT (123.36， 39.15， 11)， 0.1)) = 1 0.265 SELECT COUNT (ID) FROM SDE.TABLEA A WHERE SDE.ST_INTERSECTS (SDE.ST_BUFFER (SDE.ST_POINT (123.36， 39.15， 11)， 0.1)， A.SHAPE) = 1 329.6 表 2. ARC SDE空间检索函数效率表 执行表2的第一条SQL语句时，oracle先生成一个point对象，然后与TABLEA中的每条记录的索引对比；执行表2的第二条SQL语句时，oracle会从TABLEA中取出每个图元，再与生成的POINT对象进行空间运行对比，这样在执行一个对比25万条记录的SQL语句时，就要生成25万次对象，而且不能充分利用ARC SDE的索引进行加速。 3.3. 发布空间数据检索的Web Service服务 为了提高集成系统模块的复用性，降低系统间各模块的耦合程度，我们在Apache Tomcat平台上使用Apache CXF(Apache Celtix + XFire)对刚才描述的ARC SDE的存储过程进行了封装。CXF建立的Web Service分为接口部分和实现部分 [ 6 ] ，系统对确权用海项目封装的Web Service如图1所示。图1中的ISDESpatialElementsFactory.java是Web Service实现部分，用户通过调用该方法获取需要检索的经纬度坐标列表，SDESpatialElementsFactoryImpl.java是Web Sevice接口部分，此接口首先利用st_buffer方法获取用户选择区域，再利用st_within方法获取与用户选择区域相交的图元。参考World Wind Java的空间检索方式，系统对指定的空间点进行了一定的扩展，也就是对用户选择位置设置了一定的缓冲半径，避免要求用户必须进行“精确点击”才能拾取图元。 在完成Webs Service发布后，集成框架内的应用系统都可以通过Web Service接口来检索指定位置的确权用海数据，其返回值可以通过两种方法调用： (1) 通过AJAX进行无刷新检索，然后更新系统网页； (2) 通过Applet的JavaScript接口，也就是Object.getWindow(this).eval (javaScriptString)方法获取返回值后直接在Applet中解析应用； 通过Web Service服务的发布，ARC SDE的空间数据检索函数已经能够被World Wind Java和其他Web应用系统所调用，通过这种方法解决了大数据量下WMS空间数据服务与ARC SDE数据源的显示效率和空间检索功能的矛盾，图2显示了利用这种技术构建的“北海区海洋综合信息一张图”中的空间数据检索结果。 图 1. 使用CXF封装的指定空间点检索的Web Service服务 图 2. 利用本文方法实现的World Wind Java应用界面