黄石市网站建设,网站服务器时间查询工具,建站边检站,建设个人网站需要备案吗目录 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 创建项目…目录 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事件呢 加载MXD文档当你使用AxMapControl的LoadMxFile方法加载一个新的MXDMap Exchange DocumentArcMap的地图文档格式时当前的Map对象会被新的MXD中的Map对象替换因此触发该事件。 设置Map属性如果你直接设置AxMapControl的Map属性为一个新的Map对象那么此事件也会被触发。 添加/移除数据帧如果你在ArcMap中有多个数据帧并使用ArcObjects代码或ArcMap界面添加或删除数据帧OnMapReplaced事件也可能被触发。 新建地图如果你在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 稍作演示