在ArcGIS API for Flex中实现鹰眼图中方框的拖动

  这是我第一次写blog,主要目的是想告诉大家如何在ArcGIS API for Flex中拖动Graphic对象,如果是Graphic对象是鹰眼图中方框的话,可以在鹰眼图中拖动方框以改变主图的范围,如果是点图形,则可以用于做最短路径分析,通过移动起点或终点,最短路径可以重新计算,所以这个功能可以说是实现一些更高级功能的基础,所以还是比较实用的。

   话不多说,说一说思路,以Extent为例(注意,这里的Extent是graphic.geometry类型而不是graphic.geometry.extent类型),对这个Extent拖动时会经历四个事件,鼠标按下,鼠标移动,鼠标放开,哎,这不是三个事件吗?别忘了,鼠标按下和放开就是一个Click事件(对这个Click事件的监听在鹰眼图中有很大用处,后面再说)。那么如何对Extent添加这四个事件监听器呢,肯定不是同时添加,看下面的代码

 1 public var extentBox:Graphic = new Graphic();
 2 public var dragStartExtent:Extent;
 3 public var dragStartPoint:MapPoint;
 4 protected function layerCreationComplete(event:FlexEvent):void
 5 {
 6                 
 7     layer.add(extentBox);
 8     extentBox.symbol = extentBoxSym;
 9     extentBox.buttonMode=true;
10                 
11     extentBox.addEventListene(MouseEvent.MOUSE_DOWN,graphicStartDrag);
12     extentBox.addEventListene(MouseEvent.CLICK,onBoxClick);
13                 
14     if(mainMap.loaded)
15     {
16           extentBox.geometry=mainMap.extent;
17     }
18 }
19             
20 protected function graphicStartDrag(event:MouseEvent):void
21 {
22     extentBox.addEventListener(MouseEvent.MOUSE_MOVE,graphicUpdate);    
23     extentBox.addEventListener(MouseEvent.MOUSE_UP,graphicDragEnd);
24                 
25     dragStartPoint = overviewMap.toMapFromStage(event.stageX,event.stageY);    
26     dragStartExtent=extentBox.geometry.extent;            
27 }
28             
29 protected function graphicUpdate(event:MouseEvent):void
30 {
31     var mapPoint:MapPoint=MapPoint(overviewMap.toMapFromStage(event.stageX,event.stageY));
32     var xOff:Number=mapPoint.x-dragStartPoint.x;
33     var yOff:Number=mapPoint.y-dragStartPoint.y;        
34                 
35     var newExtent:Extent=dragStartExtent.offset(xOff,yOff);   
36     extentBox.geometry=newExtent;
37 }
38             
39 protected function graphicDragEnd(event:MouseEvent):void
40 {
41      extentBox.removeEventListener(MouseEvent.MOUSE_MOVE,graphicUpdate);
42      extentBox.removeEventListener(MouseEvent.MOUSE_UP,graphicDragEnd);
43      mainMap.extent=extentBox.geometry.extent;
44 }

  (注:mainMap是主地图,overviewMap是鹰眼图)

  在上面的代码中layerCreationComplete是监听GraphicsLayer创建完成时触发的函数,在GraphicsLayer创建完成后将extentBox(也就是鹰眼图中的方框)添加到该图层中,如果主地图加载完成的话,则方框即为主地图范围,然后对extentBox添加的两个事件监听器,MOUSE_DOWN和CLICK。

  graphicStartDrag是监听MOUSE_DOWN触发的函数,当鼠标按下时又对extentBox添加的两个事件监听器,MOUSE_MOVE和MOUSE_UP,至此对extentBox拖动时的四个事件进行了监听。然后记录鼠标按下时起始点,用了toMapFromStage方法将屏幕上的点转化为了地图上的点,以及记录鼠标按下时extentBox的初始范围(如果是点的话,只记录起始点就可以了)。

  graphicUpdate是监听MOUSE_MOVE触发的函数,也就是实现extentBox拖动的函数,这里面最关键的就是这两行

var newExtent:Extent=dragStartExtent.offset(xOff,yOff);  
extentBox.geometry=newExtent;

  利用offset的方法在拖动时不断的生成newExtent,然后用newExtent来实时更新extentBox的geometry属性,这两行就是Graphic拖动的精髓了,它的思想是不销毁Graphic对象,而是不断的更新Graphic的gemotry属性来实现Graphic对象的移动。我刚开始做的时候,总是想着在移动的时候不断的生成和不断的销毁Graphic对象,结果总是移动了一下整个extentBox就没了,我后来想了下,extentBox销毁后对MOUSE_MOVE的监听就算结束了,所以只有不销毁extentBox,才能一直保持对MOUSE_MOVE事件的监听,然后通过不断的改变geomotry属性来达到移动的效果。

  graphicDragEnd是监听MOUSE_UP触发的函数,主要是为了移除对MOUSE_MOVE和MOUSE_UP这两个事件的监听,如果不移除的话,在对extentBox进行第一次拖动以后,鼠标在滑过extentBox时,extentBox又会跟着鼠标一起动,而且会发生一些意想不到的错误,不是有句话吗,出来混,总是要还的,呵呵。

  然后来说一下对CLICK事件监听的作用,看下面的代码

 1 private function onBoxClick( event:MouseEvent ):void
 2 {              
 3     event.stopPropagation();   
 4 }
 5             
 6 protected function overviewMapClick(event:MouseEvent):void
 7 {
 8     var newExtent:Extent=extentBox.geometry.extent.centerAt(overviewMap.toMapFromStage(event.stageX,event.stageY));
 9     extentBox.geometry=newExtent;
10     mainMap.extent=newExtent;
11 }                

  先看overviewMapClick这个函数,它是对监听鹰眼图CLICK事件触发的函数,它的作用就是,当用户在鹰眼图上点击时,extentBox移动到以该点为中心的位置,然后使主地图进行联动。但是,当用户在extentBox内部单击时,却不会发生任何事。前面我已经说过了,extentBox在拖动过程中会触发CLICK事件,在上面的代码中extentBox监听CLICK事件触发的函数只有一行代码

event.stopPropagation();

  从字面来看,stopPropagation,停止传播,它的作用就是不让CLICK事件传播到鹰眼图中,我们来看看它有什么用。对 extentBox单击时,extentBox和鹰眼图会同时分派CLICK事件,对extentBox拖动完成后,相当于同时单击了extentBox和鹰眼图,因为鹰眼图中已经添加了对CLICK事件的监听,那么总是会使方框移动到以该点为中心的位置,如果你移动方框的起始点不是extentBox的中心点,extentBox总是会移动到以你拖动完成时鼠标放开的点为中心的位置,这句话很拗口,总之你的extentBox的在拖动完成后会突然位移。但是,对extentBox添加对CLICK事件的监听后,使用stopPropagation方法,就可以使鹰眼图不会监听到CLICK事件,所以就可以保证对extentBox拖动后,extentBox不会发生位移。

  这个实际上是Flex的事件机制,捕获,目标,冒泡,关于Flex的事件机制,我这里就不讲了,网上有好多资料,可以自行查阅

   最后顺便说一句,鹰眼图最好用ArcGISDynamicMapServiceLayer,好不好你用了就知道

posted @ 2013-06-21 15:25  拖鞋公子  阅读(1274)  评论(0编辑  收藏  举报