怎么会用到SDE按说,采用
ArcGIS Server开发的系统,完全可以不用直接访问SDE,但我认为有这么几个理由,不按照
ESRI规定的
技术路线使用ArcGIS Server SDK:
1、基于JSF框架的ADF不是唯一的选择。尽管它已经高度浓缩了,但在
Java的世界里,那仅仅是一种选择。很多系统本身并不是建立在这种框架之下的。因此采用此种方式,会大大限制
开发的自由度。当然,快在有些时候是最关键的要求;
2、
GIS软件厂商提供的应用框架都是以GIS应用为核心的,但是在实际应用中,GIS往往是作为整个业务系统的一部分而不是全部的基础。用一部分的影响能力很小,技术上往往要遵循整体的技术架构,不能单独构建。
3、虽然,特定的架构能够在某种程度上进行多源数据的整合,但相对更高层次的聚合,其耦合性更为紧密, 不够松散。对于一个相对复杂的系统来说,足够松散的耦合程度能够更大程度提高系统的灵活性和扩展性。
基于如上观点,我决定在这个系统的GIS部分中采用标准
地图服务作为基本的地图发布方式,属性的查询通过
数据库的定制Web服务,WMS中获取关键信息进行二次查询,而复杂的空间信息的查询(属性条件和空间条件)则通过直接访问空间数据库,有代理直接完成。最后这点其实是由于ArcGIS Server没有提供WFS所造成的,当然,自己实现起来会灵活很多,对于非标准的Mark Text图层,也可以实现出来用于加强显示。
访问空间数据的部分就是通过
ArcSDE SDK来实现的一个简单服务。
怎么会用到对象池经过这几天的研究,终于确认.SDE的连接管理,ESRI并没有实现.根据ArcGIS Server的说明文档,提出ArcGIS的服务都实现了
连接池,而在SDE sdk中却没有找到有关池的信息,配置中也没有相关的选项。这就很容易让人想到,连接池,在ESRI的架构中,应该是属于服务层次而非引擎层次的。而且,SDE作为引擎,要承担长时间的会话,对于频繁而短暂的访问才需要的对象池也就不在此实现了。因此,如果要自定义服务,那么,就必须建立自己的连接池来管理连接。
建立连接池对象的方法其实不难,有很多相关的文章讲解这个问题。http://www.cndw.com/tech/page/2008051479664.asp
然而,如果存在一个现成的,我们还有必要自己写么?(偷懒是我们的制胜法宝)
介绍一下GeoTools的org.geotools.arcsde.pool其实,如果看了上面的那个原理性的讲解,这个包中的类的使用是很简单的。
GeoTools下载在下面这个地址可以获得:
http://geotools.codehaus.org/Downloads
这个包中有四个类,各自的作用如下:
ArcSDEConnectionConfig
连接配置信息,主要是用于设置连接的基本属性
“表现一系列ArcSDE数据库连接(池)参数”
构造器为:
ArcSDEConnectionConfig(Map params)
ArcSDEConnectionConfig(String dbType, String serverName, String portNumber, String databaseName, String userName, String userPassword)
当然,除了第二个构造器中需要的配置信息外,还有两个重要的配置信息,就是MIN_CONNECTIONS_PARAM(最小连接数) 和MAX_CONNECTIONS_PARAM (最大连接数)
ArcSDEConnectionPool
这是我们用来获取连接的对象,就是池对象,它有一个构造器,但是这个构造器是能直接调用的。
ArcSDEConnectionPoolFactory
这是用于创建池对象的对象,它有一个静态方法用于获取实例。“给每一套连接池参数维护着单独的一个连接池”
ArcSDEPooledConnection
类似于SeConnection的一个对象,数据库连接,但是方法更直观方便。
一个例子例子很简单,目的是连接到我的空间数据库中,列出所有可用的表,获取其中一个表的所有图形对象的最小包含范围,并输出为一个Extent字符串(left,bottom,right,top)
<%@ page import="com.esri.sde.sdk.client.*,com.esri.sde.sdk.pe.*,org.geotools.arcsde.pool.*,org.geotools.data.*,java.util.*" contentType="text/html;charset=utf-8"%><% //用一个哈希表来存储配置信息 HashMap m =new HashMap(); //给出基本的连接信息,其中DBTYPE_PARAM必须使用“arcsde”,默认最大对象数是6,最小是2 m.put(ArcSDEConnectionConfig.DBTYPE_PARAM,ArcSDEConnectionConfig.DBTYPE_PARAM_VALUE ); m.put(ArcSDEConnectionConfig.SERVER_NAME_PARAM ,"LENOVO-5E3EDD20"); m.put(ArcSDEConnectionConfig.PORT_NUMBER_PARAM ,"5151"); m.put(ArcSDEConnectionConfig.INSTANCE_NAME_PARAM ,"rodger"); m.put(ArcSDEConnectionConfig.USER_NAME_PARAM,"sde"); m.put(ArcSDEConnectionConfig.PASSWORD_PARAM ,"sde"); //创建一个连接配置对象 ArcSDEConnectionConfig ascc=new ArcSDEConnectionConfig(m); //获取一个池工厂实例 ArcSDEConnectionPoolFactory ascpf=ArcSDEConnectionPoolFactory.getInstance(); try{ //创建一个对象池 ArcSDEConnectionPool ascp= ascpf.createPool(ascc) ; //从池中获取一个连接对象,若没有可用的连接且达到池的上限则抛出异常UnavailableArcSDEConnectionException,此处不做处理,但实际系统中应处理 ArcSDEPooledConnection aspc= ascp.getConnection(); //获取可用图层名列表 List l=ascp.getAvailableLayerNames() ; for (int i=0;i
");
}
//通过连接获取图层,和SDE SDK不同,这里的图层名都带有数据库的用户名
SeLayer sl=aspc.getLayer("SDE.LIANGREGION");
//输出图层对象的最小外接矩形
out.println(sl.getExtent());
//为了让大家对池的管理有个认识,我在这里注释了下面这个语句
//大家可以比较一下有这一句和没有这一句的区别(速度,效果),6次运行之后再刷新页面将会抛出上面提到的异常
//文档中特别强调,与SDE SDK不同,这里的close只是将
//aspc.close();
} catch(DataSourceException e)
{
out.println(e.getMessage());
}
%>
池应该放在哪里对象池是一个对象共享的机制,为了避免重复创建耗费资源而使用的,因此,应该最大化这些对象的共享范围。我认为,对于SDE连接池,最佳的共享范围是应用程序。对于以GIS应用为核心的系统,可以扩展到整个系统,甚至是服务器。