ArcGIS Engine:鹰眼图的拓展功能-点击和矩形+坐标状态栏

2023-10-07 01:01

本文主要是介绍ArcGIS Engine:鹰眼图的拓展功能-点击和矩形+坐标状态栏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

01 前言

02 鹰眼图的控制功能

03 显示当前鼠标的地理坐标


01 前言

说是拓展,不过是忘记了实验还有附加实验.这里补上.

前文不再赘述,上一节查看:ArcGIS Engine:视图菜单的创建和鹰眼图的实现_炒茄子的博客-CSDN博客

这里加上三个功能: 

为程序增加鹰眼(缩略图)显示功能,并扩展鹰眼功能

1)增加鹰眼图控制功能:

        在鹰眼图中点击鼠标,跳转主图到鼠标点击位置;

        在鹰眼图中绘制矩形,跳转主图到该矩形范围;

2)增加地图控件操作

        响应鼠标在地图上移动事件,将当前地理坐标显示在状态栏;

02 鹰眼图的控制功能

其实本质上鹰眼图中两个功能:点击鼠标和绘制矩形是捆绑在一块的功能我个人认为.

我们说一说点击鼠标, 然后主视图转到鼠标点击位置,这实际上就是监控鼠标按下时在鹰眼图对应的位置,然后找到主视图上对应位置将其显示在最中心。

而绘制矩形,看起来好像比较难,实际上就是继续监控鼠标松开(按下就是前面的点击鼠标,现在是松开)时在鹰眼图的位置,那么这里绘制矩形就是依据按下和松开两个位置构建一个矩形,然后这个矩形范围作为主视图显示的范围。

那么就需要监控两个事件,第一就是鼠标在鹰眼图按下时;第二就是鼠标在鹰眼图松开时;

但是每一个事件触发时我们应该做什么呢?按正常来想,我们应该是按下的时候(鼠标按下事件触发)完成第一个功能;然后松开的时候(鼠标松开事件触发,同时会利用前面鼠标按下事件触发时那个点位的信息)完成第二个功能。

但是实际上可能会这么:当用户按下鼠标,第一个功能触发,当用户松开鼠标第二个功能触发,所以两个功能会同时触发。所以我将做一些更改:

当鼠标按下,仅仅记录点位信息;

当鼠标松开,记录松开点位信息并判断与前面按下点位信息是否一致,如果一致执行第一个功能,否则执行第二个功能。

具体操作如下:

类似的,对于鼠标松开事件: 

 

两个功能的实现代码:

IPoint down_point;  //  类成员变量
public void EyeMapControl_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
{// 当鼠标在鹰眼图上按下时,触发本事件// 该函数用于将主视图的显示从当前位置平移到鹰眼图中的鼠标点击的位置(平移操作放到了鼠标松开事件函数中, 因为要与鼠标绘制矩形然后主视图平移过去的功能区分)down_point = new PointClass();  // 实例化一个点对象down_point.X = e.mapX;  // 记录当前鼠标的X坐标down_point.Y = e.mapY;  // 记录当前鼠标的Y坐标
}private void EyeMapControl_OnMouseUp(object sender, IMapControlEvents2_OnMouseUpEvent e)
{// 当鼠标在鹰眼图上松开时,触发本事件IPoint up_point = new PointClass();  // 实例化一个点对象up_point.X = e.mapX;up_point.Y = e.mapY;// 如果按下的鼠标为null说明用户在其它位置按下鼠标, 然后在鹰眼图中松开鼠标, 这不应该进行平移, 可能是误触if (down_point == null){return;}if ((down_point.X == up_point.X) && (down_point.Y == up_point.Y)){// 如果按下和松开鼠标点位一致那么说明仅仅是点击MainMapControl.CenterAt(down_point);  // 将中心点移动到click_point点对象所在位置.}else{   // 如果不一致, 说明用户拉框了.我们将IEnvelope env = new EnvelopeClass();  // 实例化一个包络线对象double x_min = Math.Min(down_point.X, up_point.X);double x_max = Math.Max(down_point.X, up_point.X);double y_min = Math.Min(down_point.Y, up_point.Y);double y_max = Math.Max(down_point.Y, up_point.Y);env.PutCoords(x_min, y_min, x_max, y_max);MainMapControl.Extent = env;}MainMapControl.ActiveView.Refresh();  // 刷新down_point = null;  // 将鼠标按下的点位信息清除, 为下次准备
}

03 显示当前鼠标的地理坐标

这里就更简单了,当前鼠标的地理坐标,应该是显示当前鼠标在主视图上所在位置的坐标,所以只需要有一个事件监控鼠标移动就好了。

操作如下:

 

 我始终担心,我的状态栏名是CoordStatusLabel,但是你们的不一定是,你们可以在这里查看自己的状态栏名称:

代码:

// 当鼠标在主视图中移动时, 触发此事件
// 该函数用于在状态栏中显示当前鼠标对应的地理坐标信息
double x = e.mapX;
double y = e.mapY;
string units = MainMapControl.MapUnits.ToString().Substring(4);  // 去掉esri四个字符//CoordStatusLabel.Text = string.Format("X: {0: .4f}; Y: {1: .4f}", x, y);
CoordStatusLabel.Text = string.Format("X: {0:.0000}; Y: {1:.0000}; 单位: {2}", x, y, units);

 所有完整代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;using ESRI.ArcGIS.Controls;  // 使用其中的工具类(例如平移工具Pan等)
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Carto;  //  使用ILayer类
using ESRI.ArcGIS.Display;namespace Ex2Twinborn
{public partial class MainForm : Form{public MainForm(){ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);  // 解决版本不清晰问题InitializeComponent();}private void 放大ToolStripMenuItem_Click(object sender, EventArgs e){// 该函数用于将鼠标状态切换为放大工具ControlsMapZoomInToolClass zoom_in = new ControlsMapZoomInToolClass();  //  实例化一个工具zoom_in.OnCreate(MainMapControl.Object);  // 告诉放大工具,它应该服务于谁,==> MapMainMapControl.CurrentTool = zoom_in;  // 将Map控件的当前使用工具切换为放大}private void 缩小ToolStripMenuItem_Click(object sender, EventArgs e){// 当前函数用于将鼠标状态切换为缩小工具ControlsMapZoomOutToolClass zoom_out = new ControlsMapZoomOutToolClass();zoom_out.OnCreate(MainMapControl.Object);  // 将缩小工具的服务对象进行绑定MainMapControl.CurrentTool = zoom_out;  // 将Map控件的当前使用工具切换为缩小}private void 平移ToolStripMenuItem_Click(object sender, EventArgs e){// 该函数用于将当前鼠标状态切换为平移工具ControlsMapPanToolClass pan = new ControlsMapPanToolClass();  //  如果不能正常运行, 请将引用下关于ESRI的所有引用的属性-嵌入互操作类型更改为false.pan.OnCreate(MainMapControl.Object);  // 告诉pan工具,你是在Map控件上进行工作的MainMapControl.CurrentTool = pan;  // 将Map控件当前的使用工具更改为平移工具}private void 全图ToolStripMenuItem_Click(object sender, EventArgs e){// 该函数用于将当前Map进行全图显示-方法1MainMapControl.Extent = MainMapControl.FullExtent;MainMapControl.Refresh();方法2//ControlsMapFullExtentCommandClass full_extent = new ControlsMapFullExtentCommandClass();//full_extent.OnCreate(MainMapControl.Object);//full_extent.OnClick();}private void MainMapControl_OnMapReplaced(object sender, IMapControlEvents2_OnMapReplacedEvent e){// 当主视图(MainMapControl)的内容被替换了(实际上此处仅仅是针对mxd文档被替换,对于一般数据的加载实际上不会触发此函数), 那么执行该部分函数// 该函数用于将主视图上的所有图层同步加载到鹰眼图中for (int ix=0; ix < MainMapControl.LayerCount; ix++){ILayer layer = MainMapControl.get_Layer(ix);EyeMapControl.AddLayer(layer);}EyeMapControl.Extent = EyeMapControl.FullExtent;  // 全图显示EyeMapControl.Refresh();EyeMapControl.AutoMouseWheel = false;  // 不允许有滚动条}private void MainMapControl_OnExtentUpdated(object sender, IMapControlEvents2_OnExtentUpdatedEvent e){// 当主视图的Extent范围发生变化, 那么触发此事件// 该函数用于更新鹰眼图中的矩形框(矩形框范围为主视图的Extent)IRectangleElement pRectangleElement = new RectangleElement() as IRectangleElement;  // 新建一个矩形框并更换类型IElement pEle = pRectangleElement as IElement;  //  再次更换类型IEnvelope pEnv = e.newEnvelope as IEnvelope;  // 获取主视图的范围边框并更换类型为包络线==> IEnvelopepEle.Geometry = pEnv;  // 设置刚刚创建的矩形边框的几何形状为刚刚主视图的范围的边框.IRgbColor pColor = new RgbColor();  // 实例化一个颜色对象pColor.Red = 200;  // 红色分量为200, 255表示完全红色pColor.Transparency = 255;  // 颜色的透明度, 255表示完全不透明ILineSymbol pLineSymbol = new SimpleLineSymbol();  // 实例化一个线对象pLineSymbol.Width = 2;  // 线的宽度为2pLineSymbol.Color = pColor;  // 线的颜色为刚刚设置的不饱和但完全不透明的红色IFillSymbol pFillSymbol = new SimpleFillSymbol();  // 创建一个填充符号pColor.Transparency = 0;  // 刚刚的颜色透明度修改为0也就是完全透明度pFillSymbol.Color = pColor;  // 填充色设置为刚刚的颜色, 实际上就是透明度的没有任何填充pFillSymbol.Outline = pLineSymbol;  // 但是填充符号的外边框(它是线)设置为刚刚的线对象IFillShapeElement pFillShapeElement = pRectangleElement as IFillShapeElement;pFillShapeElement.Symbol = pFillSymbol;IGraphicsContainer pGC = EyeMapControl.Map as IGraphicsContainer;  // 创建一个pGC.DeleteAllElements();  // 清除之前所有的图形\注记等等避免与后面新的图形发生冲突或者重叠.pGC.AddElement(pEle, 0);  // 添加矩形框在最底层IActiveView pActiveView = EyeMapControl.Map as IActiveView;pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);// 刷新的图层是图形层(不包括加载的数据等)、刷新的对象(null表示图形层的所有对象)、刷新的空间范围(null表示整个鹰眼图范围)}private void MainMapControl_OnMapReplaced_1(object sender, IMapControlEvents2_OnMapReplacedEvent e){// 当主视图(MainMapControl)的内容被替换了(实际上此处仅仅是针对mxd文档被替换,对于一般数据的加载实际上不会触发此函数), 那么执行该部分函数// 该函数用于将主视图上的所有图层同步加载到鹰眼图中for (int ix = 0; ix < MainMapControl.LayerCount; ix++){ILayer layer = MainMapControl.get_Layer(ix);EyeMapControl.AddLayer(layer);}EyeMapControl.Extent = EyeMapControl.FullExtent;  // 全图显示EyeMapControl.Refresh();EyeMapControl.AutoMouseWheel = false;  // 不允许有滚动条}IPoint down_point;  //  类成员变量public void EyeMapControl_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e){// 当鼠标在鹰眼图上按下时,触发本事件// 该函数用于将主视图的显示从当前位置平移到鹰眼图中的鼠标点击的位置(平移操作放到了鼠标松开事件函数中, 因为要与鼠标绘制矩形然后主视图平移过去的功能区分)down_point = new PointClass();  // 实例化一个点对象down_point.X = e.mapX;  // 记录当前鼠标的X坐标down_point.Y = e.mapY;  // 记录当前鼠标的Y坐标}private void EyeMapControl_OnMouseUp(object sender, IMapControlEvents2_OnMouseUpEvent e){// 当鼠标在鹰眼图上松开时,触发本事件IPoint up_point = new PointClass();  // 实例化一个点对象up_point.X = e.mapX;up_point.Y = e.mapY;// 如果按下的鼠标为null说明用户在其它位置按下鼠标, 然后在鹰眼图中松开鼠标, 这不应该进行平移, 可能是误触if (down_point == null){return;}if ((down_point.X == up_point.X) && (down_point.Y == up_point.Y)){// 如果按下和松开鼠标点位一致那么说明仅仅是点击MainMapControl.CenterAt(down_point);  // 将中心点移动到click_point点对象所在位置.}else{   // 如果不一致, 说明用户拉框了.我们将IEnvelope env = new EnvelopeClass();  // 实例化一个包络线对象double x_min = Math.Min(down_point.X, up_point.X);double x_max = Math.Max(down_point.X, up_point.X);double y_min = Math.Min(down_point.Y, up_point.Y);double y_max = Math.Max(down_point.Y, up_point.Y);env.PutCoords(x_min, y_min, x_max, y_max);MainMapControl.Extent = env;}MainMapControl.ActiveView.Refresh();  // 刷新down_point = null;  // 将鼠标按下的点位信息清除, 为下次准备}private void MainMapControl_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e){// 当鼠标在主视图中移动时, 触发此事件// 该函数用于在状态栏中显示当前鼠标对应的地理坐标信息double x = e.mapX;double y = e.mapY;string units = MainMapControl.MapUnits.ToString().Substring(4);  // 去掉esri四个字符//CoordStatusLabel.Text = string.Format("X: {0: .4f}; Y: {1: .4f}", x, y);CoordStatusLabel.Text = string.Format("X: {0:.0000}; Y: {1:.0000}; 单位: {2}", x, y, units);}}
}

最终效果:

 

 

这篇关于ArcGIS Engine:鹰眼图的拓展功能-点击和矩形+坐标状态栏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/155099

相关文章

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF

JavaFX应用更新检测功能(在线自动更新方案)

JavaFX开发的桌面应用属于C端,一般来说需要版本检测和自动更新功能,这里记录一下一种版本检测和自动更新的方法。 1. 整体方案 JavaFX.应用版本检测、自动更新主要涉及一下步骤: 读取本地应用版本拉取远程版本并比较两个版本如果需要升级,那么拉取更新历史弹出升级控制窗口用户选择升级时,拉取升级包解压,重启应用用户选择忽略时,本地版本标志为忽略版本用户选择取消时,隐藏升级控制窗口 2.

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

Spring+MyBatis+jeasyui 功能树列表

java代码@EnablePaging@RequestMapping(value = "/queryFunctionList.html")@ResponseBodypublic Map<String, Object> queryFunctionList() {String parentId = "";List<FunctionDisplay> tables = query(parent

PostgreSQL核心功能特性与使用领域及场景分析

PostgreSQL有什么优点? 开源和免费 PostgreSQL是一个开源的数据库管理系统,可以免费使用和修改。这降低了企业的成本,并为开发者提供了一个活跃的社区和丰富的资源。 高度兼容 PostgreSQL支持多种操作系统(如Linux、Windows、macOS等)和编程语言(如C、C++、Java、Python、Ruby等),并提供了多种接口(如JDBC、ODBC、ADO.NET等

寻迹模块TCRT5000的应用原理和功能实现(基于STM32)

目录 概述 1 认识TCRT5000 1.1 模块介绍 1.2 电气特性 2 系统应用 2.1 系统架构 2.2 STM32Cube创建工程 3 功能实现 3.1 代码实现 3.2 源代码文件 4 功能测试 4.1 检测黑线状态 4.2 未检测黑线状态 概述 本文主要介绍TCRT5000模块的使用原理,包括该模块的硬件实现方式,电路实现原理,还使用STM32类