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

news2024/11/23 18:44:26

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;  // 赋初值None
            IBasicMap 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 members
        private IMapControl3 m_mapControl = null;
        private string m_mapDocumentName = string.Empty;
        #endregion

        #region class constructor
        public MainForm()
        {
            InitializeComponent();
        }
        #endregion

        private void MainForm_Load(object sender, EventArgs e)
        {
            //get the MapControl
            m_mapControl = (IMapControl3)axMapControl1.Object;

            //disable the Save menu (since there is no document yet)
            menuSaveDoc.Enabled = false;
        }

        #region Main Menu event handlers
        private void menuNewDoc_Click(object sender, EventArgs e)
        {
            //execute New Document command
            ICommand command = new CreateNewDocument();
            command.OnCreate(m_mapControl.Object);
            command.OnClick();
        }

        private void menuOpenDoc_Click(object sender, EventArgs e)
        {
            //execute Open Document command
            ICommand command = new ControlsOpenDocCommandClass();
            command.OnCreate(m_mapControl.Object);
            command.OnClick();
        }

        private void menuSaveDoc_Click(object sender, EventArgs e)
        {
            //execute Save Document command
            if (m_mapControl.CheckMxFile(m_mapDocumentName))
            {
                //create a new instance of a MapDocument
                IMapDocument mapDoc = new MapDocumentClass();
                mapDoc.Open(m_mapDocumentName, string.Empty);

                //Make sure that the MapDocument is not readonly
                if (mapDoc.get_IsReadOnly(m_mapDocumentName))
                {
                    MessageBox.Show("Map document is read only!");
                    mapDoc.Close();
                    return;
                }

                //Replace its contents with the current map
                mapDoc.ReplaceContents((IMxdContents)m_mapControl.Map);

                //save the MapDocument in order to persist it
                mapDoc.Save(mapDoc.UsesRelativePaths, false);

                //close the MapDocument
                mapDoc.Close();
            }
        }

        private void menuSaveAs_Click(object sender, EventArgs e)
        {
            //execute SaveAs Document command
            ICommand command = new ControlsSaveAsDocCommandClass();
            command.OnCreate(m_mapControl.Object);
            command.OnClick();
        }

        private void menuExitApp_Click(object sender, EventArgs e)
        {
            //exit the application
            Application.Exit();
        }
        #endregion

        //listen to MapReplaced evant in order to update the statusbar and the Save menu
        private void axMapControl1_OnMapReplaced(object sender, IMapControlEvents2_OnMapReplacedEvent e)
        {
            //get the current document name from the MapControl
            m_mapDocumentName = m_mapControl.DocumentFilename;

            //if there is no MapDocument, diable the Save menu and clear the statusbar
            if (m_mapDocumentName == string.Empty)
            {
                menuSaveDoc.Enabled = false;
                statusBarXY.Text = string.Empty;
            }
            else
            {
                //enable the Save manu and write the doc name to the statusbar
                menuSaveDoc.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;  // 赋初值None
            IBasicMap 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对象
        }

    }
}

实现界面:

在这里插入图片描述

打开地图文档功能:

在这里插入图片描述

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

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

SpringBoot——日志及原理

优质博文&#xff1a;IT-BLOG-CN 一、SpringBoot日志 选用 SLF4j&#xff08;接口&#xff09;和 logback&#xff08;实现类&#xff09;&#xff0c;除了上述日志框架&#xff0c;市场上还存在 JUL(java.util.logging)、JCL(Apache Commons Logging)、Log4j、Log4j2、SLF4j…

QT5 MSVC2017 64bit配置OpenCV4.5无需编译与示范程序

环境&#xff1a;Windows 10 64位 Opencv版本&#xff1a;4.5 QT&#xff1a;5.14 QT5 MSVC2017配置OpenCV 版本参考&#xff1a; opencv msvc c对应版本 1.安装MSVC2017&#xff08;vs2017&#xff09; 打开Visual Studio Installer&#xff0c;点击修改 选择vs2017生成工…

U-boot(三):start.S

本文主要探讨x210的uboot的start.S文件,也是uboot启动的第一阶段。 头文件 config.h config.h x210_sd.h,由mkconfig脚本生成,包含了开发板的配置宏 rootkaxi-virtual-machine:~/qt_x210v3s_160307/uboot/include# cat config.h /* Automatically generate…

基于水基湍流算法优化概率神经网络PNN的分类预测 - 附代码

基于水基湍流算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于水基湍流算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于水基湍流优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

day15-Linux对文件系统的支持

1.Linux中使用文件系统分几个部分 1.1 有关于Linux中高速缓冲区的管理程序。 分页机制 buffer.c 1.2 文件系统的底层通用函数(对于硬盘的读写 分配 释放等&#xff0c;对于目录的节点管理 inode 内存与磁盘的映射) 1.3 对文件数据进行读写操作模块 (VFS&#xff1a;虚拟文件系统…

CSDN的文档编辑器使用

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

K8S(一)

一、kubernetes 概述 1、kubernetes 基本介绍 kubernetes&#xff0c;简称 K8s&#xff0c;是用 8 代替 8 个字符“ubernete”而成的缩写。是一个开源的&#xff0c;用于管理云平台中多个主机上的容器化的应用&#xff0c;Kubernetes 的目标是让部署容器化的 应用简单并且高效…

Upwork 新手使用指南——如何快速在Upwork上接单

Upwork 这个自由职业平台不知道大家听说过没&#xff0c;在 Upwork&#xff0c;如果你是自由职业者&#xff0c;你可以接单&#xff1b;如果你是客户&#xff0c;你可以找人干活。但对于新手来说&#xff0c;怎么使用 Upwork 并且用好 Upwork 是一大难题。因此今天给大家分享 U…

uvm环境获取系统时间的方法和使用案例

背景&#xff1a; 有时候我们想统计一下验证环境中某个步骤总共花费了多少时间&#xff0c;有什么比较方便的方法呢&#xff0c;利用$realtime理论上也是能做到的&#xff0c;不过这个和timescale绑定起来了&#xff0c;需要手动换算成单位是秒的数&#xff0c;现在提供一种利用…

数据分析基础之《jupyter notebook工具》

一、安装库 1、linux库 yum install python3-devel 2、python库 pip3 install -U matplotlib pip3 install -U numpy pip3 install -U pandas pip3 install -U TA-Lib pip3 install -U tables pip3 install -U notebook 3、如果TA-Lib安装不上&#xff0c;先手动安装依赖库 …

2019年计网408

第33题 OSI 参考模型的第 5 层&#xff08;自下而上&#xff09;完成的主要功能是()A. 差错控制B. 路由选择C. 会话管理D. 数据表示转换 本题考察开放系统互联参考模型的第五层完成的主要功能。开放系统互联参考模型是一个七层的体系结构。自下而上&#xff0c;依次是物理层、…

基于Vue+SpringBoot的校园电商物流云平台开源项目

项目编号&#xff1a; S 034 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S034&#xff0c;文末获取源码。} 项目编号&#xff1a;S034&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 商品数据模块2.3 快…

小红书为什么没人看,小红书爆款标题怎么写?

作为快节奏的社会&#xff0c;人们追求的是不仅仅是高价值更是高性价比&#xff0c;和吸引度。而标题类似于门面&#xff0c;吸引程度自然作为重中之重。今天我们和大家分享下小红书为什么没人看&#xff0c;小红书爆款标题怎么写&#xff1f; 以母婴类型为例子&#xff0c;母婴…

笔记57:双向循环神经网络

本地笔记地址&#xff1a;D:\work_file\DeepLearning_Learning\03_个人笔记\3.循环神经网络\第9章&#xff1a;动手学深度学习~现代循环神经网络 a a a a a a a a a a a a

【活动通知】2023 Elastic Meetup 北京站将于12月2日下午1点30在北京召开

《2023 Elastic Meetup 北京站》活动将于 12 月 2 日下午 1 点 30 在北京市海淀区西北旺东路10号腾讯北京总部大楼213会议室举办&#xff0c;届时将有行业专家及知名企业分享他们在 Elasticsearch 应用中的经验与观点&#xff0c;带来最前沿的技术分享与思想碰撞。 请使用电脑浏…

SVG直线 <line>与折线 <polyline>代码示例

本专栏是汇集了一些HTML常常被遗忘的知识&#xff0c;这里算是温故而知新&#xff0c;往往这些零碎的知识点&#xff0c;在你开发中能起到炸惊效果。我们每个人都没有过目不忘&#xff0c;过久不忘的本事&#xff0c;就让这一点点知识慢慢渗透你的脑海。 本专栏的风格是力求简洁…

Win10 开始菜单、微软app和设置都打不开(未解决)

环境&#xff1a; Win10专业版 问题描述&#xff1a; Win10 开始菜单、微软app和设置都打不开,桌面个性话打开就报错&#xff0c;打开个性化该文件没有与之关联的程序来执行该操作 解决方案&#xff1a; 一般造成原因是MS-Settings文件系统错误 1.先重启电脑&#xff08;重…

吐槽一个 R package :DSS

TMD&#xff01;&#xff01;&#xff01; 前言 最近在整理WGBS分析的流程&#xff0c;下游需要找 Differentially Methylated Loci (DML) / Region (DMR)&#xff0c;类似普通转录组中的差异分析。之前看的一篇文章提到一个R package &#xff1a; DSS&#xff0c;看Biocond…

直播美颜SDK对比评测:技术原理与应用实践

直播行业蓬勃发展&#xff0c;其中&#xff0c;美颜滤镜技术在直播中扮演着至关重要的角色。本文将深入探讨不同直播美颜SDK的技术原理&#xff0c;并通过对比评测它们在实际应用中的表现&#xff0c;以揭示各SDK的优劣之处。 一、背景 随着直播技术的不断进步&#xff0c;直…

又欲又撩人,基于新版Bert-vits2V2.0.2音色模型雷电将军八重神子一键推理整合包分享

Bert-vits2项目近期炸裂更新&#xff0c;放出了v2.0.2版本的代码&#xff0c;修正了存在于2.0先前版本的重大bug&#xff0c;并且重炼了底模&#xff0c;本次更新是即1.1.1版本后最重大的更新&#xff0c;支持了三语言训练及混合合成&#xff0c;并且做到向下兼容&#xff0c;可…