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 );
文件地理數據庫(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);
ArSDE(Spatial Database Engine空間數據庫引擎)是在現有的關型數據庫上進行的空間擴展,它使空間數據能保存在關係數據庫中(如oracle,sqlserver中)ArcSDE空間數據庫的一個重要的特色就是支持多用戶併發操做,而且能夠經過版原本表現空間數據編輯的狀態。當完成數據編輯後,可將多人的編輯狀態進行版版本合併,若多個用戶對同一個要素進行了編輯,且編輯的狀態不同,將會出現「版本衝突」,提示用戶採用哪一版本的數據。版本最後肯定取決於用戶對於數據管理的權限。
一、ArcSDE的組成
由ArcSDE服務管理進程、專用服務器進程、ArcSDE客戶端三部分組成。
ArcSDE服務器管理進程負責維護ArcSDE和監聽來自客戶端的連接請求。ARCSDE啓動就是ArcSDE服務器管理進程,利用管理員帳戶管理ArcSDE與RDBMS的鏈接,處理客戶端的鏈接請求。
專用服務器進程由ArcSDE服務器管理進程建立,用於每個特定的客戶端應用程序與數據庫的鏈接。
ArcSDE客戶端經過ArcSDE服務器管理進程和專用服務器進程創建和RDBMS的鏈接,實現對數據庫的操做。
2、ArcSDE數據庫的鏈接方式
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 }
總結: 由上述ArcGIS Engine加載幾種經常使用的數據源的方法,能夠看出ArcGIS Engine加載空間數據通常具備如下的五個步驟:
1)建立數據對應的工做空間工廠(WorkspaceFactory)。
2)使用WorkspaceFactory建立要加載數據的工做空間Workspace。
3)使用Workspace打開並獲得圖層的數據集。
4)強Dataset賦值給新建圖層的數據源。
5)添加圖層到MapControl中進行顯示。