ArcGIS Engine开发之地图基本操作(4)

您所在的位置:网站首页 如何添加数据分析库文件 ArcGIS Engine开发之地图基本操作(4)

ArcGIS Engine开发之地图基本操作(4)

2024-07-17 15:14| 来源: 网络整理| 查看: 265

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的连接,实现对数据库的操作。

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); } /// /// 服务器连接,以Oracle数据库为例 /// /// /// private void btnaddSDEByServer_ItemClick(object sender, ItemClickEventArgs e) { IWorkspace pWorkspace; pWorkspace = arcSDEWorkspaceOpen("192.168.70.110", "esri_sde", "sde", "sde", "", "SDE.DEFAULT");//调用定义的函数 } /// /// 定义函数arcSDEWorkspaceOpen(),用于连接数据库 /// /// 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; } /// /// 直接连接数据库 /// /// /// 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 /// 3 /// 进行函数的声明,调用AxControl控件 4 /// 5 /// 定义函数,并返回值 6 private AxMapControl buddyMap; 7 public AxMapControl BuddyMap 8 { 9 get { return buddyMap; } 10 set { buddyMap = value; } 11 } 12 13 /// 14 /// 创建一个点结构,进行点信息的存储 15 /// 16 struct CPoint 17 { 18 public string Name; 19 public double X; 20 public double Y; 21 } 22 /// 23 /// 定义全局变量的数组pColumns用来存储点数据 24 /// 25 List pColumns = new List(); 26 27 28 public FormAddtxtData() 29 { 30 InitializeComponent(); 31 } 32 33 private void FormAddtxtData_Load(object sender, EventArgs e) 34 { 35 36 } 37 /// 38 /// 打开文本格式文件 39 /// 40 /// 41 /// 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 /// 53 /// 将文本格式保存成shape格式,调用刺痛保存文本的函数 54 /// 55 /// 56 /// 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 /// 72 /// 创建并实例化一个CPoint类型的数组,将所有的点信息进行 存储 73 /// 74 /// 75 /// 76 private List GetPoints(string surveyDataFullName) 77 { 78 try 79 { 80 List pList = new List(); 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 /// 123 /// 封装函数,根据点坐标进行创建shapefile图层 124 /// 125 /// 126 /// 127 /// 128 private IFeatureLayer CreateShpFromPoints(List 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 /// 175 /// 定义一个函数进行验证数据和存储位置是否有效 176 /// 177 /// 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 /// 193 /// 调用函数,将生成的shape文件加载到mapControl中 194 /// 195 /// 196 /// 197 /// 198 private void btnCreat_Click(object sender, EventArgs e) 199 { 200 if (ValidateTxtbox()) 201 { 202 List 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中进行显示。



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3