博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Arcengine实现创建网络数据集札记(二)
阅读量:4650 次
发布时间:2019-06-09

本文共 10102 字,大约阅读时间需要 33 分钟。

四 ArcEngine实现创建网络数据集

      ArcEngine创建网络数据集的过程,与ArcMap设置的过程类似,主要通过六个步骤即可以实现。

      1 定义网络数据集对象,并设置基本属性,包括网络数据集名称,空间参考,空间范围等内容。

      关键代码如下:

1      ///  2  3   /// 创建网络数据集对象 4  5   ///  6  7   /// 包含网络数据集的空间要素集 8  9   /// 网络数据集名称10 11   /// 
边线网络数据集
12 13   public IDENetworkDataset CreateNetworkDataset(IFeatureDataset featureDataset, string NetworkName)14 15   {16 17 if (string.IsNullOrEmpty(NetworkName)||null==featureDataset)18 19 {20 21 return null;22 23 }24 25 26 27 //定义边线网络数据集对象28 29 IDENetworkDataset deNetworkDataset = new DENetworkDatasetClass();30 31 // 转换为 IGeoDataset 接口32 33 IGeoDataset geoDataset = (IGeoDataset)featureDataset;34 35 36 37 // 设置数据集的空间参考和空间范围38 39 IDEGeoDataset deGeoDataset = (IDEGeoDataset)deNetworkDataset;40 41 deGeoDataset.Extent = geoDataset.Extent;42 43 deGeoDataset.SpatialReference = geoDataset.SpatialReference;44 45 46 47 // 设置名称48 49 IDataElement dataElement = (IDataElement)deNetworkDataset;50 51 dataElement.Name = NetworkName;52 53 // 设置为可创建54 55 pDENetworkDataset.Buildable = true;56 57 //设置数据集类型58 59 pDENetworkDataset.NetworkType = esriNetworkDatasetType.esriNDTGeodatabase;60 61 62 63 return deNetworkDataset;64 65   }
View Code

     2 创建数据源对象;

     关键代码如下:

1 ///  2  3   /// 创建网络源对象 4  5   ///  6  7   /// 参与网络数据集的空间要素类名称 8  9   /// 
10 11   public INetworkSource CreateEdgeFeatureNetworkSource(string FeatureClassName)12 13   {14 15 16 17 INetworkSource pEdgeNetworkSource = new EdgeFeatureSourceClass();18 19 pEdgeNetworkSource.Name = FeatureClassName;20 21 //设置类型22 23 pEdgeNetworkSource.ElementType = esriNetworkElementType.esriNETEdge;24 25 26 27 return pEdgeNetworkSource;28 29   }
View Code

      3 设置数据源的属性,主要包括连通性策略,源对象方向;

      关键代码如下:

1  ///  2  3   /// 设置源的连通性,不使用字段值设置 4  5   ///  6  7   /// 源对象 8  9   public void SetNetworkSourcewithoutSubtypes(INetworkSource pEdgeNetworkSource)10 11   {12 13          // 源的连通性14 15         IEdgeFeatureSource pEdgeFeatureSource = (IEdgeFeatureSource)pEdgeNetworkSource;16 17         //不使用子类18 19         pEdgeFeatureSource.UsesSubtypes = false;20 21          //分组22 23          pEdgeFeatureSource.ClassConnectivityGroup = 1;24 25         //使用节点参与26 27         pEdgeFeatureSource.ClassConnectivityPolicy = esriNetworkEdgeConnectivityPolicy.esriNECPEndVertex;28 29   }30 31  32 33   /// 34 35   /// 设置源对象的方向36 37   /// 38 39   /// 道路属性名40 41   /// 源对象42 43   private void SetNetworkSourceDirections(string StreetFieldName, INetworkSource EdgeNetworkSource)44 45   {46 47             // 创建道路名字段类对象48 49             IStreetNameFields streetNameFields = new StreetNameFieldsClass();50 51             streetNameFields.Priority = 1;52 53             // 设置名称54 55             streetNameFields.StreetNameFieldName = StreetFieldName;56 57  58 59            //添加到集合中60 61            IArray nsdArray = new ArrayClass();62 63            nsdArray.Add(streetNameFields);64 65  66 67            //创建网络方向对象68 69             INetworkSourceDirections nsDirections = new NetworkSourceDirectionsClass();70 71  72 73             nsDirections.StreetNameFields = nsdArray;74 75  76 77             //设置源对象的网络方向78 79             EdgeNetworkSource.NetworkSourceDirections = nsDirections;80 81   }82 83
View Code

        4 设置网络数据集的属性,对应ArcMap创建网络数据集的第六步设置;

        关键代码如下:

1 ///   2   3   /// 网络权重属性设置,多个源参与同一个网络数据集属性的设置  4   5   ///   6   7   /// 参与的所有源对象  8   9   /// 属性名称 10  11   /// 设置表达式 12  13   /// 设置逻辑表达式,可空 14  15   /// 
16 17   private IEvaluatedNetworkAttribute CreateNetworkSourceAttribute(List
SourceLst, string AttributeName, string Expression, string PreLogic) 18 19   { 20 21 //定义变量 22 23 IEvaluatedNetworkAttribute pEvalNetAttr; 24 25 INetworkAttribute2 pNetAttr2; 26 27 INetworkFieldEvaluator pNetFieldEval; 28 29 INetworkConstantEvaluator pNetConstEval; 30 31 32 33 pEvalNetAttr = new EvaluatedNetworkAttributeClass(); 34 35 pNetAttr2 = (INetworkAttribute2)pEvalNetAttr; 36 37 pNetAttr2.Name = AttributeName; 38 39 //计算类型 40 41 pNetAttr2.UsageType = esriNetworkAttributeUsageType.esriNAUTCost; 42 43 //数值类型 44 45 pNetAttr2.DataType = esriNetworkAttributeDataType.esriNADTDouble; 46 47 //单位类型 48 49 pNetAttr2.Units = esriNetworkAttributeUnits.esriNAUMeters; 50 51 pNetAttr2.UseByDefault = true; 52 53 54 55 //计算表达式 56 57 pNetFieldEval = new NetworkFieldEvaluatorClass(); 58 59 pNetFieldEval.SetExpression(Expression, PreLogic); 60 61 62 63 //参与的每个源的计算表达式设置 64 65 SourceLst.ForEach(pEdgeNetworkSource => 66 67 { 68 69 //正向计算表达式 70 71 pEvalNetAttr.set_Evaluator(pEdgeNetworkSource, esriNetworkEdgeDirection.esriNEDAlongDigitized, (INetworkEvaluator)pNetFieldEval); 72 73 //反向计算表达式 74 75 pEvalNetAttr.set_Evaluator(pEdgeNetworkSource, esriNetworkEdgeDirection.esriNEDAgainstDigitized, (INetworkEvaluator)pNetFieldEval); 76 77 78 79 }); 80 81 82 83 pNetConstEval = new NetworkConstantEvaluatorClass(); 84 85 pNetConstEval.ConstantValue = 0; 86 87 88 89 //设置边,交汇点,转弯的默认值为常数 90 91 pEvalNetAttr.set_DefaultEvaluator(esriNetworkElementType.esriNETEdge, 92 93 (INetworkEvaluator)pNetConstEval); 94 95 pEvalNetAttr.set_DefaultEvaluator(esriNetworkElementType.esriNETJunction, 96 97 (INetworkEvaluator)pNetConstEval); 98 99 pEvalNetAttr.set_DefaultEvaluator(esriNetworkElementType.esriNETTurn,100 101 (INetworkEvaluator)pNetConstEval);102 103 104 105 return pEvalNetAttr;106 107   }
View Code

       5 设置网络数据集的方向;

       关键代码如下:

1 ///  2  3   /// 指定网络数据集的方向属性 4  5   ///  6  7   /// 网络数据集 8  9   /// 单位类型10 11   ///  创建的长度属性的名称12 13   ///  创建的时间属性名称,可空14 15   /// 创建的道路类型属性名称,可空16 17   public void SetNetworkDirction(IDENetworkDataset deNetworkDataset,esriNetworkAttributeUnits UnitsType, string LengthAttribute, string TimeAttribute, string RoadClassAttribute)18 19   {20 21              // 创建网络方向对象22 23              INetworkDirections networkDirections = new NetworkDirectionsClass();24 25              networkDirections.DefaultOutputLengthUnits = UnitsType;26 27  28 29               //设置长度属性30 31               if (!string.IsNullOrEmpty(LengthAttribute))32 33              {34 35                     networkDirections.LengthAttributeName = LengthAttribute;36 37                }38 39              //设置时间属性40 41                if (!string.IsNullOrEmpty(TimeAttribute))42 43                {44 45                     networkDirections.TimeAttributeName = TimeAttribute;46 47              }48 49              //设置道路类型属性50 51              if (!string.IsNullOrEmpty(RoadClassAttribute))52 53              {54 55                     networkDirections.RoadClassAttributeName = RoadClassAttribute;56 57              }58 59  60 61            // 设置网络数据集的方向属性62 63            deNetworkDataset.Directions = networkDirections;64 65   }
View Code

      6 建立网络数据集;

      关键代码如下:

1 ///  2  3   /// 根据网络节点信息,创建网络数据集对象 4  5   ///  6  7   /// 包含网络数据集的空间数据集 8  9   /// 源网络10 11   /// 
12 13   public INetworkDataset CreateBuildingDataset(IFeatureDataset _pFeatureDataset, IDENetworkDataset2 _pDENetDataset)14 15   {16 17 IFeatureDatasetExtensionContainer pFeatureDatasetExtensionContainer = (IFeatureDatasetExtensionContainer)_pFeatureDataset;18 19 IFeatureDatasetExtension pFeatureDatasetExtension = pFeatureDatasetExtensionContainer.FindExtension(esriDatasetType.esriDTNetworkDataset);20 21 IDatasetContainer2 pDatasetContainer2 = (IDatasetContainer2)pFeatureDatasetExtension;22 23 IDEDataset pDENetDataset = (IDEDataset)_pDENetDataset;24 25 26 27 //创建网络数据集28 29 INetworkDataset pNetworkDataset = (INetworkDataset)pDatasetContainer2.CreateDataset(pDENetDataset);30 31 32 33 return pNetworkDataset;34 35   }36 37 38 39   /// 40 41   /// 生成网络数据集42 43   /// 44 45   /// 网络数据集46 47   /// 空间数据集48 49   public bool BuildNetwork(INetworkDataset networkDataset, featureDataset)50 51   {52 53 // 空间数据集转换为IGeoDataset 接口54 55 IGeoDataset geoDataset = (IGeoDataset)featureDataset;56 57 58 59 if (null==geoDataset)60 61 {62 63 return false;64 65 }66 67 68 69 INetworkBuild networkBuild = (INetworkBuild)networkDataset;70 71 //构建网络数据集72 73 networkBuild.BuildNetwork(geoDataset.Extent);74 75 76 77 return true;78 79   }
View Code

五 遇到的难题与解决过程

      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”。

 

未完待续......

转载于:https://www.cnblogs.com/chuzhouGIS/p/3576176.html

你可能感兴趣的文章