ArcGIS Engine開發之地圖基本操作(4)


ArcGIS Engine開發中數據庫的加載

1、加載個人地理數據庫數據

個人地理數據庫(Personal Geodatabase)使用Miscrosoft Access文件(*.mdb)進行空間數據的存儲和管理,它將不同的數據統一納入Access文件中,便於數據的管理與遷移,容量限制為2GB。個人地理數據庫支持單用戶編輯,不支持版本管理。在進行ArcGIS軟件操作和開發的學習過程中,一般建議采用個人地理數據庫進行數據的 組織和存儲,同時也便於直接導到ArcSDE空間數據庫中。加載個人地理數據庫的用到的接口為:IFeatureDataset、IEnumDataset。

1.IFeatureDataset接口:繼承自IDataset接口,在其基礎上增加一個 創建要素類的功能CreateFeatureClass。

2.IEnumDataset接口:用於訪問個人地理數據庫中的所有數據集成員,有Reset和Next兩個方法。Reset方法重置數據集序列,使指針位於第一個數據集之前;Next方法獲取枚舉序列的 下一個數據集。

實現的思路:

1)床架AccessWorkspaceFactory類的實例。

2)用IWorkspaceFactory接口的OpenFromFile方法打開.mdb數據集的工作空間,對工作空間里面的數據進行加載。

 

代碼1:對加載數據庫的方法進行函數封裝

 #region
        //封裝加載空間數據庫方法:AddAllDataset函數,以便對其他空間數據庫加載時直接調用。
        private void AddAllDataset(IWorkspace pWorkspace, AxMapControl mapControl)
        {
            IEnumDataset pEnumDataset = pWorkspace.get_Datasets(ESRI.ArcGIS.Geodatabase.esriDatasetType.esriDTAny);
            pEnumDataset.Reset();
            //將Enum數據集集中的數據一個一個地讀到dataset 中
            IDataset pDataset = pEnumDataset.Next();
            //判斷數據集是否有數據
            while (pDataset != null)
            {
                if (pDataset is IFeatureDataset)//要素數據集
                {
                    IFeatureWorkspace pFeatureWorkspac = (IFeatureWorkspace)pWorkspace;
                    IFeatureDataset pFeatureDataset = pFeatureWorkspac.OpenFeatureDataset(pDataset.Name);
                    IEnumDataset pEnumDataset1 = pFeatureDataset.Subsets;
                    pEnumDataset1.Reset();
                    IGroupLayer pGroupLayer = new GroupLayerClass();
                    pGroupLayer.Name = pFeatureDataset.Name;
                    IDataset pDataset1 = pEnumDataset1.Next();
                    while (pDataset1 != null)
                    {
                        if (pDataset1 is IFeatureClass)//要素類
                        {
                            IFeatureLayer pFeatureLayer = new FeatureLayerClass();
                            pFeatureLayer.FeatureClass = pFeatureWorkspac.OpenFeatureClass(pDataset1.Name);
                            if (pFeatureLayer.FeatureClass != null)
                            {
                                pFeatureLayer.Name = pFeatureLayer.FeatureClass.AliasName;
                                pGroupLayer.Add(pFeatureLayer);
                                mapControl.Map.AddLayer(pFeatureLayer);
                            }
                        }
                        pDataset1 = pEnumDataset1.Next();
                    }
                }
                else if (pDataset is IFeatureClass)//要素類
                {
                    IFeatureWorkspace pFeatureWorkspace = (IFeatureWorkspace)pWorkspace;
                    IFeatureLayer pFeatureLayer = new FeatureLayerClass();
                    pFeatureLayer.FeatureClass = pFeatureWorkspace.OpenFeatureClass(pDataset.Name);
                    pFeatureLayer.Name = pFeatureLayer.FeatureClass.AliasName;
                    mapControl.Map.AddLayer(pFeatureLayer);
                }
                else if (pDataset is IRasterDataset)//柵格數據
                {
                    IRasterWorkspaceEx pRasterWorkspace = (IRasterWorkspaceEx)pWorkspace;
                    IRasterDataset pRasterDataset = pRasterWorkspace.OpenRasterDataset(pDataset.Name);
                    //影像金字塔的判斷和創建
                    IRasterPyramid3 pRasterPyramid;
                    pRasterPyramid = pRasterDataset as IRasterPyramid3;
                    if (pRasterPyramid != null)
                    {
                        if (!(pRasterPyramid.Present))
                        {
                            pRasterPyramid.Create();//創建金字塔
                        }
                    }
                    IRasterLayer pRasterLayer = new RasterLayerClass();
                    pRasterLayer.CreateFromDataset(pRasterDataset);
                    ILayer pLayer = pRasterLayer as ILayer;//進行繼承
                    mapControl.AddLayer(pLayer, 0);
                }
                pDataset = pEnumDataset.Next();
            }
            mapControl.ActiveView.Refresh();
            //同步鷹眼
            // SynchronizeEagleEye();
        }
        #endregion

代碼2:調用個人地理數據庫

  ////加載個人地理數據庫
            OpenFileDialog pOpenFileDialog = new OpenFileDialog();
            pOpenFileDialog .Title ="打開PersonGeoDatabase文件";
            pOpenFileDialog.Filter = "Personal GeoDatabase(*.mdb)|*.mdb";
            pOpenFileDialog.ShowDialog();
            string pFullPath = pOpenFileDialog.FileName;
            if (pFullPath == "") return;
            AccessWorkspaceFactory pAccessWorkspaceFactory = new AccessWorkspaceFactoryClass();
            //獲取工作空間
            IWorkspace pWorkspace = pAccessWorkspaceFactory.OpenFromFile(pFullPath ,0);
            ClearAllData();
            AddAllDataset(pWorkspace,mainMapControl );

2.加載文件地理數據庫

文件地理數據庫(File GeoDatabase)是以文件夾形式存儲各種類型的GIS數據集,可以存儲查詢和管理空間數據和非空間數據,支持地理數據庫的大小為1TB,在不使用數據庫管理系統的情況下能夠擴展並存儲大量的數據,是繼個人地理數據庫之后esr推出的新的數據管理系統。文件地理數據庫支持單用戶編輯,不支版本管理。

實現的思路:

1)由於文件地理數據庫是以文件夾的形式存在的,因此可以使用FolderBrowserDialog選擇文件夾進行加載。首先創建FileGDBWorkspaceFactoryClass類的實例。

2)使用IWorkspaceFactory接口的OpenFromFile方法打開文件地理數據庫的工作空間,對工作空間中的文件夾進行加載。

////加載文件地理數據庫數據
            FolderBrowserDialog dlg = new System.Windows.Forms.FolderBrowserDialog();
            if(dlg.ShowDialog ()!=DialogResult .OK ) return ;
            string pFullth=dlg.SelectedPath ;
            if(pFullth =="") return ;
            //使用esri.arcgis.DataSourseGDB
            FileGDBWorkspaceFactory pFileGDBWorkspaceFactory=new FileGDBWorkspaceFactoryClass();
            ClearAllData ();
            //獲取工作空間
            IWorkspace pWorkspac=pFileGDBWorkspaceFactory .OpenFromFile (pFullth ,0);
            AddAllDataset (pWorkspac,mainMapControl);

3.加載ARCSDE空間數據庫數據

ArSDE(Spatial Database Engine空間數據庫引擎)是在現有的關型數據庫上進行的空間擴展,它使空間數據能保存在關系數據庫中(如oracle,sqlserver中)ArcSDE空間數據庫的一個重要的特點就是支持多用戶並發操作,並且可以通過版本來表現空間數據編輯的狀態。當完成數據編輯后,可將多人的編輯狀態進行版版本合並,若多個用戶對同一個要素進行了編輯,且編輯的狀態不一樣,將會出現“版本沖突”,提示用戶采用哪一版本的數據。版本最后確定取決於用戶對於數據管理的權限。

1、ArcSDE的組成

由ArcSDE服務管理進程、專用服務器進程、ArcSDE客戶端三部分組成。

ArcSDE服務器管理進程負責維護ArcSDE和監聽來自客戶端的鏈接請求。ARCSDE啟動就是ArcSDE服務器管理進程,利用管理員賬戶管理ArcSDE與RDBMS的連接,處理客戶端的連接請求。

專用服務器進程由ArcSDE服務器管理進程創建,用於每一個特定的客戶端應用程序與數據庫的連接。

ArcSDE客戶端通過ArcSDE服務器管理進程和專用服務器進程建立和RDBMS的連接,實現對數據庫的操作。

2ArcSDE數據庫的連接方式

ArcSDE提供了應用服務器連接和直接連接兩種連接方式。當服務器性能較好時可采用應用服務器連接,否則采用直接連接,為了減輕服務器的壓力,建議采用直接連接的方式進行連接。

應用服務器連接和直接連接的主要區別是屬性參數的設置不同:

1)應用服務器連接參數的設置

服務器(Server):SDE服務器的主機名稱。

數據庫實例(Instance):安裝SDE時選擇的端口,默認為5151或esri_sde。

數據庫(DataBase).根據不同的DBMS決定是否填寫。Oracle系列不用填,而SQlServer需要填寫。

用戶名(Usename):需要填寫

密碼(Password):需要填寫。

2)直接連接的參數設置

服務器(Server):不用填寫

數據庫實例(Instance):SDE數據類型,例如:如果是Oracle 11g,則為SDE:Oracle:11g:Orcl。其中orcl為數據庫的服務名。

數據庫(Database):根據不同的DBMS決定是否填寫。

用戶名(Username):需要填寫

密碼(password):需要填寫

3)兩種連接方式的異同

直接連接就是通過ArcSDE訪問數據庫,並在本地完成對數據庫的各種操作(如空間分析、編輯等):而應用服務器連接就是通過ARCSDE訪問數據表后,在服務器端完成對數據的各種操作,再把操作結果返回客戶端。因此,即便服務器上SDE服務沒有啟動,采用直接連接的方式也可以直接訪問和操作SED數據庫,而應用服務器連接只有在SDE服務器啟動后才能訪問和操作SDE數據庫。

SDE 數據庫的加載主要用到IPropertySet接口。屬性幾何(PropertySet)對象是一個專門用於設置屬性的對象,它是一種【名稱】——【值】對應的集合,類似於哈希表或字典。

4)實例程序的思路:

① 創建SdeWorkspaceFactoryClas類的實例。

②通過SDE連接的連接屬性打開SDE數據庫的工作空間,對工作空間里面的數據進行加載。

 private void btnFileDatabase_ItemClick(object sender, ItemClickEventArgs e)
        {
            ////加載文件地理數據庫數據
            FolderBrowserDialog dlg = new System.Windows.Forms.FolderBrowserDialog();
            if (dlg.ShowDialog() != DialogResult.OK) return;
            string pFullth = dlg.SelectedPath;
            if (pFullth == "") return;
            //使用esri.arcgis.DataSourseGDB
            FileGDBWorkspaceFactory pFileGDBWorkspaceFactory = new FileGDBWorkspaceFactoryClass();
            ClearAllData();
            //獲取工作空間
            IWorkspace pWorkspac = pFileGDBWorkspaceFactory.OpenFromFile(pFullth, 0);
            AddAllDataset(pWorkspac, mainMapControl);
        }
        /// <summary>
        /// 服務器連接,以Oracle數據庫為例
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnaddSDEByServer_ItemClick(object sender, ItemClickEventArgs e)
        {
            IWorkspace pWorkspace;
            pWorkspace = arcSDEWorkspaceOpen("192.168.70.110", "esri_sde", "sde", "sde", "", "SDE.DEFAULT");//調用定義的函數

        }
        /// <summary>
        /// 定義函數arcSDEWorkspaceOpen(),用於連接數據庫
        /// </summary>
        /// <returns></returns>

        private IWorkspace arcSDEWorkspaceOpen(string server, string instance, string user, string password, string database, string version)
        {
            IWorkspace pWorkSpace = null;
            //創建和實例化數據集
            IPropertySet pPropertySet = new PropertySetClass();
            pPropertySet.SetProperty("SERVER", server);
            pPropertySet.SetProperty("SERVER", server);
            pPropertySet.SetProperty("INSTANCE", instance);
            pPropertySet.SetProperty("USER", user);
            pPropertySet.SetProperty("PASSWORD", password);
            pPropertySet.SetProperty("DATABASE", database);
            pPropertySet.SetProperty("VERSION", version);
            IWorkspaceFactory2 pWorkspaceFactory = new SdeWorkspaceFactoryClass();

            try
            {
                pWorkSpace = pWorkspaceFactory.Open(pPropertySet, 0);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            return pWorkSpace;
        }
        /// <summary>
        /// 直接連接數據庫
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnaddSDEByDriect_ItemClick(object sender, ItemClickEventArgs e)
        {
            IWorkspace pWorkspace;
            pWorkspace = arcSDEWorkspaceOpen("", "sde:oracle11g:orcl", "sde", "sde", "", "SDE.DEFAULT");
            //如果工作空間不為空,則進行加載
            if (pWorkspace != null)
            {
                AddAllDataset(pWorkspace, mainMapControl);
            }

        }

 


 

四、加載文本文件數據

野外測量的數據是GIS數據的一個主要來源,如GPS、全站儀等儀器測量的數據等,這類數據通常為含有X/Y坐標的Excel文件或者文本文件。

實現的思路:

1)根據Excel或者.txt文件等獲取點的坐標信息。

2)根據點的坐標創建ShapeFile圖層。

3)加載該shapefile圖層。

具體代碼:

  1     
  2         /// <summary>
  3         /// 進行函數的聲明,調用AxControl控件
  4         /// </summary>
  5         /// 定義函數,並返回值
  6         private AxMapControl buddyMap;
  7         public AxMapControl BuddyMap
  8         {
  9             get { return buddyMap; }
 10             set { buddyMap = value; }
 11         }
 12 
 13         /// <summary>
 14         /// 創建一個點結構,進行點信息的存儲
 15         /// </summary>
 16         struct CPoint
 17         {
 18             public string Name;
 19             public double X;
 20             public double Y;
 21         }
 22         /// <summary>
 23         /// 定義全局變量的數組pColumns用來存儲點數據
 24         /// </summary>
 25         List<string> pColumns = new List<string>();
 26 
 27  
 28         public FormAddtxtData()
 29         {
 30             InitializeComponent();
 31         }
 32 
 33         private void FormAddtxtData_Load(object sender, EventArgs e)
 34         {
 35 
 36         }
 37         /// <summary>
 38         /// 打開文本格式文件
 39         /// </summary>
 40         /// <param name="sender"></param>
 41         /// <param name="e"></param>
 42         private void btnOpen_Click(object sender, EventArgs e)
 43         {
 44             OpenFileDialog pOpenFileDialog = new OpenFileDialog();
 45             pOpenFileDialog.Title = "打開測量數據文件";
 46             pOpenFileDialog.Filter = "測量坐標文件(*.txt)|*.txt";
 47             if (pOpenFileDialog.ShowDialog() == DialogResult.OK)
 48             {
 49                 txtSource.Text = pOpenFileDialog.FileName;//獲取顯示文件名
 50             }
 51         }
 52         /// <summary>
 53         /// 將文本格式保存成shape格式,調用刺痛保存文本的函數
 54         /// </summary>
 55         /// <param name="sender"></param>
 56         /// <param name="e"></param>
 57         private void btnSave_Click(object sender, EventArgs e)
 58         {
 59             SaveFileDialog pSaveFileDialog = new SaveFileDialog();
 60             pSaveFileDialog.Filter = "Shape 文件(*.shp)|*.shp";
 61             if (File.Exists(txtSource.Text))
 62             {
 63                 pSaveFileDialog.FileName = System.IO.Path.GetFileNameWithoutExtension(txtSource.Text);//返回不具有返回值的指定路徑的文件名
 64             }
 65             if (pSaveFileDialog.ShowDialog() == DialogResult.OK)
 66             {
 67                 txtSave.Text = pSaveFileDialog.FileName;
 68             }
 69 
 70         }
 71         /// <summary>
 72         /// 創建並實例化一個CPoint類型的數組,將所有的點信息進行 存儲
 73         /// </summary>
 74         /// <param name="surveyDataFullName"></param>
 75         /// <returns></returns>
 76         private List<CPoint> GetPoints(string surveyDataFullName)
 77         {
 78             try
 79             {
 80                 List<CPoint> pList = new List<CPoint>();
 81                 char[] charArray = new char[] { ',', ' ', '\t' };   //常用的分隔符為逗號、空格、制位符
 82                 //文本信息讀取
 83                 FileStream fs = new FileStream(surveyDataFullName, FileMode.Open);
 84                 StreamReader sr = new StreamReader(fs, Encoding.Default);
 85                 string strLine = sr.ReadLine();
 86                 if (strLine != null)
 87                 {
 88                     string[] strArray = strLine.Split(charArray);
 89                     if (strArray.Length > 0)
 90                     {
 91                         for (int i = 0; i < strArray.Length; i++)
 92                         {
 93                             pColumns.Add(strArray[i]);
 94                         }
 95                     }
 96 
 97                     while ((strLine= sr.ReadLine())!=null)
 98                     {
 99                         //點信息的讀取
100                         strArray = strLine.Split(charArray);
101                         CPoint pCPoint = new CPoint();
102                         pCPoint.Name = strArray[0].Trim();
103                         pCPoint.X = Convert.ToDouble(strArray[1]);
104                         pCPoint.Y = Convert.ToDouble(strArray[2]);
105                     
106                         pList.Add(pCPoint);
107                     }
108                 }
109                 else
110                 {
111                     return null;
112                 }
113                 sr.Close();
114                 return pList;
115             }
116             catch (Exception ex)
117             {
118                 MessageBox.Show(ex.Message);
119                 return null;
120             }
121         }
122         /// <summary>
123         /// 封裝函數,根據點坐標進行創建shapefile圖層
124         /// </summary>
125         /// <param name="cPointList"></param>
126         /// <param name="filePath"></param>
127         /// <returns></returns>
128         private IFeatureLayer CreateShpFromPoints(List<CPoint> cPointList, string filePath)
129         {
130             int index = filePath.LastIndexOf('\\');
131             string folder = filePath.Substring(0, index);
132             string shapeName = filePath.Substring(index + 1);  
133             IWorkspaceFactory pWSF = new ShapefileWorkspaceFactoryClass();
134             IFeatureWorkspace pFWS = (IFeatureWorkspace)pWSF.OpenFromFile(folder, 0);
135 
136             IFields pFields = new FieldsClass();
137             IFieldsEdit pFieldsEdit;
138             pFieldsEdit = (IFieldsEdit)pFields;
139 
140             IField pField = new FieldClass();
141             IFieldEdit pFieldEdit = (IFieldEdit)pField;
142             pFieldEdit.Name_2 = "Shape";
143             pFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
144             IGeometryDef pGeometryDef = new GeometryDefClass();
145             IGeometryDefEdit pGDefEdit = (IGeometryDefEdit)pGeometryDef;
146             pGDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPoint;
147             //定義坐標系
148             ISpatialReferenceFactory pSRF = new SpatialReferenceEnvironmentClass();
149             ISpatialReference pSpatialReference = pSRF.CreateGeographicCoordinateSystem((int)esriSRGeoCSType.esriSRGeoCS_Beijing1954);
150             pGDefEdit.SpatialReference_2 = pSpatialReference;
151 
152             pFieldEdit.GeometryDef_2 = pGeometryDef;
153             pFieldsEdit.AddField(pField);
154            
155             IFeatureClass pFeatureClass;
156             pFeatureClass = pFWS.CreateFeatureClass(shapeName, pFields, null, null, esriFeatureType.esriFTSimple, "Shape", "");
157 
158             IPoint pPoint = new PointClass();
159             for (int j = 0; j < cPointList.Count; j++)
160             {
161                 pPoint.X = cPointList[j].X;
162                 pPoint.Y = cPointList[j].Y;
163 
164                 IFeature pFeature = pFeatureClass.CreateFeature();
165                 pFeature.Shape = pPoint;
166                 pFeature.Store();
167             }
168             
169             IFeatureLayer pFeatureLayer = new FeatureLayerClass();
170             pFeatureLayer.Name = shapeName;
171             pFeatureLayer.FeatureClass = pFeatureClass;
172             return pFeatureLayer;
173         }
174        /// <summary>
175        /// 定義一個函數進行驗證數據和存儲位置是否有效
176        /// </summary>
177        /// <returns></returns>
178         private bool ValidateTxtbox()
179         {
180             if (txtSource.Text == "" || !File.Exists(txtSource.Text))
181             {
182                 MessageBox.Show("測量數據無效,請重新選擇!", "提示", MessageBoxButtons.OK);
183                 return false;
184             }
185             if (txtSave.Text == "" || System.IO.Path.GetExtension(txtSave.Text).ToLower() != ".shp")
186             {
187                 MessageBox.Show("保存路徑無效,請重新選擇!", "提示", MessageBoxButtons.OK);
188                 return false;
189             }
190             return true;
191         }
192         /// <summary>
193         /// 調用函數,將生成的shape文件加載到mapControl中
194         /// 
195         /// </summary>
196         /// <param name="sender"></param>
197         /// <param name="e"></param>
198         private void btnCreat_Click(object sender, EventArgs e)
199         {
200             if (ValidateTxtbox())
201             {
202                 List<CPoint> pCPointList = GetPoints(txtSource.Text);
203                 if (pCPointList == null)
204                 {
205                     MessageBox.Show("所選擇的文件為空,請重新選擇!");
206                 }
207                 else
208                 {
209                     //實例化要素圖層,進行添加
210                     IFeatureLayer pFeatureLayer = CreateShpFromPoints(pCPointList, txtSave.Text);//傳入實參數據
211                     buddyMap.Map.AddLayer(pFeatureLayer);
212                     this.Close();
213                 }
214             }
215 
216         }
217 
218         private void btnCancel_Click(object sender, EventArgs e)
219         {
220              this.Close();
221         }
222     }
View Code

總結: 由上述ArcGIS Engine加載幾種常用的數據源的方法,可以看出ArcGIS Engine加載空間數據一般具有以下的五個步驟:

1)創建數據對應的工作空間工廠(WorkspaceFactory)。

2)使用WorkspaceFactory創建要加載數據的工作空間Workspace。

3)使用Workspace打開並得到圖層的數據集。

4)強Dataset賦值給新建圖層的數據源。

5)添加圖層到MapControl中進行顯示。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM