《ArcGIS Server:如何动态添加图层并进行查询》由会员分享,可在线阅读,更多相关《ArcGIS Server:如何动态添加图层并进行查询(12页珍藏版)》请在金锄头文库上搜索。
1、ArcGIS Server 如何动态添加图层并进行查询如何动态添加图层并进行查询作者:未知 文章来源:ESRI 中国(北京)有限公司 点击数:6952 更新时间: 2008-9-18 软件:ArcGIS Server for Java platform版本:9.2平台:Solaris 9.0, 10; Linux Red Hat AS/ES 3.0, AS/ES 4.0; Linux-SUSE Server 9在 ArcGIS Server 9.2 的应用程序中,如果使用的资源类型是 com.esri.adf.web.ags.data.AGSLocalMapResource,就可以在该资源上动
2、态添加新的图层,图 层数据可以来自不同的地方,比如本地的 shapefile、file geodatabase 或者 SDE,也可以来 自 WMS 等 web 服务。本文以本地的 file geodatabase 为例,为 AGSLocalMapResource 动态 添加一个新的图层。首先,要得到地图的 IMap 接口才能对地图的图层进行操作。清单 1. 获取 IMap 接口1. AGSLocalMapResource res = (AGSLocalMapResource)webContext .getResources().get(“ags0“);2. com.esri.arcgis.ca
3、rto.MapServer mapServer = res.getLocalMapServer();3. try 4. IMap map = mapServer.getMap(mapServer.getDefaultMapName();5. map.addLayer(ILayer layer); 6. catch(Exception e)7. 动态添加图层的核心代码就是第 5 行,它接收的参数是实现了 ILayer 接口的对象。因此, 接下来我们需要把 file geodatabase 里的 feature class 组装成一个 ILayer 对象。清单 2. 从 Feature Class
4、 到 ILayer1. IServerContext sctx = res.getServerContext();2. IWorkspaceFactory pWorkspaceFactory = (IWorkspaceFactory) sctx .createObject(FileGDBWorkspaceFactory.getClsid();3. IFeatureWorkspace pFWS = (IFeatureWorkspace) pWorkspaceFactory .openFromFile(“E:dataqixiangqixiang.gdb“, 0);4. IFeatureClass
5、fc = pFWS.openFeatureClass(“Road“);5. IFeatureLayer fLayer = (IFeatureLayer) sctx .createObject(FeatureLayer.getClsid();6. fLayer.setFeatureClassByRef(fc);7. fLayer.setName(“Road“); Server 中的 AO 对象,必须在一个 IServerContext 上下文中使用,因此,AO 对象的创建跟 一般的 Java 类有所不同。因为数据是保存在 filegeodatabase,所以在第 2 行代码中我们创 建了一个 F
6、ileGDBWorkspaceFactory,接下来的两行利用这个工厂类打开了一个 IFeatureWorkspace,然后读取了其中的一个 feature class。最后,用这个 feature class 设置了 一个 IFeatureLayer(ILayer 的一个子类) 。有了 IMap 和 IFeatureLayer 对象以后,其实就已经能动态添加图层了。但是这样添加的图 层有一点欠缺的地方它的渲染方式是随机的。就像我们用 ArcMap 直接打开一个 polygon feature class 时,ArcMap 会随机选择一个填充色。为了保证每次用户添加图层以后 能够看到同样的效果
7、,我们需要为动态图层设置一个渲染方式。当然,我们可以在程序中 为不同类型的要素分别设置一个 Renderer,但是本文将探讨另一种方式。先用 ArcMap 设 置好渲染方式,然后保存成一个*.lyr 文件,动态添加图层的时候从 lyr 文件中读取 Renderer 信息,然后添加到 IFeatureLayer。毕竟,用 ArcMap 设置 Renderer 比写代码要简 单多了!而且,也更易于分发。清单 3. 从*.lyr 文件中读取 Renderer 信息1. IMapDocument doc = (IMapDocument)sctx.createObject(MapDocument.get
8、Clsid();2. doc.open(lyrFilePath, null);3. ILayer lyr = doc.getLayer(0, 0);/get the first maps first layer4. IFeatureRenderer renderer = null;5. if(lyr instanceof IGeoFeatureLayer)6. IGeoFeatureLayer geoLyr = (IGeoFeatureLayer)lyr;7. renderer = geoLyr.getRenderer();8. 在清单 3 中我们创建了一个 MapDocument 对象来读取
9、 lyr 文件(API 说明:The MapDocument CoClass encapsulates map document files (*.mxd, *mxt, *.pmf) and layer files (*.lyr)) 。第 2 行代码中的 lyrFilePath 就是 lyr 文件存放的路径。由于打开的是 lyr 文件,只 有一个图层,所以第 3 行代码的两个参数都为零,表示打开的是第一个地图的第一个图层。 接下来从图层文件中读取 Renderer 信息。接下来,我们就可以把 Renderer 信息赋给图层,然后将图层添加到地图上。清单 4. 设置渲染方式,添加图层1. if(
10、renderer != null)2. IGeoFeatureLayer geoFeatureLyr = (IGeoFeatureLayer)fLayer;3. geoFeatureLyr.setRendererByRef(renderer);4. 5. fLayer.setVisible(true);6. map.addLayer(fLayer);7. map.moveLayer(fLayer, 1);至此,我们通过 map service 提供的 AO 接口完成了动态添加图层的工作,但是如果这时候 我们去刷新浏览器,并不会看到新增加的图层!这是由于 Web ADF 层还不知道图层信息 发生
11、变化了。这与 Web ADF 的初始化有关,当一个 session 启动的时候,WebContext 会根 据 map service 的信息完成初始化,包括一些列的 functionalities 以及 attributes,这些初始化 信息中就包含图层信息(保存在 com.esri.arcgisws.MapDescription 和 com.esri.arcgisws.MapLayerInfo 等类中) 。在 WebContext 初始化完成以后,如果 map service 的信息发生改变,必须由程序员自己去刷新 Web ADF 中的相关对象,实现 Web ADF 对象与 map ser
12、vice 同步。有趣的是,并不是所有对 map service 的修改都要自己去通 知 Web ADF,比如修改图层的 Renderer 信息就不需要。我觉得如果 com.esri.arcgisws 包中 的与 AO 同名的对象,很可能就需要手工修改,因为这些对象都是初始化的时候创建的; 如果没有,说明没有必要为其单独创建 Web ADF 对象,需要的时候就直接访问 AO 接口 了。清单 5. 刷新 ADF 对象1. mapServer.refreshServerObjects();2. IMapServerInfo serverInfo = mapServer.getServerInfo(m
13、apServer.getDefaultMapName();3. agsServerInfo = (com.esri.arcgisws.MapServerInfo)AGSUtil.createStubFromArcObject(serverInfo,com.esri.arcgis ws.MapServerInfo.class,sctx);4. com.esri.arcgisws.MapServerInfo si = mapFun.getMapServerInfo();5. si.setMapLayerInfos(agsServerInfo.getMapLayerInfos();6. mapFun
14、.setMapDescription(agsServerInfo.getDefaultMapDescription();在清单 5 中,我们先刷新了 map server object,然后获取了新的 IMapServerInfo 对象。第 3 行代码中我们完成了从 AO 对象到 ADF 对象的转换,这样,ADF 就有了一个反映当前 map service 状态的 com.esri.arcgisws.MapServerInfo。4 到 6 行代码用新的 com.esri.arcgisws.MapServerInfo 刷新了 AGSMapFunctionality,从而完成了 ADF 与 map
15、 service 的同步。下面的截图显示了动态添加图层的效果。由于 WebContext 以及它管理的一系列 ADF 资源只在 session 开始时进行一次初始化,因此 动态添加的图层就无法用 WebQuery 来进行查询和高亮显示。在清单 5 中已经介绍了如何 刷新 ADF 端的对象,因此,我们可以用更新以后的 com.esri.arcgisws.MapServerPort 对动态 添加的图层进行查询。接下来的例子中,让用户在地图上拖一个矩形框,然后查询所有图层中与该矩形框相交的 要素,并将它们高亮显示。首先需要将用户在地图上绘制的矩形框传递到服务器端,并创 建一个 com.esri.arcgisws.PolygonN 对象。清单 6. 捕获屏幕操作并构造服务器端几何要素 1. WebExtent ext = (WebExtent)event.getWebGeometry().toMapGeometry(webContext.getWebMap();2. EnvelopeN env = (EnvelopeN)AGSUtil.toAGSGeometry