当前位置: 首页 > article >正文

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;  // 赋初值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.kler.cn/news/135857.html

相关文章:

  • 关于这个“这是B站目前讲的最好的【Transformer实战】教程!“视频的目前可以运行的源代码GPU版本
  • 采集1688整店商品(店铺所有商品、店铺列表api)
  • 北京君正客户应用案例:掌静脉3D人脸猫眼视屏智能锁
  • 信息机房监控系统(动环辅助监控系统)
  • 4种经典的限流算法与集群限流
  • MAC地址_MAC地址格式_以太网的MAC帧_基础知识
  • IDEA运行thymeleaf的html文件打开端口为63342且连不上数据库
  • pnpm : 无法加载文件 E:\Soft\PromSoft\nodejs\node_global\pnpm.ps1,
  • 理解Android线程基础与多线程编程模型
  • CTFHub Git泄露
  • Spring Framework IOC依赖查找 - 按类型查找解析
  • Linux-CentOS重要模块
  • 编写高效的消息传递代码-对消息进行降维
  • 不同content-type对应的前端请求参数处理格式
  • HTTP四种请求方式,状态码,请求和响应报文
  • 比赛调研资料
  • Apache阿帕奇安装配置
  • 学习c#的第二十一天
  • pip list 和 conda list的区别
  • 在市场发展中寻变革,马上消费金融树行业发展“风向标”
  • Android修行手册-POI操作中文API文档
  • 数据结构之链表练习与习题详细解析
  • HTTPS流量抓包分析中出现无法加载key
  • vscode Prettier配置
  • 苹果(Apple)公司的新产品开发流程(一)
  • 计蒜客T1654 数列分段(C语言实现)
  • 结合scss实现黑白主题切换
  • 趣学python编程 (五、常用IDE环境推荐)
  • 10 Redis的持久化
  • c++ 获取当前时间(精确至秒、毫秒和微妙)