1. 程式人生 > >ArcEngine10.2設計與開發課程學習(作業一)——地圖、圖層載入及屬性訪問

ArcEngine10.2設計與開發課程學習(作業一)——地圖、圖層載入及屬性訪問

先說一句,我是新手,剛註冊的CSDN,剛學的C#和engine,剛寫的文章。下面的程式碼質量肯定是經不住的,慢慢來,相信有很多和我一樣的未入門級的同胞,沒事的,都是這麼一竅不通過來的啦,我也是斷斷續續折騰了好幾天搞出來的。踩了賊多坑,也都是很**的坑,建議還是瞭解一下控制元件和類的功能實現原理等等,那樣捋的舒服點,不然這裡搬一點那裡搬一點不怎麼好整,寫別的程式碼也一樣吧,都是從看程式碼到模仿的。

剛開始學AE開發(剛開課的純小白),所以自然會遇到無語多的問題,網上搜索到一些資料,還有一些前輩們的部落格文章,當然也有書本的,很想收藏但是太多不便於管理,而且都是零散的組合才能達到我做作業的目的(好吧,暴露了,我是以做課堂作業的形式學的,所以肯定很片面了,哈哈),好了好了,步入正題,第一次寫有點緊張,多多多多指教。



首先是第一部分安裝和配置了,對應的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我也都有,有需要可以留言。安裝和配置完按照結尾步驟生成一個窗體瞧瞧,相信大家就迫不及待的開啟窗體想開始幹活了。

首先大家最好設定一下螢幕解析度100%,不然窗體會亂彪,大小定不下來,這個我也是是問老師才知道的。


首先是關於介面,個人習慣,然後就是button等等這個c#基本的控制元件,如下圖,控制元件的分類什麼和基本用法的自己可以去搜索一下,簡單來說就是一個屬性和一個事件。屬性就是空間在基本的顯示效果、在窗體中的位置和一些基本功能的設定,是不需要編寫程式碼的;事件則是觸發之後執行相關操作,如按鈕點選、滑鼠移動、下拉選擇等等,選擇控制元件右擊屬性,右側屬性窗格中一個閃電標誌,就可以點進去寫程式碼了,函式體什麼的它都會幫你生成後,淡然也可以按自己需求改動。

工具箱


進去正題,首先新增控制元件進去,依次將MapControl、LicenseControl拖入窗體(窗體的大小可以自行拉伸),然後program.cs加入下列程式碼:

using ESRI.ArcGIS;
using ESRI.ArcGIS.Carto;
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());
        }


然後這裡可以先在引用裡設定嵌入互操作,具體為什麼後面瞭解了再作補充,右擊屬性,設定

嵌入互操作型別為 False,我為了圖方便統一都設定了。

嵌入互操作設定


然後按題目要求把相關控制元件直接拖進去,在屬性裡設定好文字啊之類的,這裡只用到了lable、button、combox、textbox(有一個屬性MultLine可以設定是否為多列文字)、因為這裡只供顯示,所以我有設定了readonly型別,只讀。控制元件按鈕什麼的也可以做的好看,圖表啊字型什麼的,有興趣的可以自己整。

介面設定


下一步就是設定地圖了,雙擊LoadMxd進入程式碼區,因為我做的這個題目是點選載入地圖(也可以在事件中進入),所以選擇了這個事件。

第一步是地圖的載入,我參考了教材和這位前輩的文章,還是很詳細的,但是我只用到了部分https://blog.csdn.net/weiwanshu/article/details/49784019,可以先看看這個。載入mxd的三種方法:
1. 使用IMapControl介面的LoadMxFile 載入地圖
2. 通過IMapDocument 介面載入
3. 使用ArcGIS Engine 中封裝好的ConstrolsOpenCommandClass

我推薦使用第一種,感覺好些,而且可以自己選擇檔案。我這裡也只列出第一種方法實現的程式碼

我載入地圖的程式碼如下:(別看一坨,很多都是我加了解釋,畢竟我小白弄不很清楚,不過保證都是我手打手敲的hh慢慢磨)

       private void btn1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openfiledialog = new OpenFileDialog();
            openfiledialog.Title = "開啟地圖文件檔案";
            openfiledialog.Filter = "地圖文件 (*.mxd)|*.mxd";
            if (openfiledialog.ShowDialog() == DialogResult.OK)   //檢查地圖文件有效性
            {
                string filePath = openfiledialog.FileName;//獲取檔案地址
                
                if (axMapControl1.CheckMxFile(filePath))      
                 //  CheckMxFile用來判斷地址是否有效 
                {
                    axMapControl1.LoadMxFile(filePath, 0, Type.Missing);
                    //使用axMapControl來載入mxd地圖文件,下面的程式碼是依次訪問各個地圖並將地圖            
                  名寫入combox.item中去

                    IMapDocument pMapDocument = new MapDocumentClass();
                    pMapDocument.Open(filePath, null);
                   //這裡也可以直接連線到當前地圖,我這裡是借用了之前寫的程式碼,重新載入了檔案, 
                   後續有時間改改
                    for (int i = 0; i < pMapDocument.MapCount; i++)//依次訪問地圖
                    {
                        axMapControl1.Map = pMapDocument.get_Map(i);                        
                        comboBox1.Items.Add(axMapControl1.Map.Name);
                    }//新增
                    axMapControl1.Refresh();    //可選,重新整理
                    axMapControl1.Extent = axMapControl1.FullExtent;    //全域性顯示
                }
                else
                {
                    MessageBox.Show("無法開啟!" + filePath + "不是有效的地圖文件");
                }//在窗體中不用Console.write(),一般是通過MessageBox.Show()彈窗顯示,也可以 
             用來作簡單的除錯什麼的,具體的除錯當然還是執行過程中間變數。
 
            }            
        }

到了這裡可以執行試試看了哈哈,要是各種報錯我就沒辦法一一列出了,不過完全不要灰心,我也是在經歷了n次百度各種錯誤解決,猜坑嘛,踩多了就好。

然後就是下拉選擇了,下拉框有一個SelectChange的事件,點進去開始編寫,因為我一開始沒注意到地圖裡有一個柵格檔案,所以按照書本《ArcGIS應用於開發》,學校的教材(有需要可以發PDF),很薄的,在p31面,按照順序模仿敲好可以顯示。

我才用的是較為方便直接的索引,有興趣的可以嘗試value值改變,下面是我的程式碼。

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            string filePath = axMapControl1.DocumentFilename;
            int i = comboBox1.SelectedIndex;    //存下拉選擇框的索引

            IMapDocument pMapDocument = new MapDocumentClass();
            pMapDocument.Open(filePath, null);
            axMapControl1.Map = pMapDocument.get_Map(i);//按照選擇的索引獲取響應的map

            IMap pMap = axMapControl1.Map;//載入當前選擇地圖
            axMapControl1.Extent = axMapControl1.FullExtent;    //全域性顯示

            textBox1.Clear();//每次選擇肯定要清空原來的文字啊

            /*讀取地圖中的圖層資訊,這是註釋掉了,舊方法
            UID id = new UIDClass();
            id.Value = "{40A9E885-5533-11d0-98BE-00805F7CED21}";//FeatureLayer
            IEnumLayer pLayers = pMap.get_Layers(id, false);
            pLayers.Reset();*/

            for (int j=0; j<pMap.LayerCount; j++)
            {
                ILayer layer = pMap.get_Layer(j);
                textBox1.Text += layer.Name;
                textBox1.Text += "\r\n";
            }//按理來說是應該有方法可以lines字串直接賦值寫入的吧,但是我只會手動加換行haha,            
           筆者很菜, 求指導
            //第一幅地圖中 Kauai and Niihau為柵格地圖,所以用UID方法將第一個不能完全載入
            
            bool showtips = pMap.get_Layer(0).ShowTips;
            textBox2.Text = pMap.get_Layer(0).MaximumScale.ToString();
            textBox3.Text = pMap.get_Layer(0).MinimumScale.ToString();
            textBox4.Text = showtips.ToString();
//這裡就是下面文字框的的資訊顯示了,只有第一個圖有資訊,我也不知道為啥,湊合用吧,以後會了再回來改
        }

馬上大功告成,可把我激動死了,視窗顯示出來了,還能選擇,一個close把我難住了,找了半天沒有找到關閉的函式,就找到一個clearlayer()能用,就用它了,但是清除完還得記得把下拉框、文字框裡的東西儲存的東西清除掉,對了,我對自己的按鈕和文字框有些可能改了text,但是應該不影響。


        //清除圖層及顯示的所有資訊
        private void btn2_Click(object sender, EventArgs e)
        {
            axMapControl1.ClearLayers();
            axMapControl1.Refresh();
            comboBox1.Items.Clear();
            textBox1.Clear();
            textBox2.Clear();
            textBox3.Clear();
            textBox4.Clear();
        }

這個就沒什麼好解釋的了,我對所有程式碼也就是這個樣子的,我這裡能正常工作,作為我的的第一個窗體作業可以說灰常興奮了哈哈。祝好運。要趕緊做下個作業了,老師催的賊緊。朋友們可以關注一起學習啊,有老師指點就更棒了。