• 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                 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

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

  • 相关阅读:
    连接服务器时通时不通的问题
    二进制包搭建k8s集群
    2、带着问题学习JVM_对象存活_垃圾回收的内容_理论_收集算法
    四、redis事务_真正实现分布式Lua_分布式锁
    四、Spring 框架中接入单机Redis的两种方式
    3、通过zkCli⼯具命令和zk 的java API两种方式创建⼀个主从模式示列
    1、带着问题学习JVM_Java为什么属于编译型+解释型的高级语言_Class类文件结构理解
    2、zookeeper安装、常用命令、API说明及简单示列(创建ZK会话及对节点进行操作、创建分布式锁、创建全局唯一ID)
    1、zk的产生、优劣、基础知识
    十三、Spring容器的原理及源码分析
  • 原文地址:https://www.cnblogs.com/dongteng/p/5908208.html
Copyright © 2020-2023  润新知