首页 > 其他 > 详细

Arcengine实现创建网络数据集札记(二)

时间:2014-03-03 01:47:23      阅读:616      评论:0      收藏:0      [点我收藏+]

四 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 = 1;

        //使用节点参与

        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 = 1;

            // 设置名称

            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 = 0;

 

           //设置边,交汇点,转弯的默认值为常数

          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实现创建网络数据集札记(二),布布扣,bubuko.com

Arcengine实现创建网络数据集札记(二)

原文:http://www.cnblogs.com/chuzhouGIS/p/3576176.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!