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

鹰眼一般具有的功能:

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

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

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

具体的开发过程:

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

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

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

  #region 同步鹰眼视图的方法封装
private void SynchronizeEagleEye()
{
if (EagleEyeMapControl.LayerCount > )
{
EagleEyeMapControl.ClearLayers();
}
//设置鹰眼和MainMapcontrol中地图的坐标系统一致
EagleEyeMapControl.SpatialReference = mainMapControl.SpatialReference;
for (int i = mainMapControl.LayerCount - ; i >= ; i--)
{
//是鹰眼视图与数据视图的图层上下顺序保持一致
ILayer pLayer = mainMapControl.get_Layer(i);
if (pLayer is IGroupLayer || pLayer is ICompositeLayer)
{
ICompositeLayer pCompositeLayer = (ICompositeLayer)pLayer;
for (int j = pCompositeLayer.Count - ; j >= ; j--)
{
ILayer pSubLayer = pCompositeLayer.get_Layer(i);
IFeatureLayer pFeatureLayer = pSubLayer as IFeatureLayer;
if (pFeatureLayer != null)
{
if (pFeatureLayer.FeatureClass.ShapeType != esriGeometryType.esriGeometryPoint && pFeatureLayer.FeatureClass.ShapeType != esriGeometryType.esriGeometryMultipoint)
{
EagleEyeMapControl.AddLayer(pLayer);
}
}
}
}
else
{
IFeatureLayer pFeatureLayer = pLayer as IFeatureLayer;
if (pFeatureLayer != null)
{
if (pFeatureLayer.FeatureClass.ShapeType != esriGeometryType.esriGeometryPoint && pFeatureLayer.FeatureClass.ShapeType != esriGeometryType.esriGeometryMultipoint)
{
EagleEyeMapControl.AddLayer(pLayer);
}
}
//设置鹰眼地图的全图显示
EagleEyeMapControl.Extent = mainMapControl.FullExtent;
pEnv = mainMapControl.Extent as IEnvelope;
DrawRectangle(pEnv);
EagleEyeMapControl.ActiveView.Refresh();
}
}
}
#endregion

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

  #region 获取RGB颜色
private IRgbColor GetRgbColor(int intR, int intG, int intB)
{
IRgbColor pRgbColor = null;
if (intR < || intR > || intG < || intG > || intB < || intB > )
{
return pRgbColor;
}
pRgbColor = new RgbColorClass();
pRgbColor.Red = intR;
pRgbColor.Green = intG;
pRgbColor.Blue = intB;
return pRgbColor;
}
#endregion

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

  #region 鹰眼中矩形框绘制的方法封装
private void DrawRectangle(IEnvelope pEnvelop)
{
//在绘制前,清除鹰眼中之前绘制的矩形框
IGraphicsContainer pGraphicsContainer = EagleEyeMapControl.Map as IGraphicsContainer;
IActiveView pActiveView = pGraphicsContainer as IActiveView;
pGraphicsContainer.DeleteAllElements();
//得到当前视图范围
IRectangleElement pRectangleElement = new RectangleElementClass();
IElement pElement = pRectangleElement as IElement;
pElement.Geometry = pEnvelop;
//设置矩形框(实质为中间透明度面)
IRgbColor pColor = new RgbColorClass();
pColor = GetRgbColor(, , );
pColor.Transparency = ;
ILineSymbol pOutLine = new SimpleLineSymbolClass();
pOutLine.Width = ;
pOutLine.Color = pColor; IFillSymbol pFillSymbol = new SimpleFillSymbolClass();
pColor = new RgbColorClass();
pColor.Transparency = ;
pFillSymbol.Color = pColor;
pFillSymbol.Outline = pOutLine;
//向鹰眼中添加矩形框
IFillShapeElement pFillShapeElement = pElement as IFillShapeElement;
pFillShapeElement.Symbol = pFillSymbol;
pGraphicsContainer.AddElement((IElement)pFillShapeElement, );
//刷新
pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
}
#endregion

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

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

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

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

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

代码:

   #region 鹰眼视图的OnMouseDown事件
private void EagleEyeMapControl_OnMouseDown(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseDownEvent e)
{
if (EagleEyeMapControl.Map.LayerCount > )
{
//按下鼠标左键,移动矩形框
if (e.button == )
{
//如果指针落在鹰眼的矩形框中,标记可移动
if (e.mapX > pEnv.XMin && e.mapY > pEnv.YMin && e.mapX < pEnv.XMax && e.mapY < pEnv.YMax)
{
bCanDrag = true;
}
pMoveRectPoint = new PointClass();
pMoveRectPoint.PutCoords(e.mapX, e.mapY);//记录点击的第一个点的坐标
mainMapControl.AutoKeyboardScrolling = true;
mainMapControl.AutoMouseWheel = true;
}
//按下鼠标右键,绘制矩形框
else if (e.button == )
{
IEnvelope pEnvelop = EagleEyeMapControl.TrackRectangle();
IPoint pTemPoint = new PointClass();
pTemPoint.PutCoords(pEnvelop.XMin + pEnvelop.Width / , pEnvelop.YMin + pEnvelop.Height / );
mainMapControl.Extent = pEnvelop;
//矩形框的高度和数据视图的高度不一定成正比,这里做一个中心调整
mainMapControl.CenterAt(pTemPoint);
mainMapControl.AutoKeyboardScrolling = true;
mainMapControl.AutoMouseWheel = true;
}
} }
#endregion

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

  #region 鹰眼视图的OnMouseMove事件
private void EagleEyeMapControl_OnMouseMove(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseMoveEvent e)
{
if (e.mapX > pEnv.XMin && e.mapY > pEnv.YMin && e.mapX < pEnv.XMax && e.mapY < pEnv.YMax)
{
//如果鼠标移动到矩形框中,鼠标编程小手,表示可以移动
EagleEyeMapControl.MousePointer = esriControlsMousePointer.esriPointerHand;
if (e.button == )//如果在内部点点击鼠标右键,将鼠标演示设置为默认样式
{
EagleEyeMapControl.MousePointer = esriControlsMousePointer.esriPointerDefault;
mainMapControl.AutoKeyboardScrolling = true;
mainMapControl.AutoMouseWheel = true;
}
}
else
{
//在其位置将鼠标设为默认样式
EagleEyeMapControl.MousePointer = esriControlsMousePointer.esriPointerDefault;
mainMapControl.AutoKeyboardScrolling = true;
mainMapControl.AutoMouseWheel = true;
}
if (bCanDrag)
{
double Dx, Dy;//记录鼠标移动的距离
Dx = e.mapX - pMoveRectPoint.X;
Dy = e.mapY - pMoveRectPoint.Y;
pEnv.Offset(Dx, Dy);//根据偏移量更改pEnv位置
pMoveRectPoint.PutCoords(e.mapX, e.mapY);
DrawRectangle(pEnv);
mainMapControl.Extent = pEnv;
} }
#endregion

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

  #region 鹰眼视图的OnMouseUp事件
private void EagleEyeMapControl_OnMouseUp(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseUpEvent e)
{
if (e.button == && pMoveRectPoint != null)
{
if (e.mapX == pMoveRectPoint.X && e.mapY == pMoveRectPoint.Y)
{
mainMapControl.CenterAt(pMoveRectPoint);
}
bCanDrag = false;
} }
#endregion

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

ArcGIS Engine开发之鹰眼视图的更多相关文章

  1. ArcGIS Engine开发鹰眼图的功能(代码优化篇)

    在上一篇,ArcGIS Engine开发鹰眼图的功能(基础篇) 上一篇的实现效果图如下, 如果仔细观察,会发现一个问题,即在“鹰眼”的区域,只要在红色线框内的注记会被覆盖. 如果红色框包括整张图的话, ...

  2. ArcGIS Engine开发鹰眼图的功能(基础篇)

    鹰眼是用于调节全视域范围内主地图显示范围情况的副地图.它体现了地图整体与详细局部的关系. 用户可以通过鼠标单击或者画框等动作实现鹰眼与主地图的交互情况. 鹰眼功能的原理是通过主地图窗口的地图控件和鹰眼 ...

  3. ArcGIS Engine开发之地图基本操作(4)

    ArcGIS Engine开发中数据库的加载 1.加载个人地理数据库数据 个人地理数据库(Personal Geodatabase)使用Miscrosoft Access文件(*.mdb)进行空间数据 ...

  4. ArcGIS Engine开发前基础知识(2)

    ArcGIS基本控件简介 ArcGIS Engine控件是一组可视化的开发组件,每个ArcGIS Engine控件都是一个COM组件.这些组件包括MapControl,PageLayoutContro ...

  5. C#,ArcGIS Engine开发入门教程

    C#,ArcGIS Engine开发入门教程 转自:http://blog.csdn.net/yanleigis/article/details/2233674  目录(?)[+] 五实现 一 加载A ...

  6. ArcGIS Engine开发基础总结(一)

    标准Engine功能 地图浏览    地图制作 数据查询 数据分析 及 所有的开发控件 —MapControl, PageLayout, Toolbar, TOC, ArcReader 对所有矢量和栅 ...

  7. ArcGIS Engine开发前基础知识(3)

    对象模型图 一.对象模型图中的类与接口 ArcGIS Engine 提供大量的对象,这些对象之间存在各种各样的关系,如继承.组合.关联等.对象模型图(Object model diagram,ODM) ...

  8. ArcGIS Engine开发的ArcGIS 版本管理的功能

    原文:ArcGIS Engine开发的ArcGIS 版本管理的功能 转自:http://blog.csdn.net/linghe301/article/details/7965901 这是以前的Arc ...

  9. arcgis engine 开发教程系列

    版权声明:        <ArcGIS Engine+C#实例开发教程>为3SDN(http://www.3sdn.net)原创教程,版权所有.禁止商业用途转载(如需请联系作者),非商业 ...

随机推荐

  1. JavaScript

    2015-08-01 16:20 JavaScript使用时需要注意的地方 1.引入JS的位置:最好的做法是把<script>的标签放到HTML文档的最后.</body>标签之 ...

  2. 学习笔记:发现一个IE版本判断的好方法

    web开发就不得不面对浏览器兼容性问题,特别是IE的兼容问题.在前端代码中经常要处理一些兼容格式,为了解决这个问题网上找了找识别浏览器版本的方法.   常规js方法 找到一个方法,还不错,可以识别出各 ...

  3. CYQ.Data V5 分布式自动化缓存设计介绍

    前方: 其实完成这个功能之前,我就在思考:是先把想法写了来,和大伙讨论讨论后再实现,还是实现后再写文论述自己的思维. 忽然脑后传来一个声音说:你发文后会进入发呆阶段. 所以还是静下心,让我轻轻地把代码 ...

  4. Lesson 16 A polite request

    Text If you park your car in the wrong place, a traffic policeman will soon find it. You will be ver ...

  5. Go语言实战 - 使用SendCloud群发邮件

    山坡网需要能够每周给注册用户发送一封名为"本周最热书籍"的邮件,而之前一直使用的腾讯企业邮箱罢工了,提示说发送请求太多太密集. 一番寻找之后发现了大家口碑不错的搜狐SendClou ...

  6. Entity Framework 6 Recipes 2nd Edition(9-3)译->找出Web API中发生了什么变化

    9-3. 找出Web API中发生了什么变化 问题 想通过基于REST的Web API服务对数据库进行插入,删除和修改对象图,而不必为每个实体类编写单独的更新方法. 此外, 用EF6的Code Fri ...

  7. C++11 shared_ptr 智能指针 的使用,避免内存泄露

    多线程程序经常会遇到在某个线程A创建了一个对象,这个对象需要在线程B使用, 在没有shared_ptr时,因为线程A,B结束时间不确定,即在A或B线程先释放这个对象都有可能造成另一个线程崩溃, 所以为 ...

  8. JavaScript高级编程 (1) - javscript是什么

    <重温javascript>这是一系列 javascript 的学习笔记,部分内容摘自书本或者网络,我这里只是基于自己的理解进行了梳理整理. 一个完整的 javscript 实现是由以下3 ...

  9. 从零开始编写自己的C#框架(20)——框架异常处理及日志记录

    最近很忙,杂事也多,所以开发本框架也是断断续续的,终于在前两天将前面设定的功能都基本完成了,剩下一些小功能遗漏的以后发现再补上.接下来的章节主要都是讲解在本框架的基础上进行开发的小巧. 本框架主要有四 ...

  10. clipChildren和clipToPadding

    clipChildren 和 clipToPadding clipChild 用于定义子控件是否在父控件边界内进行绘制.clipChild 默认为 true.也就是不允许进行扩展绘制. clipToP ...