一起学习ArcEngine(8)鹰眼

ae的官方类库没有提供该控件,需要自己实现,不过也比较简单,原理或实现的思路是,另外增加一个axMapControl控件,把他的视图设为地图的全图范围,把当前地图的范围,在这个地图控件上用红色框画出来即可。

首先新建一个用户控件,名称设为MapEagle,在控件上拖拽一个axmapcontrol控件,名称设为axMapEagle ,用来显示地图。

接下来,增加一个自定义属性,用来和地图主窗口关联,使得axMapEagle 能获得当前地图的范围

   1:  private AxMapControl pMap;
   2:          
   3:          /// <summary>
   4:          /// 关联的地图控件
   5:          /// </summary>
   6:          public AxMapControl MapControl
   7:          {
   8:              set
   9:              {
  10:                  if (value != pMap) pMap = value;
  11:                  //this.axMapEagle.Extent = pMap.FullExtent;
  12:                  pMap.OnMapReplaced += new IMapControlEvents2_Ax_OnMapReplacedEventHandler(pMap_OnMapReplaced);
  13:                  pMap.OnExtentUpdated += new IMapControlEvents2_Ax_OnExtentUpdatedEventHandler(pMap_OnExtentUpdated);
  14:              }
  15:   
  16:          }

主地图控件的OnMapReplaced事件,使得当主地图窗口重新加载时,刷新axMapEagle 的视图范围,实现代码如下

   1:    void pMap_OnMapReplaced(object sender, IMapControlEvents2_OnMapReplacedEvent e)
   2:          {
   3:   
   4:              for (int i = 0; i <= pMap.LayerCount; i++)
   5:              {
   6:                  axMapEagle.AddLayer(pMap.get_Layer(i));
   7:              }
   8:              this.axMapEagle.Extent = pMap.FullExtent;
   9:   
  10:              IGraphicsContainer pGraphicsContainer = this.axMapEagle.Map as IGraphicsContainer;
  11:              IActiveView pActiveView = pGraphicsContainer as IActiveView;
  12:              pGraphicsContainer.DeleteAllElements();
  13:   
  14:              IElement pEle = Envelope2Element(pMap.Extent);
  15:              pGraphicsContainer.AddElement(pEle, 0);
  16:              pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
  17:          }

该事件中,首先将主地图的图层都加载到axMapEagle 控件中,然后将试图设为全图,接下来删除窗口中的所有Element,再往后就是把主地图的视图范围,在axMapEagle 的视图上画出来,采用创建element的方法实现,方法Envelope2Element 实现将视图范围IEnvelope转化为一个element,把axMapEagle的地图设为图形容器,把创建好的element加进去,然后刷新视图即可。

方法Envelope2Element 的实现过程,如下所示

   1:   private IElement Envelope2Element(IEnvelope env)
   2:          {
   3:              IRectangleElement pRectangleEle = new RectangleElementClass();
   4:              IElement pEle = pRectangleEle as IElement;
   5:              pEle.Geometry = env;
   6:   
   7:              IRgbColor pColor = new RgbColorClass();
   8:              pColor.RGB = 255;
   9:              pColor.Transparency = 255;
  10:   
  11:              ILineSymbol pOutline = new SimpleLineSymbolClass();
  12:              pOutline.Width = 1.5;
  13:              pOutline.Color = pColor;
  14:   
  15:              pColor = new RgbColorClass();
  16:              pColor.RGB = 255;
  17:              pColor.Transparency = 0;
  18:   
  19:              IFillSymbol pFillSymbol = new SimpleFillSymbolClass();
  20:              pFillSymbol.Color = pColor;
  21:              pFillSymbol.Outline = pOutline;
  22:   
  23:              IFillShapeElement pFillshapeEle = pEle as IFillShapeElement;
  24:              pFillshapeEle.Symbol = pFillSymbol;
  25:              return  pFillshapeEle as IElement;
  26:          }

到这里已经实现一半了,剩下当主地图视图放大或缩小后,鹰眼地图上的范围标示随之变化没有实现了。也就是主地图的OnExtentUpdated方法,它的官方说明是这样 “Fires after the extent (visible bounds) of the MapControl is changed.”当地图控件的可视范围变化后触发,正是我们想要的。它的实现和加载时一样,同样将变化后的视图范围在地图上绘制就可以了,不用重新加载地图,具体代码如下

   1:          void pMap_OnExtentUpdated(object sender, IMapControlEvents2_OnExtentUpdatedEvent e)
   2:          {
                   //删除已添加的Element
   3:              IGraphicsContainer pGraphicsContainer = this.axMapEagle.Map as IGraphicsContainer;
   4:              IActiveView pActiveView = pGraphicsContainer as IActiveView;
   5:              pGraphicsContainer.DeleteAllElements();
   6:   
   7:              IElement pEle = Envelope2Element(e.newEnvelope as IEnvelope );
   8:              pGraphicsContainer.AddElement(pEle, 0);
   9:              pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
  10:          }
工作已经完成90%了,呵呵,axMapEagle 控件都会适应主地图视图的变化,还缺的就是主地图视图要适应axMapEagle的视图变化。
即,当在鹰眼视图上点击时,主地图也要能够移动到点击的位置,这样才是真正的方便。要实现这样的功能,就要用到地图控件
的OnMouseDown事件,代码如下
   1:  private void axMapEagle_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
   2:          {
   3:              IRubberBand pBand = new RubberEnvelopeClass();
   4:              IGeometry pGeometry = pBand.TrackNew(axMapEagle.ActiveView.ScreenDisplay, null);
   5:            
   6:              if (pGeometry.IsEmpty)
   7:              {
   8:                  IPoint pPt = new PointClass();
   9:                  pPt.PutCoords(e.mapX, e.mapY);
  10:                  //改变主控件的视图范围
  11:                  pMap.CenterAt(pPt);
  12:              }
  13:              else
  14:              {
  15:                  pMap.Extent = pGeometry.Envelope;
  16:                  pMap.ActiveView.Refresh();
  17:              }
  18:          }

IRubberBand 接口的官方解释是”Provides access to members that control simple rubberbanding.”rubberbanding 翻译过来是‘橡皮带式生成线’;直译是提供控制简单橡皮带式生成线的权限,(英语水平太凹了,只能查字典直译了!)就是能够控制按下鼠标左键拉框时的框范围。该接口的TrackNew方法就是将拉框转换成一个地理要素,然后可以根据这个要素对地图范围进行设定。

大功告成,主地图和鹰眼实现双向互动了!

http://www.cnblogs.com/liuyh208/archive/2009/09/28/1576011.html

http://blog.csdn.net/zhongjiekangping/article/details/6618412

转载自:https://blog.csdn.net/mycomputerxiaomei/article/details/7646689

You may also like...