鹰眼是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 else 31 { 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 else 16 { 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
综上述,一个鹰眼功能成功的实现