2008-06-12

自定义Tools开

什么是tools,tools就是工具,它跟command的区别就是tools是要跟地图进行交互后再执行某个命令,而command是直接执行某个命令。最简单的tools和command的对比是放大是一个工具,而全图显示就是一个命令。

ESRI已经包含的工具包括:放大(zoom in),缩小(zoom out),平移(Pan)。

前面我们都是先说服务器端的处理代码,现在先来看看客户端的处理。跟地图交互,就会产生怎么交互的问题。拉框放大的时候是在地图上画的是一个长方形,测距的时候在地图上画的是一条线。如何控制这些客户端的功能呢?

查看com.esri.adf.web.faces.event.MapEvnet的帮助,里面详细说明了如何把客户端的操作如何和服务器端的代码建立联系。已有的客户端支持的操作包括:
EsriMapCircle 
EsriMapContinuousPan 
EsriMapLine 
EsriMapOval 
EsriMapPan 
EsriMapPoint 
EsriMapPolygon 
EsriMapPolyline 
EsriMapRectangle

如果我们要自己写一个工具,我们可以新建一个普通的类,这个类可以实现MapToolAction接口,也可以不实现任何接口。我们先来看一个实现接口的类。


public class CJZoomInTool implements MapToolAction {

    public void execute(MapEvent event)  {

        WebContext ctx = event.getWebContext();
        WebGeometry screenGeom = event.getWebGeometry();
        WebGeometry mapGeom = screen.toMapGeometry(ctx.getWebMap());
    }
}


我们可以看到,通过MapEvent的getWebGeometry方法可以得到客户端所画的多边形,此时得到的是屏幕坐标,然后再通过toMapGeometry方法转换为地图坐标。

MapEvent的getWebGeometry方法事实上是指向到ClientActionArgs的getWebGeometry方法,你可以用下面的代码得到另外一个WebGeometry进行比较:

ClientActionArgs clientarg=event.getClientActionArgs();
WebGeometry anotherGeom=clientarg.getWebGeometry();

我们还可以用ClientActionArcgs的getRequestParameter查看传送过来的参数是什么,在客户端指定长方形的情况下,得到的RequestParamerter里面有如下参数:
Map0_maxx:246
Map0_miny:147
Map0_minx:199
Map0_maxy:199

你一定想看看客户端是多边形的情况下,参数是什么情况,我们满足一下您的愿望:
Map0_coords:220:168|264:220|296:186|292:136|258:125

出现了以|分隔的参数集合,这个意思大家都明白了吧,这就是多边形的情况。

ClientActionArgs是一个基类,它的所有的子类对应于每一个客户端的操作。每个积累需要实现它的抽象方法。最重要的两个方法是init()和getWebGeometry,init从request里面得到所有的参数,getWebGeometry从根据不同的参数,构建不同的geometry返回。ADF会根据不同的客户端操作,创建不同的ClientActionArgs类。如果你一定要问我ADF是如何根据不同的客户端操作创建ClientActionArgs的,我们可以看到ClientActionArgs有一个静态方法:
getClientActionArgs(java.lang.String clientAction, java.util.Map requestParameters, java.lang.String controlId)

ADF就是用这个静态方法,根据不同的clientAction可以得到的ClientActionArgs。

这一下,把来龙去脉都讲了,既让大家看看整个客户端和服务器端操作的来龙去脉,也为大家增加自己的客户端操作热个身。

当然,自定义一个tool并不需要这么多的知识。事实上,自定义一个tools非常得简单,我们来看看帮助中的一段代码,计算选中了多少个要素。
package com.cj.ucdemo;

import java.rmi.RemoteException;

import com.esri.adf.web.ags.ADFAGSException;
import com.esri.adf.web.ags.data.AGSMapResource;
import com.esri.adf.web.data.WebContext;
import com.esri.adf.web.data.geometry.WebExtent;
import com.esri.adf.web.faces.event.MapEvent;
import com.esri.adf.web.faces.event.MapToolAction;
import com.esri.arcgisws.EnvelopeN;
import com.esri.arcgisws.EsriSearchOrder;
import com.esri.arcgisws.EsriSpatialRelEnum;
import com.esri.arcgisws.MapServerPort;
import com.esri.arcgisws.SpatialFilter;

public class CountFeatureTool implements MapToolAction {
         
         WebContext context=null;
         int countedFeatures;
         
         private void countFeatures(WebExtent extent){
                  
                    //Get the MapServerPort so we can execute methods through ArcGIS Server API
                    
                    AGSMapResource agsMap = ((AGSMapResource)context.getResources().get("ags1"));
                    MapServerPort mapServer = agsMap.getMapServer();
                    //Make a new envelope from the web extent
                    EnvelopeN env = new EnvelopeN(extent.getMinX(), extent.getMinY(), extent.getMaxX(), extent.getMaxY(),
                      null, null, null, null, null);

                    //Setup a spatial filter for an Intersection relationship
                    SpatialFilter spatialFilter = new SpatialFilter();
                    spatialFilter.setSpatialRel(EsriSpatialRelEnum.esriSpatialRelIntersects);
                    spatialFilter.setWhereClause("");
                    spatialFilter.setSearchOrder(EsriSearchOrder.esriSearchOrderSpatial);
                    spatialFilter.setSpatialRelDescription("");
                    spatialFilter.setGeometryFieldName("");
                    //Set the envelope as the geometry
                    spatialFilter.setFilterGeometry(env);

                    //MapServer::queryFeatureCount() executes on the server and can throw a RemoteException
                    try{
                      //Count features in 4th layer which intersect with the envelope
                      int layerId = 1;
                      this.countedFeatures =
                        mapServer.queryFeatureCount(mapServer.getDefaultMapName(), layerId, spatialFilter);
                      
                      System.out.println("你选择了 "+countedFeatures+" 要素");
                      
                    }catch(RemoteException rme){
                      //Rethrow this as ADFAGSException so that it can participate in the exception framework
                      throw new ADFAGSException("Could not execute MapServer::queryFeatureCount()",rme);
                    }
                  }

         

         public void execute(MapEvent arg0) throws Exception {
                  // TODO Auto-generated method stub
                  try{
                            this.context=arg0.getWebContext();
                  WebExtent ex=(WebExtent)arg0.getWebGeometry();
                  ex=(WebExtent)ex.toMapGeometry(arg0.getWebContext().getWebMap());
                  this.countFeatures(ex);
                  }catch(Exception ex){
                            ex.printStackTrace();
                  }

         }

}


大家注意这里使用了很多com.esri.arcgisws package里面的类,这个package是通过axis调用远程webservice的方式去调用服务器端的方法的。我们会在后续的讲座中说明。编译这个类后,直接在jsp页面里面用下面的代码调用即可:
  <a:tool id="countFeature" defaultImage="images/selection.gif" hoverImage="images/ selectionU.gif"  selectedImage="images/ selectionD.gif" clientAction="EsriMapRectangle"                                 serverAction="com.cj.ucdemo.CountFeatureTool" clientPostBack="true"/>
评论
发表评论

您还没有登录,请登录后发表评论

Virgo_S
搜索本博客
存档
最新评论