• 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[] { ',', ' ', '	' };   //常用的分隔符为逗号、空格、制位符
     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中进行显示。

  • 相关阅读:
    VBS进程判断
    [转]Myeclipse的使用方法格式化源代码
    Stay hungry,stay foolish
    【转】tomcat 设置 session 过期时间
    【转】Java编码转换问题,new String(str.getByts("ISO88591"), "GBK")的作用
    【转】VBS CHR码值对应列表
    【转】 从MS SQL Server 2000升级到MS SQL Server 2005方法
    【转】SqlServer中decimal(numeric )、float 和 real 数据类型的区别
    html radio
    a标签点击状态
  • 原文地址:https://www.cnblogs.com/dongteng/p/5878656.html
Copyright © 2020-2023  润新知