ArcEngine C# GIS开发入门作业 (一) Ex01,Ex02 ——地图、图层加载及属性访问

AE C# GIS 设计与开发课程分享(一) Ex01,Ex02——地图、图层加载及属性 访问

  • 这学期在想学习的动力下,刚结束了GIS开发与设计课,简单入门了刚学的C#和ArcEngine,想趁热写点东西记录下来。

  • 感觉这个作业Ex01-Ex07全做一遍就可以基本入门ArcEngine C#开发了,欢迎和我一样的大家一起学习。

    写这篇文章:
    1.第一,是为了纪念一下我Domen的入门IT的人生重大转折点;
    2.第二是为了锻炼一下自己写作的能力;
    3.还有因为我为了增加印象我重新整理了一下自己作业的代码花了很多时间不想浪费,直接拿出来供分享希望做点贡献;

    虽然下面的代码质量肯定是经不住的各种考验,但还是可以运行的,慢慢来。相信有很多和我一样的入门级的同胞,没事的,都是这么一窍不通过来的啦,我也是零基础过来的多亏了舍友,同学的讲解,才能勉强更得上大家的步伐。踩了贼多坑,建议还是了解一下控件和类的功能实现原理等等,那样捋的舒服点,不然这里搬一点那里搬一点不怎么好整,写别的代码也一样吧,都是从看代码到模仿的。然后没有一点C#基础的话看起来可能会有点吃力,我这学期其实也算是没C#基础,虽然大二下选修了C#但根本就是水过的,所以还是花了很多很多时间,其实我昨前天重新理一遍作业后才会自己写一点代码,之前都是复制粘贴。

  • 好的现在终于步入正题了,一不小心简单介绍写这么多,我们的GIS开发与设计,是利用ArcEngine10.2和VS2012配套学习的,一边课上听老师讲教材,一边课下完成老师的作业

相应的教材和作业文件在这里:
  • 链接:https://pan.baidu.com/s/15dlQuZyrx9OtZUNNZptXoA
    提取码:88d6
    复制这段内容后打开百度网盘手机App,操作更方便哦

因为每个地图文件与空间数据库的路径是设置好的,所以每个作业需要打开对应的文件夹下的地图否则打不开,比如说把地图单独粘贴到其他地方就打不开了

  • 首先是第一部分安装和配置了,对应的VS和engine是这样,vs2012-ArcGIS10.2,vs2013 / 2015-ArcGIS10.4,VS10.6-ArcGIS2015 / 2017,按需求吧,我自己的安装是参考这位大哥的文章 https://blog.csdn.net/qq_35117024/article/details/80131198?utm_source=blogxgwz0 ,很详细,其他版本的vs和gis我也都有,有需要可以留言,注意如果有安装ArcGIS的话看一下破解文件service.txt,改成本地主机。安装和配置完按照结尾步骤生成一个窗体瞧瞧,相信大家就迫不及待的打开窗体想开始干活了。
    ArcEngine C# GIS开发入门作业 (一) Ex01,Ex02 ——地图、图层加载及属性访问_第1张图片

EX01:ArcObjects中有哪几种Class,Class之间存在哪些关系?采用ArcObjects中的实例进行说明,每种举3~5例。

  • 这里不赘述了,在我上面分享的百度云链接里有作业文档。

EX02 :关系编写程序,获取MapDocument 中的地图,获取地图中的图层,获取图层的基本属性。

ArcEngine C# GIS开发入门作业 (一) Ex01,Ex02 ——地图、图层加载及属性访问_第2张图片

功能需求:
  1. 加载MapDocument,并获取其包含的Map。
  2. 获取当前选中Map所包含的Layer。
  3. 显示选中Layer的属性信息。
实现效果

ArcEngine C# GIS开发入门作业 (一) Ex01,Ex02 ——地图、图层加载及属性访问_第3张图片

  • 这个作业的功能需求,我一开始看上去,完全不知道什么意思,先跟着给的截图布置一下窗体,慢慢的就理解了
    进去正题,在创建工程后(我创建的是EngineWindowsApplication),首先在from1.cs[设计]*窗口添加控件进去(我这里将from1改成了MainFrom02文件,下面就用MainFrom02.cs*来叙述),如图
    在这里插入图片描述
  • 依次将地图控件,LicenseControl(如果在普通的Windows项目中没有这个控件无法运行)拖入窗体(窗体的大小可以自行拉伸),这个界面呢,Ctrl+W,X打开工具箱,根据要求布置窗体界面就是按钮等等这个C#基本的控件,如下图,控件的分类什么和基本用法的自己可以去搜索一下,简单来说就是一个属性和一个事件。属性就是控件在基本的显示效果,在窗体中的位置和一些基本功能的设置,是不需要编写代码的;事件则是触发之后执行相关操作,如按钮点击,鼠标移动,下拉选择等等,选择控件右击属性,右侧属性窗格中一个闪电标志,就可以双击点进去写代码了,函数体什么的它都会帮你生成后,然后就可以按自己需求在生成的函数体力改动。

ArcEngine C# GIS开发入门作业 (一) Ex01,Ex02 ——地图、图层加载及属性访问_第4张图片
然后在Program.cs中加入下列有备注的三行代码:

using ESRI.ArcGIS;//需加
using ESRI.ArcGIS.esriSystem;//需加
//引用,本作业程序要用到
有用到别的当然可以自行添加
 
        static void Main()
        {
            ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);//需加
        //engine控件的使用需加入此行
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }

然后在MainFrom02.cs中加入下图中用红框框出的部分(被#region 和#endregion 框起来的代码部分可以缩成上图中的灰色小框#region 后的文字会显示在灰色小框里在每个功能块之间用了一个空行来分开方便阅读)
在这里插入图片描述

  • 这里就直接放代码了,每句话我都尝试着写出了其中的含义,应该还是有错的不过大部分是没问题的(这里必须提个醒,下面代码里面的函数都是由MainFrom02.cs[设计]*窗口中双击相应控件的事件自动生成的,比如下图生成private void button2_Click(object sender, EventArgs e) 的这样,所以如果直接复制粘贴下面的代码到自己的form1文件是一般不能运行的,我们需要在自己设计的窗口中对不同的控件的事件进行下图的方式在form1.cs文件里生成相对应的函数头,再把下面代码的对应函数中的内容复制粘贴到自己生成的空函数里,才可以运行
    ArcEngine C# GIS开发入门作业 (一) Ex01,Ex02 ——地图、图层加载及属性访问_第5张图片
    然后就会在MainFrom02.cs窗口中生成private void button2_Click(object sender, EventArgs e) 函数
    在这里插入图片描述
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using ESRI.ArcGIS.Carto; //用来应用下面代码中的 IMapDocument,IMap,ILayer
 



namespace EngineWindowsApplication1
{
    public partial class MainForm02 : Form
    {
        public MainForm02()
        {
            ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);
            //engine控件的使用需加入此行
            InitializeComponent();
        }
        
        #region    //文件打开  1、加载MapDocument,并获取其包含的Map。
        private void button2_Click(object sender, EventArgs e)
        {
            OpenFileDialog OFD = new OpenFileDialog();//创建一个新的OpenFileDialog类(也就是打开文件的对话框控件),并命名为ODF
            OFD.Title = "打开地图文档文件";//设置对话框控件的对话框名字为"打开地图文档文件",就是对话框的左上角的名字
            OFD.Filter = "地图文档(*.mxd)|*.mxd";//在对话框中的文件类型中,筛选掉除了*.mxd为后缀名的文件,(这样在对话框中打开的文件夹中就只有*.mxd为后缀的文件了)
            if (OFD.ShowDialog() ==DialogResult.OK)//检查地图文件是否有效,有效就继续执行if下面的语句块
            {
                string filePath = OFD.FileName;//将选择的文件的路径赋予新创建的filePath字符串中
                if (axMapControl1.CheckMxFile(filePath))//  CheckMxFile用来判断地址是否有效,同理有效执行if下面的语句块
                {
                    axMapControl1.LoadMxFile(filePath, 0,Type.Missing);
                    //使用axMapControl1.LoadMxFile来加载filePath路径中的文件(即mxd地图文件),下面的代码是依次访问各个地图,并将地图显示在axMapControl中。
                    IMapDocument pMapDocument = new MapDocumentClass();
                    pMapDocument.Open(filePath, null);
                    //这里是获取路径文件的地图,将地址存入pMapDocument中
                    for (int i = 0; i <= pMapDocument.MapCount-1; i++)
                    {
                        axMapControl1.Map = pMapDocument.get_Map(i);//这里将pMapDocument中的地图获取到axMapControl1中,以得到显示
                        comboBox1.Items.Add(axMapControl1.Map.Name);//这里将获取到的地图名字,添加到combox1里显示

                    }
                    axMapControl1.Refresh();//刷新一下axMapControl1窗口
                    axMapControl1.Extent = axMapControl1.FullExtent;//将获取到的地图全局显示在axMapControl1中
                }
                else
                {
                    MessageBox.Show("无法打开!" + filePath + "不是有效的文档");//如果文件路径无效,弹出一个文本为"无法打开!" + filePath + "不是有效的文档"的窗口
                }

            }
        }
        #endregion

        #region 下拉框comboBox1读入地图文件中所含的地图名字,且所选图层变化时 读取地图文件 地图信息
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            string filePath = axMapControl1.DocumentFilename;
            int i = comboBox1.SelectedIndex;//将下拉框中已获取的地图引索号,赋予自定义变量 i
            IMapDocument pMapDocument = new MapDocumentClass();
            pMapDocument.Open(filePath,null);
            axMapControl1.Map = pMapDocument.get_Map(i);//按照下拉框中所选择的地图的索引,将索引相对应的地图获取到axMapControl1中
            IMap pMap= axMapControl1.Map;//将当前选择的地图获取到pMap中,以便下面获取图层到ListBox中
            axMapControl1.Extent = axMapControl1.FullExtent;//将地图设置为全空间铺满,这样axMapControl1中在选择相应地图后将会缩放到全控件显示状态
            listBox1.Items.Clear();//在获取新的图层信息前先清空之前的图层信息
            for (int j=0; j <= pMap.LayerCount-1;j++ )
            {
                ILayer pLayer = pMap.get_Layer(j);//获取索引为j的图层
                listBox1.Items.Add(pLayer.Name);//获取当前获取图层的名字添加到ListBox1中
            }
            //第一幅地图中 Kauai and Niihau为栅格地图,所以用UID方法第一个不能完全加载
            bool showtips = pMap.get_Layer(0).ShowTips;//获取第一个图层的显示信息
            textBox1.Text = pMap.get_Layer(0).MaximumScale.ToString();//获取第一个图层的最大比例尺值,转化为String值,并赋予textBox1
            textBox2.Text = pMap.get_Layer(0).MinimumScale.ToString();//获取第一个图层的最小比例尺值,转化为String值,并赋予textBox2
            
            //第一个图层的显示信息的bool值==ture,textBox3.Text显示Yes,否则显示No
            if (showtips.ToString() == "ture")
                textBox3.Text = "Yes";
            else
                textBox3.Text = "No"; ;

        }
        #endregion

        #region button1清空的功能实现
        private void button1_Click(object sender, EventArgs e)//点击button1后,清空所有控件中的信息
        {
            axMapControl1.ClearLayers();
            axMapControl1.Refresh();
            comboBox1.Items.Clear();
            listBox1.Items.Clear();
            textBox1.Clear();
            textBox2.Clear();
            textBox3.Clear();

        }
        #endregion

        #region 在listBox1中所选的图层变化时变化  下面各个textBox的文本显示为相应的值
        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            listBox1.SelectionMode = SelectionMode.One;//设置ListBox1中只能单选
            int i = listBox1.SelectedIndex;//将listBox1中所选择的图层的引索值赋予i,以方便下面读取图层的相关信息(ShowTips,MaximumScale,MinimumScale)
            IMap pMap = axMapControl1.Map;//用IMap创建一个将axMapControl1中的地图,赋予新创建的pMa
            if (i < 0)return;//这里是为了防止异常报错,如果i为-1,即没选择listBox1中的选项(一般此类空值,程序默认设为-1)
            bool ShowTips = pMap.get_Layer(i).ShowTips;
            textBox1.Text = pMap.get_Layer(i).MaximumScale.ToString();
            textBox2.Text = pMap.get_Layer(i).MinimumScale.ToString();
            if (ShowTips.ToString() == "ture")
                textBox3.Text = "Yes";
            else
                textBox3.Text = "No";
            ILayer pLayer = pMap.get_Layer(i);


        }
        #endregion




    }
}
  • 这里还没完,在把所有代码按规矩一个个复制粘贴到对应的函数里后还会有错,这里是为什么呢?查了一下之后,网上大家都说这是因为相应应用集的嵌入互操作类型没设置为false,也就是嵌入互操作类型没设置为true 如下图
    ArcEngine C# GIS开发入门作业 (一) Ex01,Ex02 ——地图、图层加载及属性访问_第6张图片
  • 所以这里需要在引用里设置嵌入互操作,具体为什么后面了解了再作补充,右击属性,设置,嵌入互操作类型为假,我为了图方便统一shift 点开头和结尾的引用都设置了(这里如果一开始创建工程项目的时候如果选的是普通的Windows应用工程项目就不会有ESRI.ArcGIS.——的引用集,需要在应用里右键添加一下相应的应用ESRI.ArcGIS.开头的引用

    ArcEngine C# GIS开发入门作业 (一) Ex01,Ex02 ——地图、图层加载及属性访问_第7张图片
    ArcEngine C# GIS开发入门作业 (一) Ex01,Ex02 ——地图、图层加载及属性访问_第8张图片
    然后错误应该就没有了,就成功完成了资料中的作业EX02还有错误可以留言。之后还会接着继续更接下来的作业,之后可能一年都不会再更了,欢迎大家发现上面的错误,后面我会改的,感谢!

你可能感兴趣的:(学习过程,AE,C#开发,ArcEngine,C#,地图加载,入门,访问图层属性)