数据加载是 ArcGIS Engine 中最基础的操作,AE 支持的数据广泛,包含矢量数据、栅格数据、CAD 数据、Excel数据等等,这些数据的加载有助于我们使用 AE 做进一步的数据处理与分析。
加载地图文档
地图文档可以是一个ArcMap文档(*.mxd)或者ArcMap模版(*.mxt)或ArcReader文件(*.pmf)。
加载地图文档的方式有三种:
- 使用 IMapControl 接口的 LoadMxFile 方法加载;
 
 
- 通过 IMapDocument 接口加载;
 
 
- 使用 ArcGIS Engine 中封装好的类库资源 ControlsOpenDocCommandClass 加载。
 
 
LoadMxFile 方法加载地图文档文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
   | private void BtnLoadMxFile_Click(object sender, EventArgs e) {          try     {         OpenFileDialog pOpenFileDialog = new OpenFileDialog();         pOpenFileDialog.CheckFileExists = true;         pOpenFileDialog.Title = "打开地图文档";         pOpenFileDialog.Filter = "ArcMap文档(*.mxd)|*.mxd;|ArcMap模板(*.mxt)|*.mxt|发布地图文件(*.pmf)|*.pmf|所有地图格式(*.mxd;*.mxt;*.pmf)|*.mxd;*.mxt;*.pmf";         pOpenFileDialog.Multiselect = false;            pOpenFileDialog.RestoreDirectory = true;            if (pOpenFileDialog.ShowDialog() == DialogResult.OK)         {             string pFileName = pOpenFileDialog.FileName;             if (pFileName == "")             {                 return;             }             if (mainMapControl.CheckMxFile(pFileName))              {                 ClearAllData();                 mainMapControl.LoadMxFile(pFileName);             }             else             {                 MessageBox.Show(pFileName + "是无效的地图文档!", "信息提示");                 return;             }         }     }     catch (Exception ex)     {         MessageBox.Show("打开地图文档失败" + ex.Message);     } }
   | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | private void ClearAllData() {     if (mainMapControl.Map != null && mainMapControl.Map.LayerCount > 0)     {                  IMap dataMap = new MapClass();         dataMap.Name = "Map";         mainMapControl.DocumentFilename = string.Empty;         mainMapControl.Map = dataMap;
                   IMap eagleEyeMap = new MapClass();         eagleEyeMap.Name = "eagleEyeMap";         EagleEyeMapControl.DocumentFilename = string.Empty;         EagleEyeMapControl.Map = eagleEyeMap;     } }
   | 
 
IMapDocument 方法加载 Mxd 文档文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
   | private void BtnIMapDocument_Click(object sender, EventArgs e) {     try     {         OpenFileDialog pOpenFileDialog = new OpenFileDialog();         pOpenFileDialog.CheckFileExists = true;         pOpenFileDialog.Title = "打开地图文档";         pOpenFileDialog.Filter = "ArcMap文档(*.mxd)|*.mxd;|ArcMap模板(*.mxt)|*.mxt|发布地图文件(*.pmf)|*.pmf|所有地图格式(*.mxd;*.mxt;*.pmf)|*.mxd;*.mxt;*.pmf";         pOpenFileDialog.Multiselect = false;         pOpenFileDialog.RestoreDirectory = true;         if (pOpenFileDialog.ShowDialog() == DialogResult.OK)         {             string pFileName = pOpenFileDialog.FileName;             if (pFileName == "")             {                 return;             }
              if (mainMapControl.CheckMxFile(pFileName))              {                                  IMapDocument pMapDocument = new MapDocument();                 pMapDocument.Open(pFileName, "");                                  mainMapControl.Map = pMapDocument.ActiveView.FocusMap;                 mainMapControl.ActiveView.Refresh();             }             else             {                 MessageBox.Show(pFileName + "是无效的地图文档!", "信息提示");                 return;             }         }     }     catch (Exception ex)     {         MessageBox.Show("打开地图文档失败" + ex.Message);     } }
   | 
 
ControlsOpenDocCommandClass 加载地图
1 2 3 4 5 6
   | private void BtncontrolsOpenDocCommandClass_Click(object sender, EventArgs e) {     ICommand command = new ControlsOpenDocCommandClass();     command.OnCreate(mainMapControl.Object);     command.OnClick(); }
   | 
 
加载 Shapefile 数据
加载 Shapefile 数据的方式有两种:
- 通过工作空间加载;
 
 
- 通过 MapControl 空间的 AddShapefile 方法加载
 
 
通过工作空间加载
实例程序实现思路:
- (1) 创建 ShapefileWorkspaceFactory 实例 pWorkspaceFactory ,使用 IWorkspaceFactory 接口的 OpenFromFile 方法打开 pFeatureWorkspace 中存储的基于 Shapefile 的工作区。
 
- (2) 创建 FeatureLayer 的实例 pFeatureLayer ,并定义数据集。
 
- (3) 使用 IMap 接口的 AddLayer 方法加载 pFeatureLayer 到当前地图。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
   | private void AddShp_Click(object sender, EventArgs e) {          try     {         OpenFileDialog pOpenFileDialog = new OpenFileDialog();         pOpenFileDialog.CheckFileExists = true;         pOpenFileDialog.Title = "打开Shape文件";         pOpenFileDialog.Filter = "Shape文件(*.shp)|*.shp";         pOpenFileDialog.ShowDialog();
                                     
                   IWorkspaceFactory pWorkspaceFactory;         IFeatureWorkspace pFeatureWorkspace;         IFeatureLayer pFeatureLayer;
          string pFullPath = pOpenFileDialog.FileName;         if (pFullPath == "")             return;
          int pIndex = pFullPath.LastIndexOf("\\");                  string pFilePath = pFullPath.Substring(0, pIndex);          string pFileName = pFullPath.Substring(pIndex + 1);          
 
 
 
 
 
                   pWorkspaceFactory = new ShapefileWorkspaceFactory();         pFeatureWorkspace = (IFeatureWorkspace)pWorkspaceFactory.OpenFromFile(pFilePath, 0);                  IFeatureClass pFeatureClass = pFeatureWorkspace.OpenFeatureClass(pFileName);         pFeatureLayer = new FeatureLayer();         pFeatureLayer.FeatureClass = pFeatureClass;         pFeatureLayer.Name = pFeatureLayer.FeatureClass.AliasName;
          ClearAllData();    
          mainMapControl.Map.AddLayer(pFeatureLayer);         mainMapControl.ActiveView.Refresh();                  SynchronizeEagleEye();     }     catch (Exception ex)     {         MessageBox.Show("图层加载失败!" + ex.Message);     } }
   | 
 
通过 MapControl 空间的 AddShapefile 方法加载
调用该方法需要传入两个参数,分别是文件路径和不带扩展名的文件名。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
   | private void AddShp2_Click(object sender, EventArgs e) {     OpenFileDialog pOpenFileDialog = new OpenFileDialog();     pOpenFileDialog.CheckFileExists = true;     pOpenFileDialog.Title = "打开Shape文件";     pOpenFileDialog.Filter = "Shape文件(*.shp)|*.shp";     pOpenFileDialog.ShowDialog();
           FileInfo pFileInfo = new FileInfo(pOpenFileDialog.FileName);     string pPath = pOpenFileDialog.FileName.Substring(0, pOpenFileDialog.FileName.Length - pFileInfo.Name.Length);     mainMapControl.AddShapeFile(pPath, pFileInfo.Name);      }
   | 
 
加载栅格数据
实例程序实现思路:
在加载栅格文件时,需引用 ESRI.ArcGIS.DataSourcesRaster 命名空间。
- (1) 用 IWorkspaceFactory 接口的 OpenFromFile 方法获得栅格文件的工作区; 
 
- (2) 用 IRasterWorkspace 接口的 OpenRasterDataset 方法获得栅格文件的数据集,实例化栅格文件对象,并对栅格数据集是否具有金字塔进行判断(这里栅格文件如果不具有金字塔则创建金字塔,可以提高大数据量图像的显示效率);
 
- (3) 创建 RasterLayer 类的实例 pRasterLayer ,并定义其数据集;
 
- (4) 使用 MapControl 控件的 AllLayer 方法将 pRasterLayer 添加至当前地图。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
   | private void AddRaster_Click(object sender, EventArgs e) {     OpenFileDialog pOpenFileDialog = new OpenFileDialog();     pOpenFileDialog.CheckFileExists = true;     pOpenFileDialog.Title = "打开Raster文件";     pOpenFileDialog.Filter = "栅格文件 (*.*)|*.bmp;*.tif;*.jpg;*.img|(*.bmp)|*.bmp|(*.tif)|*.tif|(*.jpg)|*.jpg|(*.img)|*.img";     pOpenFileDialog.ShowDialog();
      string pRasterFileName = pOpenFileDialog.FileName;     if (pRasterFileName == "")     {         return;     }
      string pPath = System.IO.Path.GetDirectoryName(pRasterFileName);     string pFileName = System.IO.Path.GetFileName(pRasterFileName);
      IWorkspaceFactory pWorkspaceFactory = new RasterWorkspaceFactory();     IWorkspace pWorkspace = pWorkspaceFactory.OpenFromFile(pPath, 0);     IRasterWorkspace pRasterWorkspace = pWorkspace as IRasterWorkspace;     IRasterDataset pRasterDataset = pRasterWorkspace.OpenRasterDataset(pFileName);          IRasterPyramid3 pRasPyrmid;     pRasPyrmid = pRasterDataset as IRasterPyramid3;     if (pRasPyrmid != null)     {         if (!(pRasPyrmid.Present))         {             pRasPyrmid.Create();          }     }     IRaster pRaster;     pRaster = pRasterDataset.CreateDefaultRaster();     IRasterLayer pRasterLayer;     pRasterLayer = new RasterLayerClass();     pRasterLayer.CreateFromRaster(pRaster);     mainMapControl.Map.AddLayer(pLayer);      }
   | 
 
加载 CAD 数据
对于 ArcGIS Engine 来说,有两种不同的方式使用 CAD 数据:① 作为要素图层,以矢量数据来使用;② 作为地图背景,以栅格数据来使用。对于前者, ArcGIS Engine 使用与 FeatureLayer 一样的方法来管理,对于后者则采用 CadLayer 对象来管理。
CAD 文件作为矢量图层加载
分图层加载
实例程序实现思路:
- (1) CAD 图可以分为点、线、面、标注,它们可以分别被加载到 MapControl 中。与加载其他数据一样,首先定义一个工作空间,用 CadWorkspaceFactoryClass 实例化工作空间,并打开相应的工作空间; 
 
- (2) 创建 FeatureLayer 的实例,定义数据集,使用 IMap 接口的 AddLayer 方法将要素图层添加至当前地图。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
   | private void AddCADByLayer_Click(object sender, EventArgs e) {     IWorkspaceFactory pWorkspaceFactory;     IFeatureWorkspace pFeatureWorkspace;     IFeatureLayer pFeatureLayer;     IFeatureClass pFeatureClass;
      OpenFileDialog pOpenFileDialog = new OpenFileDialog();     pOpenFileDialog.Filter = "CAD(*.dwg)|*.dwg";     pOpenFileDialog.Title = "打开CAD数据文件";     pOpenFileDialog.ShowDialog();
      string pFullPath = pOpenFileDialog.FileName;     if (pFullPath == "")     {         return;     }          int pIndex = pFullPath.LastIndexOf("\\");     string pFilePath = pFullPath.Substring(0, pIndex);     string pFileName = pFullPath.Substring(pIndex + 1);
      pWorkspaceFactory = new CadWorkspaceFactory();     pFeatureWorkspace = (IFeatureWorkspace)pWorkspaceFactory.OpenFromFile(pFilePath, 0);          pFeatureClass = pFeatureWorkspace.OpenFeatureClass(pFileName + ":polyline");                         pFeatureLayer = new FeatureLayerClass();     pFeatureLayer.Name = pFileName;     pFeatureLayer.FeatureClass = pFeatureClass;
      ClearAllData();    
      mainMapControl.Map.AddLayer(pFeatureLayer);     mainMapControl.ActiveView.Refresh();          SynchronizeEagleEye(); }
   | 
 
整幅图加载
实例程序实现思路:
- 将 CAD 作为整幅图加载时,在得到相应的工作空间之后对 CAD 文件中的要素进行遍历,并判断是否为注记图层,如果是注记则需要使用 CadAnnotationLayer 对象。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
   | private void AddWholeCAD_Click(object sender, EventArgs e) {     IWorkspaceFactory pWorkspaceFactory;     IFeatureWorkspace pFeatureWorkspace;     IFeatureLayer pFeatureLayer;     IFeatureDataset pFeatureDataset;
      OpenFileDialog pOpenFileDialog = new OpenFileDialog();     pOpenFileDialog.Filter = "CAD(*.dwg)|*.dwg";     pOpenFileDialog.Title = "打开CAD数据文件";     pOpenFileDialog.ShowDialog();
      string pFullPath = pOpenFileDialog.FileName;     if (pFullPath == "")     {         return;     }          int pIndex = pFullPath.LastIndexOf("\\");     string pFilePath = pFullPath.Substring(0, pIndex);     string pFileName = pFullPath.Substring(pIndex + 1);          pWorkspaceFactory = new CadWorkspaceFactoryClass();      pFeatureWorkspace = (IFeatureWorkspace)pWorkspaceFactory.OpenFromFile(pFilePath, 0);          pFeatureDataset = pFeatureWorkspace.OpenFeatureDataset(pFileName);          IFeatureClassContainer pFeatClassContainer = (IFeatureClassContainer)pFeatureDataset;
      ClearAllData();    
           for (int i = 0; i < pFeatClassContainer.ClassCount; i++)     {         IFeatureClass pFeatClass = pFeatClassContainer.get_Class(i);                  if (pFeatClass.FeatureType == esriFeatureType.esriFTCoverageAnnotation)         {             pFeatureLayer = new CadAnnotationLayerClass();             pFeatureLayer.Name = pFeatClass.AliasName;             pFeatureLayer.FeatureClass = pFeatClass;             mainMapControl.Map.AddLayer(pFeatureLayer);         }         else          {             pFeatureLayer = new FeatureLayerClass();             pFeatureLayer.Name = pFeatClass.AliasName;             pFeatureLayer.FeatureClass = pFeatClass;             mainMapControl.Map.AddLayer(pFeatureLayer);         }         mainMapControl.ActiveView.Refresh();     }          SynchronizeEagleEye(); }
   | 
 
CAD 文件作为栅格图层加载
实例程序实现思路:
- (1) 用 IWorkspaceFactory 接口的 OpenFromFile 方法获得 CAD 文件的工作区; 
 
- (2) 用 ICadDrawingWorkspace 接口的 OpenCadDrawingDataset 方法获得 CAD 文件的数据集,并将其赋值给 CadLayerClass 类的实例对象 pCadLayer 的 CadDrawingDataset 属性;
 
- (3) 使用 IMap 接口的 AddLayer 方法将 pCadLayer 添加至当前地图。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
   | private void AddRasterByCAD_Click(object sender, EventArgs e) {     IWorkspaceFactory pCadWorkspaceFactory;     IWorkspace pWorkspace;     ICadDrawingWorkspace pCadDrawingWorkspace;     ICadDrawingDataset pCadDrawingDataset;     ICadLayer pCadLayer;
      OpenFileDialog pOpenFileDialog = new OpenFileDialog();     pOpenFileDialog.Filter = "CAD(*.dwg)|*.dwg";     pOpenFileDialog.Title = "打开CAD数据文件";     pOpenFileDialog.ShowDialog();
      string pFullPath = pOpenFileDialog.FileName;     if (pFullPath == "")     {         return;     }          int pIndex = pFullPath.LastIndexOf("\\");     string pFilePath = pFullPath.Substring(0, pIndex);     string pFileName = pFullPath.Substring(pIndex + 1);     pCadWorkspaceFactory = new CadWorkspaceFactoryClass();
      pWorkspace = pCadWorkspaceFactory.OpenFromFile(pFilePath, 0);     pCadDrawingWorkspace = (ICadDrawingWorkspace)pWorkspace;          pCadDrawingDataset = pCadDrawingWorkspace.OpenCadDrawingDataset(pFileName);     pCadLayer = new CadLayerClass();     pCadLayer.CadDrawingDataset = pCadDrawingDataset;     pCadLayer.Name = pFileName;
      mainMapControl.Map.AddLayer(pCadLayer);     mainMapControl.ActiveView.Refresh(); }
   | 
 
加载个人地理数据库
个人地理数据库(Personal Geodatabase)使用 Micorosoft Access 文件(*.mdb)进行空间数据的存储与管理,它将不同的数据同一纳入 Access 文件中,便于数据的管理与迁移,容量限制为2GB。个人地理数据库支持单用户编辑,不支持版本管理。
实例程序实现思路:
- (1) 创建 AccessWorkspaceFactory 类的实例; 
 
- (2) 用 IWorkspaceFactory 接口的 OpenFromFile 方法打开 *.mdb 数据集的工作空间,对工作空间里面的数据进行加载。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
   | private void AddPersonGDB_Click(object sender, EventArgs e) {     IWorkspaceFactory pAccessWorkspaceFactory;
      OpenFileDialog pOpenFileDialog = new OpenFileDialog();     pOpenFileDialog.Filter = "Personal Geodatabase(*.mdb)|*.mdb";     pOpenFileDialog.Title = "打开PersonGeodatabase文件";     pOpenFileDialog.ShowDialog();
      string pFullPath = pOpenFileDialog.FileName;     if (pFullPath == "")     {         return;     }     pAccessWorkspaceFactory = new AccessWorkspaceFactory();           IWorkspace pWorkspace = pAccessWorkspaceFactory.OpenFromFile(pFullPath, 0);
      ClearAllData();    
           AddAllDataset(pWorkspace, mainMapControl); }
   | 
 
- 这里对加载工作空间中数据的方法进行了封装,自定义了 AddAllDataset 函数,以便对其他空间数据库(文件地理数据库、ArcSDE 空间数据库)加载时可直接调用。
 
- 以上代码主要介绍矢量和栅格数据的加载(其实不止这两种数据格式,加载其他类型的数据也是采用相同的方法,只是采用不同的工作空间而已)。
 
- 自定义函数 AddAllDataset 核心代码如下:
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
   | 
 
 
  private void AddAllDataset(IWorkspace pWorkspace, AxMapControl mapControl) {     IEnumDataset pEnumDataset = pWorkspace.get_Datasets(ESRI.ArcGIS.Geodatabase.esriDatasetType.esriDTAny);     pEnumDataset.Reset();          IDataset pDataset = pEnumDataset.Next();          while (pDataset != null)     {         if (pDataset is IFeatureDataset)           {             IFeatureWorkspace pFeatureWorkspace = (IFeatureWorkspace)pWorkspace;             IFeatureDataset pFeatureDataset = pFeatureWorkspace.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 = pFeatureWorkspace.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 pRasPyrmid;             pRasPyrmid = pRasterDataset as IRasterPyramid3;             if (pRasPyrmid != null)             {                 if (!(pRasPyrmid.Present))                 {                     pRasPyrmid.Create();                  }             }             IRasterLayer pRasterLayer = new RasterLayerClass();             pRasterLayer.CreateFromDataset(pRasterDataset);             ILayer pLayer = pRasterLayer as ILayer;             mapControl.AddLayer(pLayer, 0);         }         pDataset = pEnumDataset.Next();     }
      mapControl.ActiveView.Refresh();          SynchronizeEagleEye(); }
 
  | 
 
加载文件地理数据库数据
文件地理数据库(File Geodatabase)是以文件夹形式存储各种类型的 GIS 数据集,可以存储、查询和管理空间数据和非空间数据,支持的地理数据库的大小最大为 1 TB。文件地理数据库支持单用户编辑,不支持版本管理。
实例程序实现思路:
- (1) 由于文件地理数据库是以文件夹的形式存在的,因此可以使用 FolderBrowserDialog 选择文件夹进行加载。首先创建 FileGDBWorkspaceFactoryClass 类的实例; 
 
- (2) 用 IWorkspaceFactory 接口的 OpenFromFile 方法打开文件地理数据库的工作空间,对工作空间里面的数据进行加载。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | #region 加载文件地理数据库数据 private void AddFileDatabase_Click(object sender, EventArgs e) {     IWorkspaceFactory pFileGDBWorkspaceFactory;
      FolderBrowserDialog dlg = new FolderBrowserDialog();     if (dlg.ShowDialog() != DialogResult.OK) return;     string pFullPath = dlg.SelectedPath;
      if (pFullPath == "")     {         return;     }     pFileGDBWorkspaceFactory = new FileGDBWorkspaceFactoryClass(); 
      ClearAllData();    
           IWorkspace pWorkspace = pFileGDBWorkspaceFactory.OpenFromFile(pFullPath, 0);     AddAllDataset(pWorkspace, mainMapControl); } #endregion
   | 
 
加载 ArcSDE 空间数据库数据
ArcSDE(Spatial Database Engine,空间搜索引擎)是在现有的关系型数据库上进行的空间扩展,它使空间数据能保存在关系数据库中(如 Oracle、SQLServer等)。ArcSDE 空间数据库的一个重要特点是支持多用户并发操作,并且可以通过版本来表现空间数据编辑的状态。
ArcSDE 的组成:
- ArcSDE 服务器管理进程负责维护 ArcSDE 和监听来自客户端的连接请求。ArcSDE 启动就是启动 ArcSDE 服务器管理进程,利用管理员账户管理 ArcSDE 与 RDBMS 的连接,处理客户端的连接请求。
 
- 专用服务器进程由 ArcSDE 服务器管理进程穿件,用于每一个特定的客户端应用程序与数据库的连接。
 
- ArcSDE 客户端通过 ArcSDE 服务器管理进程和专用服务器进程建立和 RDBMS 的连接,实现对数据库的操作。
 
ArcSDE 提供了应用服务器连接和直接连接两种连接方式。当服务器性能较好时可采用应用服务器连接,否则采用直接连接。为了减轻服务器的压力,建议采用直接连接的方式进行连接。
两种连接方式的异同:直接连接就是通过 ArcSDE 访问数据表,并在本地完成对数据的各种操作(如空间分析、编辑等);而应用服务器连接就是通过 ArcSDE 访问数据表后,在服务器端完成对数据的各种操作,再把操作结果返回客户端。
实例程序实现思路:
- (1) 创建 SDEWorksapceFactoryClass 类的实例; 
 
- (2) 通过 SDE 连接的连接属性打开 SDE 数据库的工作空间,对工作空间里面的数据进行加载。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
   | # 这里以基于 Oracle 11g 的 ArcSDE 10.0 连接为例对两种连接方式进行说明。 #region 加载 ArcSDE 数据库
 
 
 
 
  private void AddSDEByService_Click(object sender, EventArgs e) {     IWorkspace pWorkspace;     pWorkspace = arcSDEWorkspaceOpen("192.168.70.110", "esri_sde", "sde", "sde", "", "SDE.DEFAULT");
           if (pWorkspace != null)     {         AddAllDataset(pWorkspace, mainMapControl);     } }
 
 
 
 
 
  private void AddSDEByDirect_Click(object sender, EventArgs e) {     IWorkspace pWorkspace;
           if (pWorkspace != null)     {         AddAllDataset(pWorkspace, mainMapControl);     } }
 
 
 
 
 
 
 
 
 
 
  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("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; } #endregion
   | 
 
加载文本文件数据
野外测量的数据通常为含有 X、Y 坐标的 Excel 文件或者文本文件。
实例程序实现思路:
- (1) 根据 Excel 或者 *.txt 文件等获取点的坐标信息; 
 
- (2) 根据点的坐标创建 Shapefile 图层;
 
- (3) 加载该 Shapefile 图层。
 
坐标信息的提取
1 2 3 4 5 6
   | struct CPoint {     public string Name;     public double X;     public double Y; }
   | 
 
- (2) 创建并实例化一个 CPoint 类型的数组,将所有的点信息进行存储。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
   | List<string> pColumns = new List<string>(); private List<CPoint> GetPoints(string surveyDataFullName) {     try     {         List<CPoint> pList = new List<CPoint>();         char[] charArray = new char[] { ',', ' ', '\t' };                     FileStream fs = new FileStream(surveyDataFullName, FileMode.Open);         StreamReader sr = new StreamReader(fs, Encoding.Default);         string strLine = sr.ReadLine();         if (strLine != null)         {             string[] strArray = strLine.Split(charArray);             if (strArray.Length > 0)             {                 for (int i = 0; i < strArray.Length; i++)                 {                     pColumns.Add(strArray[i]);                 }             }
              while ((strLine= sr.ReadLine())!=null)             {                                  strArray = strLine.Split(charArray);                 CPoint pCPoint = new CPoint();                 pCPoint.Name = strArray[0].Trim();                 pCPoint.X = Convert.ToDouble(strArray[1]);                 pCPoint.Y = Convert.ToDouble(strArray[2]);                              pList.Add(pCPoint);             }         }         else         {             return null;         }         sr.Close();         return pList;     }     catch (Exception ex)     {         MessageBox.Show(ex.Message);         return null;     } }
   | 
 
根据点坐标创建 Shapefile 图层
- (1) 创建表的工作空间,通过 IFields、IFieldsEdit、IField 等接口创建属性字段,添加到要素集中。
 
- (2) 根据获得的点坐标信息为属性字段赋值,进而得到图层的要素集。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
   | private IFeatureLayer CreateShpFromPoints(List<CPoint> cPointList, string filePath) {     int index = filePath.LastIndexOf('\\');     string folder = filePath.Substring(0, index);     string shapeName = filePath.Substring(index + 1);       IWorkspaceFactory pWSF = new ShapefileWorkspaceFactoryClass();     IFeatureWorkspace pFWS = (IFeatureWorkspace)pWSF.OpenFromFile(folder, 0);
      IFields pFields = new FieldsClass();     IFieldsEdit pFieldsEdit;     pFieldsEdit = (IFieldsEdit)pFields;
      IField pField = new FieldClass();     IFieldEdit pFieldEdit = (IFieldEdit)pField;     pFieldEdit.Name_2 = "Shape";     pFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;     IGeometryDef pGeometryDef = new GeometryDefClass();     IGeometryDefEdit pGDefEdit = (IGeometryDefEdit)pGeometryDef;     pGDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPoint;          ISpatialReferenceFactory pSRF = new SpatialReferenceEnvironmentClass();     ISpatialReference pSpatialReference = pSRF.CreateGeographicCoordinateSystem((int)esriSRGeoCSType.esriSRGeoCS_Beijing1954);     pGDefEdit.SpatialReference_2 = pSpatialReference;
      pFieldEdit.GeometryDef_2 = pGeometryDef;     pFieldsEdit.AddField(pField);          IFeatureClass pFeatureClass;     pFeatureClass = pFWS.CreateFeatureClass(shapeName, pFields, null, null, esriFeatureType.esriFTSimple, "Shape", "");
      IPoint pPoint = new PointClass();     for (int j = 0; j < cPointList.Count; j++)     {         pPoint.X = cPointList[j].X;         pPoint.Y = cPointList[j].Y;
          IFeature pFeature = pFeatureClass.CreateFeature();         pFeature.Shape = pPoint;         pFeature.Store();     }          IFeatureLayer pFeatureLayer = new FeatureLayerClass();     pFeatureLayer.Name = shapeName;     pFeatureLayer.FeatureClass = pFeatureClass;     return pFeatureLayer; }
   | 
 
Shapefile 图层的加载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | private void btnCreate_Click(object sender, EventArgs e) {     if (ValidateTxtbox())     {         List<CPoint> pCPointList = GetPoints(txtSource.Text);         if (pCPointList == null)         {             MessageBox.Show("所选文件为空,请重新选择!");         }         else         {             IFeatureLayer pFeatureLayer = CreateShpFromPoints(pCPointList, txtSave.Text);             buddyMap.Map.AddLayer(pFeatureLayer);             this.Close();         }     } }
   | 
 
总结
根据上述 ArcGIS Engine 加载几种常用的数据源的方法,可以看出 ArcGIS Engine 加载空间数据一般具有以下五个步骤:
- 创建数据对应的工作空间工厂(WorkspaceFactory);
 
- 使用 WorkspaceFactory 创建要加载数据的工作空间(Workspace);
 
- 使用 Workspace 打开并得到图层的数据集 DataSet ;
 
- 将 DataSet 赋值给新建图层的数据源;
 
- 添加图层到 MapControl。