首页 > 代码库 > ArcGIS Engine开发之鹰眼视图

ArcGIS Engine开发之鹰眼视图

鹰眼是GIS软件的必备功能之一。它是一个MapControl控件,主要用来表示数据视图中的地理范围在全图中的位置。

鹰眼一般具有的功能:

1)鹰眼视图与数据视图的地理范围保持同步。

2)数据视图的当前范围能够在鹰眼视图中用一个矩形框标示出来。若数据视图的显示范围发生变化,鹰眼视图中的矩形框位置也会发生变化。

3)在鹰眼中操作视图,数据视图中的地理范围也将同步调整。当鹰眼中用鼠标点击时,数据视图能够移动到被点击的位置。拖动矩形框可以调整数据视图中的地图显示范围;在鹰眼视图上拖动矩形框时,数据视图能够以全图显示矩形框内的内容。

具体的开发过程:

1)进行鹰眼变量的定义(全局变量)

1  //鹰眼相关变量的定义2         private bool bCanDrag;//鹰眼地图上的矩形可移动的标志3         private IPoint pMoveRectPoint;//记录在移动鹰眼地图上的矩形框时鼠标的位置4         private IEnvelope pEnv;//记录数据视图的Extent

2)鹰眼中数据与数据视图中的数据一致,且鹰眼视图中的地图始终显示为全图。当数据视图加载地图数据时,同时也把数据加载到鹰眼控件中,考虑到鹰眼中只能添加个别全局性的图层,这里需要对地图数据进行过滤,逐一添加到鹰眼中。其中Map Control 的OnMapReplaced事件只能在*.mxd文件打开时触发,加载单一图层时不被触发,故将封装一个单独的鹰眼同步的方法:

 1  #region 同步鹰眼视图的方法封装 2         private void SynchronizeEagleEye() 3         { 4             if (EagleEyeMapControl.LayerCount > 0) 5             { 6                 EagleEyeMapControl.ClearLayers(); 7             } 8             //设置鹰眼和MainMapcontrol中地图的坐标系统一致 9             EagleEyeMapControl.SpatialReference = mainMapControl.SpatialReference;10             for (int i = mainMapControl.LayerCount - 1; i >= 0; i--)11             {12                 //是鹰眼视图与数据视图的图层上下顺序保持一致13                 ILayer pLayer = mainMapControl.get_Layer(i);14                 if (pLayer is IGroupLayer || pLayer is ICompositeLayer)15                 {16                     ICompositeLayer pCompositeLayer = (ICompositeLayer)pLayer;17                     for (int j = pCompositeLayer.Count - 1; j >= 0; j--)18                     {19                         ILayer pSubLayer = pCompositeLayer.get_Layer(i);20                         IFeatureLayer pFeatureLayer = pSubLayer as IFeatureLayer;21                         if (pFeatureLayer != null)22                         {23                             if (pFeatureLayer.FeatureClass.ShapeType != esriGeometryType.esriGeometryPoint && pFeatureLayer.FeatureClass.ShapeType != esriGeometryType.esriGeometryMultipoint)24                             {25                                 EagleEyeMapControl.AddLayer(pLayer);26                             }27                         }28                     }29                 }30                 else31                 {32                     IFeatureLayer pFeatureLayer = pLayer as IFeatureLayer;33                     if (pFeatureLayer != null)34                     {35                         if (pFeatureLayer.FeatureClass.ShapeType != esriGeometryType.esriGeometryPoint && pFeatureLayer.FeatureClass.ShapeType != esriGeometryType.esriGeometryMultipoint)36                         {37                             EagleEyeMapControl.AddLayer(pLayer);38                         }39                     }40                     //设置鹰眼地图的全图显示41                     EagleEyeMapControl.Extent = mainMapControl.FullExtent;42                     pEnv = mainMapControl.Extent as IEnvelope;43                     DrawRectangle(pEnv);44                     EagleEyeMapControl.ActiveView.Refresh();45                 }46             }47         }48         #endregion

3)封装好同步鹰眼的方法后,分别在mainMapControl的OnMapReplaced事件和其他操作中进行方法的调用。
4)定义获取RGB颜色的方法,用来渲染鹰眼中的矩形框和后期其他功能的使用。

 1  #region 获取RGB颜色 2         private IRgbColor GetRgbColor(int intR, int intG, int intB) 3         { 4             IRgbColor pRgbColor = null; 5             if (intR < 0 || intR > 255 || intG < 0 || intG > 255 || intB < 0 || intB > 255) 6             { 7                 return pRgbColor; 8             } 9             pRgbColor = new RgbColorClass();10             pRgbColor.Red = intR;11             pRgbColor.Green = intG;12             pRgbColor.Blue = intB;13             return pRgbColor;14         }15         #endregion

5)封装绘制矩形框的方法

 1  #region 鹰眼中矩形框绘制的方法封装 2         private void DrawRectangle(IEnvelope pEnvelop) 3         { 4             //在绘制前,清除鹰眼中之前绘制的矩形框 5             IGraphicsContainer pGraphicsContainer = EagleEyeMapControl.Map as IGraphicsContainer; 6             IActiveView pActiveView = pGraphicsContainer as IActiveView; 7             pGraphicsContainer.DeleteAllElements(); 8             //得到当前视图范围 9             IRectangleElement pRectangleElement = new RectangleElementClass();10             IElement pElement = pRectangleElement as IElement;11             pElement.Geometry = pEnvelop;12             //设置矩形框(实质为中间透明度面)13             IRgbColor pColor = new RgbColorClass();14             pColor = GetRgbColor(255, 0, 0);15             pColor.Transparency = 255;16             ILineSymbol pOutLine = new SimpleLineSymbolClass();17             pOutLine.Width = 1;18             pOutLine.Color = pColor;19 20             IFillSymbol pFillSymbol = new SimpleFillSymbolClass();21             pColor = new RgbColorClass();22             pColor.Transparency = 0;23             pFillSymbol.Color = pColor;24             pFillSymbol.Outline = pOutLine;25             //向鹰眼中添加矩形框26             IFillShapeElement pFillShapeElement = pElement as IFillShapeElement;27             pFillShapeElement.Symbol = pFillSymbol;28             pGraphicsContainer.AddElement((IElement)pFillShapeElement, 0);29             //刷新30             pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);31         }32         #endregion

6)实现矩形框和数据视图的联动。当数据视图的显示范围发生变化时,会触发OnExtentUpdate事件,在该事件中绘制鹰眼视图中的方框。获取数据视图中的地图显示范围作为矩形框范围,添加到鹰眼视图中。

1 private void mainMapControl_OnExtentUpdated(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnExtentUpdatedEvent e)2         {3             //得到当前视图范围4             IEnvelope pEnvelop = (IEnvelope)e.newEnvelope;5             DrawRectangle(pEnvelop);6         }

7)实现矩形框的拖动和绘制

思路:1.在鹰眼的操作时,若是鼠标左键键点击,判断鼠标点击是否在矩形框之内。若在则可以进行矩形框的拖动;若不在则使数据视图以当前点击点为中心进行显示。

2.当鼠标右键点击时,可以进行矩形框的绘制,使数据视图的地图显示为矩形框范围。

代码:

 1   #region 鹰眼视图的OnMouseDown事件 2         private void EagleEyeMapControl_OnMouseDown(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseDownEvent e) 3         { 4             if (EagleEyeMapControl.Map.LayerCount > 0) 5             { 6                 //按下鼠标左键,移动矩形框 7                 if (e.button == 1) 8                 { 9                     //如果指针落在鹰眼的矩形框中,标记可移动10                     if (e.mapX > pEnv.XMin && e.mapY > pEnv.YMin && e.mapX < pEnv.XMax && e.mapY < pEnv.YMax)11                     {12                         bCanDrag = true;13                     }14                     pMoveRectPoint = new PointClass();15                     pMoveRectPoint.PutCoords(e.mapX, e.mapY);//记录点击的第一个点的坐标16                     mainMapControl.AutoKeyboardScrolling = true;17                     mainMapControl.AutoMouseWheel = true;18                 }19                 //按下鼠标右键,绘制矩形框20                 else if (e.button == 2)21                 {22                     IEnvelope pEnvelop = EagleEyeMapControl.TrackRectangle();23                     IPoint pTemPoint = new PointClass();24                     pTemPoint.PutCoords(pEnvelop.XMin + pEnvelop.Width / 2, pEnvelop.YMin + pEnvelop.Height / 2);25                     mainMapControl.Extent = pEnvelop;26                     //矩形框的高度和数据视图的高度不一定成正比,这里做一个中心调整27                     mainMapControl.CenterAt(pTemPoint);28                     mainMapControl.AutoKeyboardScrolling = true;29                     mainMapControl.AutoMouseWheel = true;30                 }31             }32 33         }34         #endregion

8)在鹰眼视图的OnMouseMove 事件中实现矩形框的移动

 1  #region 鹰眼视图的OnMouseMove事件 2         private void EagleEyeMapControl_OnMouseMove(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseMoveEvent e) 3         { 4             if (e.mapX > pEnv.XMin && e.mapY > pEnv.YMin && e.mapX < pEnv.XMax && e.mapY < pEnv.YMax) 5             { 6                 //如果鼠标移动到矩形框中,鼠标编程小手,表示可以移动 7                 EagleEyeMapControl.MousePointer = esriControlsMousePointer.esriPointerHand; 8                 if (e.button == 2)//如果在内部点点击鼠标右键,将鼠标演示设置为默认样式 9                 {10                     EagleEyeMapControl.MousePointer = esriControlsMousePointer.esriPointerDefault;11                     mainMapControl.AutoKeyboardScrolling = true;12                     mainMapControl.AutoMouseWheel = true;13                 }14             }15             else16             {17                 //在其位置将鼠标设为默认样式18                 EagleEyeMapControl.MousePointer = esriControlsMousePointer.esriPointerDefault;19                 mainMapControl.AutoKeyboardScrolling = true;20                 mainMapControl.AutoMouseWheel = true;21             }22             if (bCanDrag)23             {24                 double Dx, Dy;//记录鼠标移动的距离25                 Dx = e.mapX - pMoveRectPoint.X;26                 Dy = e.mapY - pMoveRectPoint.Y;27                 pEnv.Offset(Dx, Dy);//根据偏移量更改pEnv位置28                 pMoveRectPoint.PutCoords(e.mapX, e.mapY);29                 DrawRectangle(pEnv);30                 mainMapControl.Extent = pEnv;31             }32 33         }34         #endregion

9)在鹰眼视图的OnMouseUp事件中判断鼠标是否点击

 1  #region 鹰眼视图的OnMouseUp事件 2         private void EagleEyeMapControl_OnMouseUp(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseUpEvent e) 3         { 4             if (e.button == 1 && pMoveRectPoint != null) 5             { 6                 if (e.mapX == pMoveRectPoint.X && e.mapY == pMoveRectPoint.Y) 7                 { 8                     mainMapControl.CenterAt(pMoveRectPoint); 9                 }10                 bCanDrag = false;11             }12             13         }14         #endregion

综上述,一个鹰眼功能成功的实现

ArcGIS Engine开发之鹰眼视图