ArcEngine:如何进行缩放图层、属性信息显示、状态栏显示?

2023-11-21 00:20

本文主要是介绍ArcEngine:如何进行缩放图层、属性信息显示、状态栏显示?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

01 前言

如果以后不是工作相关,我或许以后再难了解ArcEngine相关的GIS桌面软件二次开发的内容?

02 要求

  1. 创建窗体应用程序;(10分)
  2. 修改窗口标题为本人的“学号 姓名”;(5分)
  3. 添加主地图控件、图层树控件和数据表显示控件,并合理布局;(10分)
  4. 添加菜单和状态栏控件;(5分)
  5. 增加“打开地图文档”菜单功能,弹出对话框选择地图文档(*.mxd),在主地图控件中显示该地图;(10分)
  6. 鼠标在主地图控件中移动时,将鼠标对应的地图坐标显示在状态栏上;(10分)
  7. 地图显示范围发生改变时,将地图比例显示在状态栏上;(10分)
  8. 点击图层控件的图层项,将地图视图显示范围缩放到该图层范围;(10分)
  9. 在数据表显示控件中显示所选图层的属性;(20分)
  10. 撰写期末考查报告。(10分)

笔记本;WIndow11;VS2012;ArcEngine10.2

如果安装高版本的VS可能无法完美复现本博客,因为高版本VS如何创建基础版的应用,而是创建的完全0的空应用。

03 实现步骤和代码说明

3.1 创建窗体应用程序(创建项目)

在这里插入图片描述

初始界面如下:

在这里插入图片描述

在这里插入图片描述

如果不存在上述面板如下打开:

在这里插入图片描述

如此可以看到如下初始界面:

在这里插入图片描述

在这里插入图片描述

3.2 修改窗口标题为本人的“学号 姓名”

在这里插入图片描述

3.3 添加主地图控件、图层树控件和数据表显示控件,并合理布局

主地图控件和图层树控件已经在创建项目之后已经存在了,只是数据表(用于后续选中图层的属性信息显示)并没有,而且要与当前控件布局协调。

数据表使用DataGridView工具。

3.3.1 添加数据表DataGridView

在这里插入图片描述

3.3.2 调整布局

但是目前布局不合理,我们需要调整DataGridViewaxMapControl1(主地图控件)的空间位置。

修改DataGridViewDock属性为Bottom,这里就是用其他工具进行调整了,简单一些好了。

在这里插入图片描述

3.4 添加菜单和状态栏控件;

由于创建项目时已经帮助我们添加这些控件,因此我们无需重复操作,这里直接运行看看界面吧。

在这里插入图片描述

3.5 增加“打开地图文档”菜单功能,弹出对话框选择地图文档(*.mxd),在主地图控件中显示该地图;

这个功能实际上创建项目时也已经实现了,因此演示如下:

在这里插入图片描述

3.6 鼠标在主地图控件中移动时,将鼠标对应的地图坐标显示在状态栏上;

实际上也已经实现,这里不再说明

3.7 地图显示范围发生改变时,将地图比例显示在状态栏上

状态栏加一个用于显示比例尺:

在这里插入图片描述

监听范围更新事件:

在这里插入图片描述

事件代码如下:

private void axMapControl1_OnExtentUpdated(object sender, IMapControlEvents2_OnExtentUpdatedEvent e){//当前比例尺string strScale = "   1:" + ((long)axMapControl1.MapScale).ToString() + "  ";// 在状态栏中进行格式化显示statusBarScale.Text = string.Format("{0}", strScale);}

实现效果如下:

在这里插入图片描述

3.8 点击图层控件的图层项,将地图视图显示范围缩放到该图层范围

显然,需要监听TOC图层树的鼠标点击事件:

在这里插入图片描述

事件代码如下:

// 当鼠标点击图层时, 实现图层缩放和属性获取显示两个功能private void axTOCControl1_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e){// 做鼠标点击位置检测-用于获取当前点击位置是否为图层以及获取点击的图层对象esriTOCControlItem itemType = esriTOCControlItem.esriTOCControlItemNone;  // 赋初值NoneIBasicMap basicMap = null;ILayer pCurLayer = null;object unk = null;object data = null;axTOCControl1.HitTest(e.x, e.y, ref itemType, ref basicMap, ref pCurLayer, ref unk, ref data);  // 检测点击位置, 返回给ref等// 如果点击的不是图层对象, 那么不进行任何操作if (itemType != esriTOCControlItem.esriTOCControlItemLayer){return;}// 如果pCurLayer为空则不进行操作if (pCurLayer == null){return;}// 获取当前点击图层的感兴趣区域范围IEnvelope env = pCurLayer.AreaOfInterest;  // 获取当前点击图层的范围// 当前选中图层的框为空, 那么不进行任何操作if ((env.IsEmpty) || (env == null)){return;}// 将主视图的范围显示为当前右键选中图层的范围, 实现缩放到当前图层的功能axMapControl1.Extent = env;// 显示当前图层属性(自定义一个query_feature_class函数进行操作, 传入当前点击图层变量)query_feature_class(pCurLayer);}

上述代码最后部分加入了一个自定义函数:

// 显示当前图层属性(自定义一个query_feature_class函数进行操作, 传入当前点击图层变量)
query_feature_class(pCurLayer);

注意:这是后续功能(显示选中图层的属性信息)的实现。

3.9 在数据表显示控件中显示所选图层的属性

我们主要实现前面的query_feature_class函数,代码如下:

// 实现选择所选图层属性功能
privatevoid query_feature_class(ILayer layer)
{// 获取空间过滤对象ISpatialFilter pSpatialFilter = new SpatialFilter();pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;pSpatialFilter.GeometryField = "Shape";// 将当前传入该函数的 layer 进行过滤IFeatureClass pFeatureClass = (layer as IFeatureLayer).FeatureClass;IFeatureCursor pFeatureCursor = pFeatureClass.Search(pSpatialFilter, true);if (pFeatureCursor == null){dataGridView.DataSource = null;}else{// 将对象传入dataGridView.DataSource = cursor2table(pFeatureCursor);}
}// 图层属性信息与DataGridView数据格式的转换
private DataTable cursor2table(IFeatureCursor pFeatureCursor)
{// 为DataGridView创建表头并赋值DataTable tbl = new DataTable();for (int ix = 0; ix < pFeatureCursor.Fields.FieldCount; ix++){tbl.Columns.Add(pFeatureCursor.Fields.get_Field(ix).Name);}// 将所有要素一行一行的迭代传入DataGridView中IFeature pFeature = pFeatureCursor.NextFeature();while (pFeature != null){DataRow row = tbl.NewRow();for (int ix = 0; ix < pFeatureCursor.Fields.FieldCount; ix++){row[ix] = pFeature.get_Value(ix).ToString();}tbl.Rows.Add(row);pFeature = pFeatureCursor.NextFeature();}return tbl;  // 返回已经存有图层属性信息的DataGridView对象
}

04 完整代码和应用界面展示

如此所有功能实现,完整代码:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Runtime.InteropServices;using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.SystemUI;using ESRI.ArcGIS.Geometry;namespace DropCurtain
{public sealed partial class MainForm : Form{#region class private membersprivate IMapControl3 m_mapControl = null;private string m_mapDocumentName = string.Empty;#endregion#region class constructorpublic MainForm(){InitializeComponent();}#endregionprivate void MainForm_Load(object sender, EventArgs e){//get the MapControlm_mapControl = (IMapControl3)axMapControl1.Object;//disable the Save menu (since there is no document yet)menuSaveDoc.Enabled = false;}#region Main Menu event handlersprivate void menuNewDoc_Click(object sender, EventArgs e){//execute New Document commandICommand command = new CreateNewDocument();command.OnCreate(m_mapControl.Object);command.OnClick();}private void menuOpenDoc_Click(object sender, EventArgs e){//execute Open Document commandICommand command = new ControlsOpenDocCommandClass();command.OnCreate(m_mapControl.Object);command.OnClick();}private void menuSaveDoc_Click(object sender, EventArgs e){//execute Save Document commandif (m_mapControl.CheckMxFile(m_mapDocumentName)){//create a new instance of a MapDocumentIMapDocument mapDoc = new MapDocumentClass();mapDoc.Open(m_mapDocumentName, string.Empty);//Make sure that the MapDocument is not readonlyif (mapDoc.get_IsReadOnly(m_mapDocumentName)){MessageBox.Show("Map document is read only!");mapDoc.Close();return;}//Replace its contents with the current mapmapDoc.ReplaceContents((IMxdContents)m_mapControl.Map);//save the MapDocument in order to persist itmapDoc.Save(mapDoc.UsesRelativePaths, false);//close the MapDocumentmapDoc.Close();}}private void menuSaveAs_Click(object sender, EventArgs e){//execute SaveAs Document commandICommand command = new ControlsSaveAsDocCommandClass();command.OnCreate(m_mapControl.Object);command.OnClick();}private void menuExitApp_Click(object sender, EventArgs e){//exit the applicationApplication.Exit();}#endregion//listen to MapReplaced evant in order to update the statusbar and the Save menuprivate void axMapControl1_OnMapReplaced(object sender, IMapControlEvents2_OnMapReplacedEvent e){//get the current document name from the MapControlm_mapDocumentName = m_mapControl.DocumentFilename;//if there is no MapDocument, diable the Save menu and clear the statusbarif (m_mapDocumentName == string.Empty){menuSaveDoc.Enabled = false;statusBarXY.Text = string.Empty;}else{//enable the Save manu and write the doc name to the statusbarmenuSaveDoc.Enabled = true;statusBarXY.Text = System.IO.Path.GetFileName(m_mapDocumentName);}}private void axMapControl1_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e){statusBarXY.Text = string.Format("{0}, {1}  {2}", e.mapX.ToString("#######.##"), e.mapY.ToString("#######.##"), axMapControl1.MapUnits.ToString().Substring(4));}private void axMapControl1_OnExtentUpdated(object sender, IMapControlEvents2_OnExtentUpdatedEvent e){//当前比例尺string strScale = "   1:" + ((long)axMapControl1.MapScale).ToString() + "  ";// 在状态栏中进行格式化显示statusBarScale.Text = string.Format("{0}", strScale);}private void axTOCControl1_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e){// 做鼠标点击位置检测-用于获取当前点击位置是否为图层以及获取点击的图层对象esriTOCControlItem itemType = esriTOCControlItem.esriTOCControlItemNone;  // 赋初值NoneIBasicMap basicMap = null;ILayer pCurLayer = null;object unk = null;object data = null;axTOCControl1.HitTest(e.x, e.y, ref itemType, ref basicMap, ref pCurLayer, ref unk, ref data);  // 检测点击位置, 返回给ref等// 如果点击的不是图层对象, 那么不进行任何操作if (itemType != esriTOCControlItem.esriTOCControlItemLayer){return;}// 如果pCurLayer为空则不进行操作if (pCurLayer == null){return;}// 获取当前点击图层的感兴趣区域范围IEnvelope env = pCurLayer.AreaOfInterest;  // 获取当前点击图层的范围// 当前选中图层的框为空, 那么不进行任何操作if ((env.IsEmpty) || (env == null)){return;}// 将主视图的范围显示为当前右键选中图层的范围, 实现缩放到当前图层的功能axMapControl1.Extent = env;// 显示当前图层属性(自定义一个query_feature_class函数进行操作, 传入当前点击图层变量)query_feature_class(pCurLayer);}// 实现选择所选图层属性功能private void query_feature_class(ILayer layer){// 获取空间过滤对象ISpatialFilter pSpatialFilter = new SpatialFilter();pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;pSpatialFilter.GeometryField = "Shape";// 将当前传入该函数的 layer 进行过滤IFeatureClass pFeatureClass = (layer as IFeatureLayer).FeatureClass;IFeatureCursor pFeatureCursor = pFeatureClass.Search(pSpatialFilter, true);if (pFeatureCursor == null){dataGridView.DataSource = null;}else{// 将对象传入dataGridView.DataSource = cursor2table(pFeatureCursor);}}// 图层属性信息与DataGridView数据格式的转换private DataTable cursor2table(IFeatureCursor pFeatureCursor){// 为DataGridView创建表头并赋值DataTable tbl = new DataTable();for (int ix = 0; ix < pFeatureCursor.Fields.FieldCount; ix++){tbl.Columns.Add(pFeatureCursor.Fields.get_Field(ix).Name);}// 将所有要素一行一行的迭代传入DataGridView中IFeature pFeature = pFeatureCursor.NextFeature();while (pFeature != null){DataRow row = tbl.NewRow();for (int ix = 0; ix < pFeatureCursor.Fields.FieldCount; ix++){row[ix] = pFeature.get_Value(ix).ToString();}tbl.Rows.Add(row);pFeature = pFeatureCursor.NextFeature();}return tbl;  // 返回已经存有图层属性信息的DataGridView对象}}
}

实现界面:

在这里插入图片描述

打开地图文档功能:

在这里插入图片描述

图层缩放和选中图层的属性信息显示:

在这里插入图片描述

在这里插入图片描述

这篇关于ArcEngine:如何进行缩放图层、属性信息显示、状态栏显示?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

JavaScript中的isTrusted属性及其应用场景详解

《JavaScript中的isTrusted属性及其应用场景详解》在现代Web开发中,JavaScript是构建交互式应用的核心语言,随着前端技术的不断发展,开发者需要处理越来越多的复杂场景,例如事件... 目录引言一、问题背景二、isTrusted 属性的来源与作用1. isTrusted 的定义2. 为

C#实现系统信息监控与获取功能

《C#实现系统信息监控与获取功能》在C#开发的众多应用场景中,获取系统信息以及监控用户操作有着广泛的用途,比如在系统性能优化工具中,需要实时读取CPU、GPU资源信息,本文将详细介绍如何使用C#来实现... 目录前言一、C# 监控键盘1. 原理与实现思路2. 代码实现二、读取 CPU、GPU 资源信息1.

如何设置vim永久显示行号

《如何设置vim永久显示行号》在Linux环境下,vim默认不显示行号,这在程序编译出错时定位错误语句非常不便,通过修改vim配置文件vimrc,可以在每次打开vim时永久显示行号... 目录设置vim永久显示行号1.临时显示行号2.永www.chinasem.cn久显示行号总结设置vim永久显示行号在li

Python将大量遥感数据的值缩放指定倍数的方法(推荐)

《Python将大量遥感数据的值缩放指定倍数的方法(推荐)》本文介绍基于Python中的gdal模块,批量读取大量多波段遥感影像文件,分别对各波段数据加以数值处理,并将所得处理后数据保存为新的遥感影像... 本文介绍基于python中的gdal模块,批量读取大量多波段遥感影像文件,分别对各波段数据加以数值处

使用MongoDB进行数据存储的操作流程

《使用MongoDB进行数据存储的操作流程》在现代应用开发中,数据存储是一个至关重要的部分,随着数据量的增大和复杂性的增加,传统的关系型数据库有时难以应对高并发和大数据量的处理需求,MongoDB作为... 目录什么是MongoDB?MongoDB的优势使用MongoDB进行数据存储1. 安装MongoDB

在C#中获取端口号与系统信息的高效实践

《在C#中获取端口号与系统信息的高效实践》在现代软件开发中,尤其是系统管理、运维、监控和性能优化等场景中,了解计算机硬件和网络的状态至关重要,C#作为一种广泛应用的编程语言,提供了丰富的API来帮助开... 目录引言1. 获取端口号信息1.1 获取活动的 TCP 和 UDP 连接说明:应用场景:2. 获取硬

Linux使用fdisk进行磁盘的相关操作

《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学

C#实现获取电脑中的端口号和硬件信息

《C#实现获取电脑中的端口号和硬件信息》这篇文章主要为大家详细介绍了C#实现获取电脑中的端口号和硬件信息的相关方法,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 我们经常在使用一个串口软件的时候,发现软件中的端口号并不是普通的COM1,而是带有硬件信息的。那么如果我们使用C#编写软件时候,如