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

ArcGIS Engine開發中數據庫的加載sql

一、加載我的地理數據庫數據

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

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

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

實現的思路:併發

1)牀架AccessWorkspaceFactory類的實例。oracle

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

 

代碼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:調用我的地理數據庫sqlserver

  ////加載我的地理數據庫
            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空間數據庫的一個重要的特色就是支持多用戶併發操做,而且能夠經過版原本表現空間數據編輯的狀態。當完成數據編輯後,可將多人的編輯狀態進行版版本合併,若多個用戶對同一個要素進行了編輯,且編輯的狀態不同,將會出現「版本衝突」,提示用戶採用哪一版本的數據。版本最後肯定取決於用戶對於數據管理的權限。

一、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);
            }

        }

 


 

4、加載文本文件數據

野外測量的數據是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中進行顯示。

相關文章
相關標籤/搜索