• 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);
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    实现效果如下:

    在这里插入图片描述

    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);
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

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

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

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

    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对象
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    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对象
            }
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222

    实现界面:

    在这里插入图片描述

    打开地图文档功能:

    在这里插入图片描述

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

    在这里插入图片描述

    在这里插入图片描述

  • 相关阅读:
    【构建ML驱动的应用程序】第 3 章 :构建您的第一个端到端管道
    Rust 基础(六)
    1-数据库基本概念
    mysql数据库比实际时间少了8小时
    两个对象相等(==、equals、hashCode)详解
    QT使用cmake构建安卓项目时报错
    【Python】《Python编程:从入门到实践 (第2版) 》笔记-Chapter10-文件和异常
    前端面试宝典~Symbol、相同的Set、Getter、控制动画、js中哪些操作会造成内存泄漏?等......
    js模块化CJS、AMD、CMD、UMD、ESM、IIFE理解
    Django-request请求
  • 原文地址:https://blog.csdn.net/m0_63001937/article/details/134519196