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);}}
}

最终效果:

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/150065.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

elementui修改message消息提示颜色

/* el弹出框样式 */ .el-message {top: 80px !important;border: 0; }.el-message * {color: var(--white) !important;font-weight: 600; }.el-message--success {background: var(--themeBackground); }.el-message--warning {background: var(--gradientBG); }.el-message--…

最强中间件!Kafka快速入门(Kafka理论+SpringBoot集成Kafka实践)

自媒体文章上下架 需求分析 媒体端下架文章同时app端也下架文章的实现可以通过feign去调用&#xff0c;但这种实现耦合度太高&#xff0c;这里使用MQ进行解耦 自媒体端一旦上下架文章就发送消息给MQ&#xff0c;文章微服务在去读取消息根据消息内容上下架文章 MQ还可以流量削…

【16】c++设计模式——>建造者(生成器)模式

什么是建造者模式? 建造者模式&#xff08;Builder Pattern&#xff09;是一种创建型设计模式&#xff0c;它允许你构造复杂对象步骤分解。你可以不同的步骤中使用不同的方式创建对象&#xff0c;且对象的创建与表示是分离的。这样&#xff0c;同样的构建过程可以创建不同的表…

黑马mysql教程笔记(mysql8教程)基础篇——数据库相关概念、mysql安装及卸载、数据模型、SQL通用语法及分类(DDL、DML、DQL、DCL)

参考文章1&#xff1a;https://www.bilibili.com/video/BV1Kr4y1i7ru/ 参考文章2&#xff1a;https://dhc.pythonanywhere.com/article/public/1/ 文章目录 基础篇数据库相关概念&#xff08;数据库DataBase&#xff08;DB&#xff09;、数据库管理系统DataBase Management Sy…

数据分析视角中的商业分析学习笔记

数据分析一大堆&#xff0c;结果却是大家早就知道的结论&#xff1f;是工具和方法出问题了吗&#xff1f;真正原因可能是你的思维有误区。 为什么分析的这么辛苦&#xff0c;得出的结论大家早知道&#xff0c;谁谁都不满意&#xff1f;核心原因有3个&#xff1a; 分析之前&am…

UGUI交互组件Toggle

一.Toggle对象的构造 Toggle和Button类似&#xff0c;是交互组件的一种 如果所示&#xff0c;通过菜单创建了两个Toggle&#xff0c;Toggle2中更换了背景和标记资源 对象说明Toggle含有Toggle组件的对象Background开关背景Checkmark开关选中标记Label名称文本 二.Toggle组件属…

总结三:计算机网络面经

文章目录 1、简述静态路由和动态路由&#xff1f;2、说说有哪些路由协议&#xff0c;都是如何更新的&#xff1f;3、简述域名解析过程&#xff0c;本机如何干预域名解析&#xff1f;4、简述 DNS 查询服务器的基本流程是什么&#xff1f;DNS 劫持是什么&#xff1f;5、简述网关的…

Apollo Planning2.0决策规划算法代码详细解析 (2): vscode gdb单步调试环境搭建

前言: apollo planning2.0 在新版本中在降低学习和二次开发成本上进行了一些重要的优化,重要的优化有接口优化、task插件化、配置参数改造等。 GNU symbolic debugger,简称「GDB 调试器」,是 Linux 平台下最常用的一款程序调试器。GDB 编译器通常以 gdb 命令的形式在终端…

VUE3照本宣科——package.json与vite.config.js

VUE3照本宣科——package.json与vite.config.js VUE3照本宣科系列导航 前言一、package.json1.name2.version3.private4.scripts5.dependencies6.devDependencies 二、vite.config.js1.plugins2.resolve.alias3.base4.mode 三、VUE3照本宣科系列总结 VUE3照本宣科系列导航 1.VU…

ZRTP交叉编译与移植

1 ZRTP源码下载 这里采用的是libzrtp来自于freeswitch&#xff1a;libs/libzrtp。 2 ZRTP交叉编译 zrtp编译比较简单&#xff0c;采用configure进行编译在根目录心中zrtp编译脚本&#xff0c;只需要指定交叉编译工具链和安装地址即可。脚本如下所示&#xff1a; unset CC C…

三一充填泵:煤矿矸石无害化充填,煤炭绿色高效开采的破局利器

富煤贫油少气是我国的能源禀赋特征&#xff0c;决定了我国以煤炭为主的能源结构&#xff0c;煤炭为国民经济发展提供了重要的基础。煤炭开采过程会对土地、地下水、空气等环境造成较大的污染&#xff0c;但大宗固废煤矸石无害化充填的技术手段可以有效改善这样的情况&#xff0…

《视觉 SLAM 十四讲》V2 第 6 讲 非线性优化 【高斯牛顿法、列文伯格-马夸尔特方法 、Ceres 库 和 g2o库 】

文章目录 6.1.2 最小二乘 寻找下降增量 Δ x k \Delta\bm{x}_k Δxk​的 4 种方法6.2.1 一阶和二阶梯度法(最速下降法、牛顿法)6.2.2 高斯牛顿法6.2.3 列文伯格-马夸尔特方法 【阻尼牛顿法】【信赖区域法】 6.3 实践6.3.1 手写高斯牛顿法 【Code】6.3.2 谷歌的优化库 Ceres 【最…

计算机专业毕业设计项目推荐12-志愿者管理系统(Spring+Js+Mysql)

志愿者管理系统&#xff08;SpringJsMysql&#xff09; **介绍****各部分模块实现** 介绍 本系列(后期可能博主会统一为专栏)博文献给即将毕业的计算机专业同学们,因为博主自身本科和硕士也是科班出生,所以也比较了解计算机专业的毕业设计流程以及模式&#xff0c;在编写的过程…

【进阶C语言】排序函数(qsort)与模拟实现(回调函数的实例)

本章大致内容目录&#xff1a; 1.认识回调函数 2.排序函数qsort 3.模拟实现qsort 回调函数为C语言重要知识点&#xff0c;以函数指针为主要知识&#xff1b;下面介绍回调函数的定义、回调函数的库函数举例即库函数模拟实现。 一、回调函数 1.回调函数定义 回调函数就是一…

ZRTP协议与原理

1 ZRTP简介 ZRTP&#xff0c;全名Z Real-time Transport Protocol&#xff0c;是一种网络协议&#xff0c;旨在为实时通信提供安全性。与其它安全协议&#xff08;如TLS和IPsec&#xff09;不同&#xff0c;ZRTP专门为实时通信设计&#xff0c;包括音频和视频通话。它是由Phil…

基于FastAPI的文件上传和下载

基于FastAPI的文件上传和下载 一、前言 为了实现ASR的可视化界面&#xff0c;在各个博客中寻觅了一波找找文件上传和下载的例子&#xff0c;没有找到能完整实现这个功能的&#xff0c;有也只是有一部分&#xff08;菜菜求捞捞&#xff09;&#xff0c;看了甚是烦恼&#xff0…

数据结构刷题训练——二叉树篇(一)

&#x1f4d9;作者简介&#xff1a; 清水加冰&#xff0c;目前大二在读&#xff0c;正在学习C/C、Python、操作系统、数据库等。 &#x1f4d8;相关专栏&#xff1a;C语言初阶、C语言进阶、C语言刷题训练营、数据结构刷题训练营、有感兴趣的可以看一看。 欢迎点赞 &#x1f44d…

SaaS 电商设计 (二) 全链路解决方案概述和核心业务流程梳理

一.业务目标&技术目标 业务目标:完成多业态,多渠道的数字化运营 自有业务: O2O,B2C,B2B2C,S2B2b 平台业务:POPB2c,POPB2b,POPS2B2b 1.1 自有业务 O2O:全称Online to Offline.泛指的线上线下的业务融合.这种的情况分为两种情况,第一种通过线上的数字化运营引导线上用户线下…

AutoGen - 多个Agent开发LLM应用的框架

文章目录 关于安装使用关于 Enable Next-Gen Large Language Model Applications 用多个Agent开发LLM应用的框架,这些agent可相互交流以解决任务。 官网:https://microsoft.github.io/autogen/github : http://github.com/microsoft/autogendiscord : https://discord.com/i…

Flink的处理函数——processFunction

目录 一、处理函数概述 二、Process函数分类——8个 &#xff08;1&#xff09;ProcessFunction &#xff08;2&#xff09;KeyedProcessFunction &#xff08;3&#xff09;ProcessWindowFunction &#xff08;4&#xff09;ProcessAllWindowFunction &#xff…