ArcGIS Engine:视图菜单的创建和鹰眼图的实现

目录

01 创建项目

1.1 通过ArcGIS-ExtendingArcObjects创建窗体应用

1.2 通过C#-Windows窗体应用创建窗体应用

1.2.1 创建基础项目

1.2.2 搭建界面

02 创建视图菜单

03 鹰眼图的实现

3.1 OnMapReplaced事件的触发

 3.2 OnExtentUpdated事件的触发

 04 稍作演示


01 创建项目

1.1 通过ArcGIS-ExtendingArcObjects创建窗体应用

可能会存在你的模板中没有ArcGIS-ExtendingArcObjects这个选项,这可能与VS版本有关,一般通过更改注册表使用高于12版本的VS可能会出现该情况。

但是其实模块吗,就是先给你在最基础的C#-窗体应用(.NET框架)的基础上加上一些简单的ArcGIS模块进去。这种只是会更方便罢了。所以后面我为了照顾一部分同学,我从头开始撸,当然节约时间,不会和上述模板一样的功能,只是大致相同而已。

(因为实验就是基于这个模板来进行的,所以我们不管是通过该模板还是自己手撸,后面的实验都是一致的,只是最前面的创建项目这里一个是通过模板,一个是创建基础窗体应用然后自己添加和模板一模一样的功能。)

 

我们看看运行之后的软件界面:

好了,我们开始从头撸出这一部分内容来,看看我的技术如何?毕竟只学了两三天.

1.2 通过C#-Windows窗体应用创建窗体应用

1.2.1 创建基础项目

1.2.2 搭建界面

这里的界面仅仅是可以用来看,但是还没有往里面放代码也就是编写交互的事件。例如我点击之后会发生什么之类的这类东西。

 我们回来看看人家的界面长什么样子:

好了,我们开始搭建菜单栏 

这里就是敲键盘,没有什么难点,至于分割线如下设置:
 

好了,我们开始搭建ToolBar、TOC、Map三个控件。

 我们开始调整一下布局:

 

但是好像人家的工具栏(ToolBar)好像还有一些工具,我们的没有,所以我们还需要加入一些工具(这很简单),操作如下:

 

将你需要的工具全部添加进去,我就暂时加入这些进去了:

其他的控件也不需要添加任何东西,但是这里有一个很大的问题,就是我们现在加入了三个比较关键的ArcGIS控件(TOC、ToolBar、Map),但是我们现在还没有将几个控件进行关联。So,为什么要关联或者说是绑定?因为我们的代码一定意义上是从头开始写的,所以每一个控件都是互不关联的,例如你的ToolBar控件中的工具,正常人都知道这个工具应该是需要在MapControl控件中进行使用(或多或i少),例如TOC控件中展示的图层信息应该是在MapControl控件中显示的那些文件,再例如你使用ToolBar控件中的工具进行数据的加载那么加载好的数据是不是应该显示在MapControl中呢,所以这又是联系。所以各个控件之间是存在关联的,所以我们需要进行绑定让他们知道他们实际上是存在关联的,否则你仅仅只可以显示他们,如下:

如果你绑定了那么可能如下(部分工具为灰色应该是你没有加载文件或者没有进行一定的操作所以呈现灰色):

好了,我们开始说明如何进行绑定:

还差一步你可以运行一个尚且不完整的软件了,那就是明确当前应用程序的ArcGIS版本,这确保正确的ArcGIS Runtime版本被绑定到应用程序。这是在使用ArcGIS Engine或ArcGIS Desktop二次开发的.NET应用程序中经常需要的一步。这个绑定通常确保了当你的应用程序运行时,它能够找到并使用正确版本的ArcGIS组件。这对于避免与多个版本的ArcGIS运行时的冲突特别重要。

总之就是如果你是从头开始写这个应用,使用到了ArcGIS组件,一般都需要这么一行代码:

否则运行时会报错如下:

未处理System.InvalidOperationException:

ArcGIS version not specified. You must call RuntimeManager.Bind before creating any ArcGIS components.

 如何添加代码解决ArGIS版本不清晰问题?

 该行代码:

ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);  // 解决版本不清晰问题

 现在可以运行了:

下面是界面,工具都是可以使用的了。(忘记一件事情了,需要将许可控件(LicenseControl控件)放进来,不然用不了)

 至于菜单栏的功能我们看情况吧,现在时间有限,如果后续实验我们会用到我再继续添加。

02 创建视图菜单

之前的那个文件菜单也放一放了,我们的实验是创建视图菜单,包括放大、缩小、平移、全图显示四个功能。

首先还是先搭建界面:

然后双击<放大>功能,进入该功能的具体事件编写,而不是仅仅是一层皮:

需要注意,代码不可以直接进行粘贴,因为我已经更改了各个控件的名称(为了我更好理解也是见名知意,所以代码中使用各个控件时控件的类名是与大家有所不同,例如大家的Map控件是axMapcontrol1,而我的是MainMapcontrol),名称更改=>控件-属性-Name进行更改。

 关于放大功能的代码如下:

private void 放大ToolStripMenuItem_Click(object sender, EventArgs e)
{// 该函数用于将鼠标状态切换为放大工具ControlsMapZoomInToolClass zoom_in = new ControlsMapZoomInToolClass();  //  实例化一个工具zoom_in.OnCreate(MainMapControl.Object);  // 告诉放大工具,它应该服务于谁,==> MapMainMapControl.CurrentTool = zoom_in;  // 将Map控件的当前使用工具切换为放大
}

但是不可以直接进行粘贴,可能会出错.你需要双击你自己的放大那个设计器位置进去它给你的函数内进行编写,因为可能我的函数名称和你的不一致,就算一致也可能存在问题.

其他的几个功能类似,我就不再一一说明(注释也写得比较详细),四个功能四个函数,每个函数都是调用的ArcGIS的接口.当然,因为我们使用的这几个Controls相关的类,所以确保你已经引入了相关的库:

using ESRI.ArcGIS.Controls;  // 使用其中的工具类(例如平移工具Pan等)

这一部分的完整代码如下:

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

实际上我觉得这部分实验实际上都显得有点多余,我们自己写的菜单栏中的视图部分的四个工具,和ArcGIS Toolbar控件的放大缩小平移等实际上没有任何区别(不做每次实验都是一些综合性的小项目而不是仅仅在这种地方搞一些鸡毛蒜皮的东西实属脱裤子放屁),我只能说暂且是练练手吧,聊胜于无.双非从是如此。

03 鹰眼图的实现

还是有一些难度的,而且因为本身实验的缺陷,我也没有时间和精力去修复其中的一些小问题了。

我认为鹰眼图(实际上也是一个MapControl控件<可以不止一个>)的实现分为两个部分,第一部分就是当我们往主视图中添加数据时,我们顺便也往鹰眼图中添加相同的数据,实际上就是让两个MapControl控件的数据保持一致。(但是实验只完成了仅仅mxd地图文档的添加才会有同步效果,这个我们后面再说);第二就是当我们移动主视图或者放大缩小主视图时,鹰眼图显示主视图在全局的位置(通过小红框显示相对位置)。

3.1 OnMapReplaced事件的触发

所以我们分为两个事件,第一个就是当添加或者修改了数据(这里的数据实际上仅仅时MXD文档)后,事件触发,我们将主视图中的数据同步到鹰眼图中。本身很简单,就是触发在什么时候比较难,实验是直接当MXD文档发生变化(更换或者添加啥的),那么鹰眼图数据显示发生变化。通过OnMapReplaced.

所以总的来说,什么时候会触发OnMapReplaced事件呢?

  1. 加载MXD文档:当你使用AxMapControlLoadMxFile方法加载一个新的MXD(Map Exchange Document,ArcMap的地图文档格式)时,当前的Map对象会被新的MXD中的Map对象替换,因此触发该事件。

  2. 设置Map属性:如果你直接设置AxMapControlMap属性为一个新的Map对象,那么此事件也会被触发。

  3. 添加/移除数据帧:如果你在ArcMap中有多个数据帧,并使用ArcObjects代码或ArcMap界面添加或删除数据帧,OnMapReplaced事件也可能被触发。

  4. 新建地图:如果你在ArcMap中创建一个全新的地图,这也会触发OnMapReplaced事件。

等等

好了,我们现在正式开始操作。

当主视图的数据发生变化,事件触发,所以:

代码如下:

// 当主视图(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;  // 不允许有滚动条

 思路很简单,找到主视图中总共的图层数目MainMapControl.LayerCount,然后循环将每一个图层找到MainMapControl.get_layer(索引<从0开始>),然后将找到的图层添加到鹰眼图.循环结束后,全图显示,然后刷新一下;然后不允许有滚动条.

注意添加对应的引用:

using ESRI.ArcGIS.Carto;  //  使用ILayer类

 3.2 OnExtentUpdated事件的触发

我们前面已经说了,有两个部分,前面那个关于如果主视图的数据发生变化需要同步在鹰眼图上已经解决了,但是对于主视图中如果我们进行平移、放大、缩小等操作,如何将当前主视图的范围以小红框的方式在鹰眼图中显示以标注我们当前浏览的相对位置呢?

这里我们其实已经明白了,无论你进行平移、放大还是其他,本质上都是当前视图显示范围的变化,所以我们仅仅只需要监测到当前主视图的范围一旦发生变化,小红框立即进行重绘显示新的新的位置。所以这就需要通过OnExtentUpdated事件了。

具体操作如下:

 代码:

// 当主视图的Extent范围发生变化, 那么触发此事件
// 该函数用于更新鹰眼图中的矩形框(矩形框范围为主视图的Extent)
IRectangleElement pRectangleElement = new RectangleElement() as IRectangleElement;  // 新建一个矩形框并更换类型
IElement pEle = pRectangleElement as IElement;  //  再次更换类型
IEnvelope pEnv = e.newEnvelope as IEnvelope;  // 获取主视图的范围边框并更换类型为包络线==> IEnvelope
pEle.Geometry = pEnv;  // 设置刚刚创建的矩形边框的几何形状为刚刚主视图的范围的边框.IRgbColor pColor = new RgbColor();  // 实例化一个颜色对象
pColor.Red = 200;  // 红色分量为200, 255表示完全红色
pColor.Transparency = 255;  // 颜色的透明度, 255表示完全不透明ILineSymbol pLineSymbol = new SimpleLineSymbol();  // 实例化一个线对象
pLineSymbol.Width = 2;  // 线的宽度为2
pLineSymbol.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表示整个鹰眼图范围)

 04 稍作演示

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【交互式阈值二进制图像】采用彩色或单色图像通过交互/手动方式阈值单色图像或彩色图像的单个色带研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

外部中断的基本操作

题目背景 定义一个 Working() 函数&#xff0c;使L1指示灯不断闪烁。将P32引脚定义成外部中断功能&#xff0c;按下S5按键就会产生外部中断触发信号&#xff0c;在中断响应函数中&#xff0c;点亮L8指示灯&#xff0c;延时较长一段时间后熄灭&#xff0c;该功能用两种方法实现…

selenium +IntelliJ+firefox/chrome 环境全套搭配

1第一步&#xff1a;下载IntelliJ idea 代码编辑器 2第二步&#xff1a;下载浏览器Chrome 3第三步&#xff1a;下载JDK 4第四步&#xff1a;配置环境变量&#xff08;1JAVA_HOME 2 path&#xff09; 5第五步&#xff1a;下载Maven 6第六步&#xff1a;配置环境变量&#x…

Scala第十六章节

Scala第十六章节 scala总目录 文档资料下载 章节目标 掌握泛型方法, 类, 特质的用法了解泛型上下界相关内容了解协变, 逆变, 非变的用法掌握列表去重排序案例 1. 泛型 泛型的意思是泛指某种具体的数据类型, 在Scala中, 泛型用[数据类型]表示. 在实际开发中, 泛型一般是结合…

CTFHUB SSRF

目录 web351 ​编辑 web352 web353 web354 sudo.cc 代表 127 web355 host长度 web356 web357 DNS 重定向 web358 bypass web359 mysql ssrf web360 web351 POST查看 flag.php即可 web352 <?php error_reporting(0); highlight_file(__FILE__); $url$_…

Java基础(二)

1. 面向对象基础 1.1 面向对象和面向过程的区别 面向过程把解决问题的过程拆成一个个方法&#xff0c;通过一个个方法的执行解决问题。面向对象会先抽象出对象&#xff0c;然后用对象执行方法的方式解决问题。 面向对象开发的方式更容易维护和迭代升级、易复用、易扩展。 1…

数据防泄密软件排行榜(企业电脑防泄密软件哪一款好用,有哪些推荐)

在当今信息化社会&#xff0c;数据已经成为了企业的重要资产。然而&#xff0c;数据的安全问题也日益突出&#xff0c;尤其是数据的泄露&#xff0c;不仅会导致企业的商业秘密被竞争对手获取&#xff0c;还可能引发一系列的法律问题。因此&#xff0c;数据防泄密软件的重要性不…

it端到端运营监控

公司的运维监控已成为确保业务顺利运行的关键。特别是对于IT部门&#xff0c;端到端运维监控不仅可以帮助企业及时发现和解决问题&#xff0c;还可以提高业务效率&#xff0c;优化客户体验。端到端运维监控的概念、重要性及其实施方法。 端到端操作监控的概念 端到端操作监控&…

NPDP35岁考还有意义吗? NPDP证书认可度如何?

一句话说的好&#xff0c;“活到老&#xff0c;学到老”&#xff0c;只要想学&#xff0c;想干事&#xff0c;什么时候都不晚&#xff0c;何况35岁正是一个人的转折阶段。当然&#xff0c;考取NPDP证书是否真的对自身有意义&#xff0c;这取决于你个人情况和职业发展目标。产品…

京东数据分析平台:2023年8月京东奶粉行业品牌销售排行榜

鲸参谋监测的京东平台8月份奶粉市场销售数据已出炉&#xff01; 鲸参谋数据显示&#xff0c;8月份京东平台上奶粉的销售量将近700万件&#xff0c;环比增长约15%&#xff0c;同比则下滑约19%&#xff1b;销售额将近23亿元&#xff0c;环比增长约4%&#xff0c;同比则下滑约3%。…

QMC5883L-磁力计椭球拟合校准

1.概述 磁力计椭球拟合校准是一种将磁力计测量数据校准到真实磁场的技术。这种技术通常使用椭球模型来拟合磁力计的测量结果&#xff0c;然后通过最小二乘法来找到拟合参数的最优解。 2.总体思想 磁力计椭球拟合校准的思想包括以下几个步骤&#xff1a; 1.数据预处理&#x…

万兆光模块的价格相比千兆光模块贵多少?

万兆光模块和千兆光模块是应用非常广泛的两款产品。万兆光模块与千兆光模块相比&#xff0c;主要优势在于速率更高、带宽更大。传输速率为万兆的光模块&#xff0c;理论上可以实现每秒传输10G的数据&#xff0c;是传输速率约为千兆的光模块的10倍&#xff0c;可以在同等时间内传…

HTML 笔记:初识 HTML(HTML文本标签、文本列表、嵌入图片、背景色、网页链接)

1 何为HTML 用来描述网页的一种语言超文本标记语言(Hyper Text Markup Language)不是一种编程语言&#xff0c;而是一种标记语言 (markup language) 2 HTML标签 HTML 标签是由尖括号包围的关键词&#xff0c;比如 <html> 作用是为了“标记”页面中的内容&#xff0c;使…

TCP VS UDP

程序员写网络程序&#xff0c;主要编写的应用层代码&#xff01; 真正要发这个数据&#xff0c;需要上层协议调用下层协议&#xff0c;应用层要调用传输层&#xff0c;则传输层给应用层提供一组api&#xff0c;统称为&#xff1a;soket api 基于UDP的api 基于TCP的api 这两个协…

深圳市重点实验室申报要求-华夏泰科

深圳市重点实验室&#xff0c;以开展基础研究、应用基础研究、前沿技术研究&#xff0c;培养人才、支撑产业和社会发展为目标而建立。它为研究人员提供了一个独特的平台&#xff0c;提供了一个展示他们创新性研究的舞台。本文将深入探讨如何申报深圳市重点实验室&#xff0c;为…

实战纪实 | 某米企业src未授权访问

公众号&#xff1a;掌控安全EDU 分享更多技术文章&#xff0c;欢迎关注一起探讨学习 某米企业src漏洞挖掘 这一挖就挖到了一个未授权操作漏洞&#xff0c;写个文章记录下~~ 通过信息收集&#xff0c;发现这么一个资产。 访问 http://xxx.com 如下图所示 1.点击头像-点击授权登…

短视频矩阵系统源码--源头技术独立自研框架开发

目录 一、批量剪辑&#xff08;采用php语言&#xff0c;数学建模&#xff09; 短视频合成批量剪辑的算法主要有以下几种&#xff1a; 1. 帧间插值算法&#xff1a;通过对多个视频的帧进行插帧处理&#xff0c;从而合成一段平滑的短视频。 2. 特征提取算法&#xff1a;提取多…

机器学习-数值特征

离散值处理 import pandas as pd import numpy as npvg_df pd.read_csv(datasets/vgsales.csv, encoding "ISO-8859-1") vg_df[[Name, Platform, Year, Genre, Publisher]].iloc[1:7]NamePlatformYearGenrePublisher1Super Mario Bros.NES1985.0PlatformNintendo2…

【二叉树练习题】

欢迎来到我的&#xff1a;世界 希望作者的文章对你有所帮助&#xff0c;有不足的地方还请指正&#xff0c;大家一起学习交流 ! 目录 前言初阶题二叉树的节点个数二叉树的叶子节点个数二叉树第k层节点个数二叉树查找值为x的节点 进阶题完全二叉树的节点个数翻转二叉树检验两个树…

二叉树--二叉树最小深度

文章前言&#xff1a;如果有小白同学还是对于二叉树不太清楚&#xff0c;作者推荐&#xff1a; 二叉树的初步认识_加瓦不加班的博客-CSDN博客 后序遍历求解 public int minDepth(TreeNode node) {if (node null) {return 0;}int d1 minDepth(node.left);int d2 minDepth(n…