Arcengine实现创建网络数据集札记(二)
四 ArcEngine实现创建网络数据集
ArcEngine创建网络数据集的过程,与ArcMap设置的过程类似,主要通过六个步骤即可以实现。
1 定义网络数据集对象,并设置基本属性,包括网络数据集名称,空间参考,空间范围等内容。
关键代码如下:
      /// <summary>
   /// 创建网络数据集对象
   /// </summary>
   /// <param name="featureDataset">包含网络数据集的空间要素集</param>
   /// <param name="NetworkName">网络数据集名称</param>
   /// <returns>边线网络数据集</returns>
   public IDENetworkDataset CreateNetworkDataset(IFeatureDataset featureDataset, string NetworkName)
   {
          if (string.IsNullOrEmpty(NetworkName)||null==featureDataset)
          {
                return null;
          }
         //定义边线网络数据集对象
          IDENetworkDataset deNetworkDataset = new DENetworkDatasetClass();
          // 转换为 IGeoDataset 接口
          IGeoDataset geoDataset = (IGeoDataset)featureDataset;
          // 设置数据集的空间参考和空间范围
          IDEGeoDataset deGeoDataset = (IDEGeoDataset)deNetworkDataset;
          deGeoDataset.Extent = geoDataset.Extent;
          deGeoDataset.SpatialReference = geoDataset.SpatialReference;
          // 设置名称
          IDataElement dataElement = (IDataElement)deNetworkDataset;
          dataElement.Name = NetworkName;
         // 设置为可创建
         pDENetworkDataset.Buildable = true;
         //设置数据集类型
         pDENetworkDataset.NetworkType = esriNetworkDatasetType.esriNDTGeodatabase;
         return deNetworkDataset;
   }
2 创建数据源对象;
关键代码如下:
 /// <summary>
   /// 创建网络源对象
   /// </summary>
   /// <param name="FeatureClassName">参与网络数据集的空间要素类名称</param>
   /// <returns>源</returns>
   public INetworkSource CreateEdgeFeatureNetworkSource(string FeatureClassName)
   {
          INetworkSource pEdgeNetworkSource = new EdgeFeatureSourceClass();
          pEdgeNetworkSource.Name = FeatureClassName;
          //设置类型
          pEdgeNetworkSource.ElementType = esriNetworkElementType.esriNETEdge;
          return pEdgeNetworkSource;
   }
3 设置数据源的属性,主要包括连通性策略,源对象方向;
关键代码如下:
  /// <summary>
   /// 设置源的连通性,不使用字段值设置
   /// </summary>
   /// <param name="pEdgeNetworkSource">源对象</param>
   public void SetNetworkSourcewithoutSubtypes(INetworkSource pEdgeNetworkSource)
   {
          // 源的连通性
         IEdgeFeatureSource pEdgeFeatureSource = (IEdgeFeatureSource)pEdgeNetworkSource;
         //不使用子类
         pEdgeFeatureSource.UsesSubtypes = false;
          //分组
          pEdgeFeatureSource.ClassConnectivityGroup = ;
         //使用节点参与
         pEdgeFeatureSource.ClassConnectivityPolicy = esriNetworkEdgeConnectivityPolicy.esriNECPEndVertex;
   }
   /// <summary>
   /// 设置源对象的方向
   /// </summary>
   /// <param name="StreetFieldName">道路属性名</param>
   /// <param name="EdgeNetworkSource">源对象</param>
   private void SetNetworkSourceDirections(string StreetFieldName, INetworkSource EdgeNetworkSource)
   {
             // 创建道路名字段类对象
             IStreetNameFields streetNameFields = new StreetNameFieldsClass();
             streetNameFields.Priority = ;
             // 设置名称
             streetNameFields.StreetNameFieldName = StreetFieldName;
            //添加到集合中
            IArray nsdArray = new ArrayClass();
            nsdArray.Add(streetNameFields);
            //创建网络方向对象
             INetworkSourceDirections nsDirections = new NetworkSourceDirectionsClass();
             nsDirections.StreetNameFields = nsdArray;
             //设置源对象的网络方向
             EdgeNetworkSource.NetworkSourceDirections = nsDirections;
   }
4 设置网络数据集的属性,对应ArcMap创建网络数据集的第六步设置;
关键代码如下:
 /// <summary>
   /// 网络权重属性设置,多个源参与同一个网络数据集属性的设置
   /// </summary>
   /// <param name=" SourceLst ">参与的所有源对象</param>
   /// <param name="AttributeName">属性名称</param>
   /// <param name="Expression">设置表达式</param>
   /// <param name="PreLogic">设置逻辑表达式,可空</param>
   /// <returns></returns>
   private IEvaluatedNetworkAttribute CreateNetworkSourceAttribute(List<INetworkSource> SourceLst, string AttributeName, string Expression, string PreLogic)
   {
           //定义变量
           IEvaluatedNetworkAttribute pEvalNetAttr;
           INetworkAttribute2 pNetAttr2;
           INetworkFieldEvaluator pNetFieldEval;
           INetworkConstantEvaluator pNetConstEval;
           pEvalNetAttr = new EvaluatedNetworkAttributeClass();
           pNetAttr2 = (INetworkAttribute2)pEvalNetAttr;
           pNetAttr2.Name = AttributeName;
          //计算类型
           pNetAttr2.UsageType = esriNetworkAttributeUsageType.esriNAUTCost;
           //数值类型     
           pNetAttr2.DataType = esriNetworkAttributeDataType.esriNADTDouble;
           //单位类型
           pNetAttr2.Units = esriNetworkAttributeUnits.esriNAUMeters;
           pNetAttr2.UseByDefault = true;
           //计算表达式
           pNetFieldEval = new NetworkFieldEvaluatorClass();
           pNetFieldEval.SetExpression(Expression, PreLogic);
           //参与的每个源的计算表达式设置
           SourceLst.ForEach(pEdgeNetworkSource =>
           {
                     //正向计算表达式
                     pEvalNetAttr.set_Evaluator(pEdgeNetworkSource, esriNetworkEdgeDirection.esriNEDAlongDigitized, (INetworkEvaluator)pNetFieldEval);
                      //反向计算表达式
                     pEvalNetAttr.set_Evaluator(pEdgeNetworkSource, esriNetworkEdgeDirection.esriNEDAgainstDigitized, (INetworkEvaluator)pNetFieldEval);
           });
           pNetConstEval = new NetworkConstantEvaluatorClass();
           pNetConstEval.ConstantValue = ;
            //设置边,交汇点,转弯的默认值为常数
           pEvalNetAttr.set_DefaultEvaluator(esriNetworkElementType.esriNETEdge,
           (INetworkEvaluator)pNetConstEval);
           pEvalNetAttr.set_DefaultEvaluator(esriNetworkElementType.esriNETJunction,
           (INetworkEvaluator)pNetConstEval);
           pEvalNetAttr.set_DefaultEvaluator(esriNetworkElementType.esriNETTurn,
           (INetworkEvaluator)pNetConstEval);
          return pEvalNetAttr;
   }
5 设置网络数据集的方向;
关键代码如下:
 /// <summary>
   /// 指定网络数据集的方向属性
   /// </summary>
   /// <param name="deNetworkDataset">网络数据集</param>
   /// <param name="UnitsType">单位类型</param>
   /// <param name="LengthAttribute"> 创建的长度属性的名称</param>
   /// <param name="TimeAttribute"> 创建的时间属性名称,可空</param>
   /// <param name="RoadClassAttribute">创建的道路类型属性名称,可空</param>
   public void SetNetworkDirction(IDENetworkDataset deNetworkDataset,esriNetworkAttributeUnits UnitsType, string LengthAttribute, string TimeAttribute, string RoadClassAttribute)
   {
              // 创建网络方向对象
              INetworkDirections networkDirections = new NetworkDirectionsClass();
              networkDirections.DefaultOutputLengthUnits = UnitsType;
               //设置长度属性
               if (!string.IsNullOrEmpty(LengthAttribute))
              {
                     networkDirections.LengthAttributeName = LengthAttribute;
                }
              //设置时间属性
                if (!string.IsNullOrEmpty(TimeAttribute))
                {
                     networkDirections.TimeAttributeName = TimeAttribute;
              }
              //设置道路类型属性
              if (!string.IsNullOrEmpty(RoadClassAttribute))
              {
                     networkDirections.RoadClassAttributeName = RoadClassAttribute;
              }
            // 设置网络数据集的方向属性
            deNetworkDataset.Directions = networkDirections;
   }
6 建立网络数据集;
关键代码如下:
 /// <summary>
   /// 根据网络节点信息,创建网络数据集对象
   /// </summary>
   /// <param name="_pFeatureDataset">包含网络数据集的空间数据集</param>
   /// <param name="_pDENetDataset">源网络</param>
   /// <returns></returns>
   public INetworkDataset CreateBuildingDataset(IFeatureDataset _pFeatureDataset, IDENetworkDataset2 _pDENetDataset)
   {
                    IFeatureDatasetExtensionContainer pFeatureDatasetExtensionContainer =  (IFeatureDatasetExtensionContainer)_pFeatureDataset;
                    IFeatureDatasetExtension pFeatureDatasetExtension =  pFeatureDatasetExtensionContainer.FindExtension(esriDatasetType.esriDTNetworkDataset);
                    IDatasetContainer2 pDatasetContainer2 =  (IDatasetContainer2)pFeatureDatasetExtension;
                    IDEDataset pDENetDataset = (IDEDataset)_pDENetDataset;
                    //创建网络数据集
                    INetworkDataset pNetworkDataset =  (INetworkDataset)pDatasetContainer2.CreateDataset(pDENetDataset);
                    return pNetworkDataset;
   }
   /// <summary>
   /// 生成网络数据集
   /// </summary>
   /// <param name="networkDataset">网络数据集</param>
   /// <param name="geoDataset">空间数据集</param>
   public bool BuildNetwork(INetworkDataset networkDataset, featureDataset)
   {
              // 空间数据集转换为IGeoDataset 接口
             IGeoDataset geoDataset = (IGeoDataset)featureDataset;
              if (null==geoDataset)
               {
                        return false;
                 }
             INetworkBuild networkBuild = (INetworkBuild)networkDataset;
            //构建网络数据集
            networkBuild.BuildNetwork(geoDataset.Extent);
             return true;
   }
五 遇到的难题与解决过程
ArcEngine创建网络数据集过程中,遇到一些问题,主要是两部分原因,一是扩展许可问题,二是属性值设置的问题。
1 扩展许可问题:
项目开发过程中,注意到了许可初始化的问题,通过代码实现ArcEngine许可初始化。但是,在IDatasetContainer2接口执行CreateDataset方法时,报错"异常来自HRESULT:0x80040220”。
该异常产生的原因是,由于网络数据集创建功能接口的实现,需要ArcEngine扩展许可初始化,即调用IAoInitialize 接口的CheckOutExtension方法,注册空间分析的扩展许可。
2 属性值设置问题:
1)官网的样例代码对于创建网络数据集属性接口IEvaluatedNetworkAttribute时,都是针对当个参与源对象INetworkSource进行设置的。如果多个源对象参与设置同一个IEvaluatedNetworkAttribute接口设置时,需要遍历每个源对象进行设置。
关键代码段如下:
//参与的每个源的计算表达式设置
SourceLst.ForEach(pEdgeNetworkSource =>
{
//正向计算表达式
pEvalNetAttr.set_Evaluator(pEdgeNetworkSource, esriNetworkEdgeDirection.esriNEDAlongDigitized, (INetworkEvaluator)pNetFieldEval);
//反向计算表达式
pEvalNetAttr.set_Evaluator(pEdgeNetworkSource, esriNetworkEdgeDirection.esriNEDAgainstDigitized, (INetworkEvaluator)pNetFieldEval);
});
2)创建的网络数据集属性IEvaluatedNetworkAttribute,是用在设置网络数据集的方向属性,需要保证名称一致。
例如,定义了名称为“Length”的IEvaluatedNetworkAttribute对象,在设置网络数据集的长度属性为该定义的对象时,需要把INetworkDirections接口的LengthAttributeName属性设置为“Length”。这样,网络数据集在计算长度属性时,根据已定义的接口计算。否则,会报错“The network attribute name is invalid”。
未完待续......
Arcengine实现创建网络数据集札记(二)的更多相关文章
- Arcengine实现创建网络数据集札记(一)
		
一 引子 网络数据集,GIS空间分析基础的理论和知识,是最短路径分析.连通性分析等其他空间分析技术的数据基础. 以往,网络数据集的研究很少,此次项目开发过程中,对网络数据集以及arcengine创建网 ...
 - Arcengine实现创建网络数据集札记(三)
		
后记 下面给出项目中用到的自定义的封装类. AE许可初始化封装类: public class AELicenseChecker { private static volatile AELicenseC ...
 - ArcGIS 网络分析[2] 利用自定义基础数据创建网络数据集
		
前言 似乎除了官方介绍的例子,我还没有在网上见过一篇介绍如何"使用自己的数据"创建"网络数据集"的文章. 有介绍几何网络的,有介绍如何用官方SanFrancis ...
 - ArcGIS 网络分析[1.5] 使用点线数据一起创建网络数据集(如何避免孤立点/点与线的连通性组合结果表)
		
ArcGIS中最基本的三种矢量数据是什么?点线面. 网络中除了路网之外,还会有地物点. 如上图,我们在建立网络数据集的时候,作为实验,当然可以只是公路网.但是在大型的决策任务中,网络数据集就不只是公路 ...
 - ArcGIS 网络分析[8.2] 资料2 使用IDatasetContainer2接口的CreateDataset方法创建网络数据集
		
上节提及如何使用IDatasetContainer2接口访问到网络数据集,上例可以封装为一个方法. 这节就使用IDatasetContainer2接口(Geodatabase类库)的CreateDat ...
 - ArcGIS 网络分析[8.3] 设置IDENetworkDataset的属性及INetworkDataset的对比/创建网络数据集
		
创建网络数据集就得有各种数据和参数,这篇文章很长,慎入. 网络分析依赖于网络数据集的质量,这句话就在这里得到了验证:复杂.精确定义. 本节目录如下: 1. INetworkDataset与IDENet ...
 - ArcGIS 网络分析[8.1] 资料1 使用AO打开或创建网络数据集之【打开】
		
为了创建或打开一个网络数据集,你必须使用NetworkDatasetFDExtension对象(文件地理数据库中的数据集)或NetworkDatasetWorkspaceExtension对象(对于S ...
 - ArcGIS 网络分析[1.3] 在个人地理数据库中创建网络数据集/并简单试验最佳路径
		
上篇使用shp文件创建网络数据集,然而在ArcGIS 9中就支持地理数据库了,数据库的管理更为科学强大. 本篇就使用个人地理数据库进行建立网络数据集,线数据仍然可以是1.1中的线数据,但是我做了一些修 ...
 - ArcGIS 网络分析[1.2] 利用1.1的线shp创建网络数据集/并简单试验最佳路径
		
上篇已经创建好了线数据(shp文件格式)链接:点我 这篇将基于此shp线数据创建网络数据集. 在此说明:shp数据的网络数据集仅支持单一线数据,也就是说基于shp文件的网络数据集,只能有一个shp线文 ...
 
随机推荐
- Traffic Lights
			
Traffic Lights time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...
 - Android Studio NDK 学习之接受Java传入的Int数组
			
本博客是基于Android Studio 1.3 preview版本,且默认你已经安装了Android SDK, Android NDK. 用Android Studio新建一个工程叫AndroidJ ...
 - HIVE: UDF应用实例
			
数据文件内容 TEST DATA HERE Good to Go 我们准备写一个函数,把所有字符变为小写. 1.开发UDF package MyTestPackage; import org.apac ...
 - Ubuntu主题美化--使用WPS风格
			
五一就这么过去了,我也没有出去玩,一个人闲的蛋疼,无聊就把ubuntu美化一下. 闲话不多说,先看效果: 壁纸是我自己制作的的,如果喜欢另存一下下面这张图设置成背景就可以了,分辨率是1366x768. ...
 - 自定义一个叫 ReadOnlyXmlMembershipProvider 的 MembershipProvider,用 XML 作为用户储藏室
			
1. 配置 web.config <membership defaultProvider="AspNetReadOnlyXmlMembershipProvider"> ...
 - B2B多商铺初期权限数据库设计
			
项目从无到有,两个月了.一期完成. 权限目前还很简单.USER表,ROLE表,RESOURCE表三个. 目前只有两个商铺.id是0的是我们自己,作为后台运维管理,也抽象成一个商铺,id为0.另一个商铺 ...
 - Caching查看窗口
			
闲来无事,做了一个简约的Caching查看窗口,可以方便的查看本地缓存的使用情况: 下面的URL和VersionNum用来查看某个特定资源的特定版本是否存在,分别输入所需信息,点击“检测”,即可在下面 ...
 - ruby -- 进阶学习(十五)friendly_id配置
			
实现效果:http://127.0.0.1:3000/article/1 => http://127.0.0.1:3000/article/书名 (1)Rails 4.0的friendly_ ...
 - 云计算之路-阿里云上:消灭“黑色n秒”第二招——给w3wp进程指定CPU核
			
虽然昨天的第一招失败了,但是从失败中我们学到了与多核CPU相关的Processor Affinity(处理器关联)的知识. 既然我们可以让.NET程序的不同线程运行于指定的CPU核,那是不是也可以让I ...
 - [转载]在线文档预览方案-Office Web Apps
			
最近在做项目时,要在手机端实现在线文档预览的功能.于是百度了一下实现方案,大致是将文档转换成pdf,然后在通过插件实现预览.这些方案没有具体实现代码,也没有在线预览的地址,再加上项目时间紧迫.只能考虑 ...