ArcGIS 网络分析[8.3] 设置IDENetworkDataset的属性及INetworkDataset的对比

0
分享 2017-06-20


创建网络数据集就得有各种数据和参数,这篇文章很长,慎入。
网络分析依赖于网络数据集的质量,这句话就在这里得到了验证:复杂、精确定义。



1. INetworkDataset与IDENetworkDataset的对比
挑简单的先说,INetworkDataset与IDENetworkDataset的对比。
1.1 先说说INetworkDataset是个什么东西
网络数据集是一个拥有网络关系的要素类的容器。每个要素类都有自己的拓扑规则,每个网络有可能有多个同样拓扑规则的要素类。一个要素数据集可能有多个网络数据集,但是一个要素类只能属于一个网络数据集或一个几何网络。一个属于网络数据集的要素类被称为:网络数据源,网络数据集还拥有多个网络属性,这些属性被用作解决网络分析问题。
IDatasetContainer2接口用于创建或打开网络数据集。INetworkBuild接口用作添加或删除一个网络数据集中的网络数据源、网络属性,或者被用于构建网络数据集。
再上一张INetworkDataset的属性图:

这些属性全部都是只允许访问的(都是get属性)。
INetworkDataset更合适在分析部分解释,它与INAContext有关。
1.2 二者对比
很容易与上一节的IDENetworkDataset做出对比,INetworkDataset更专注于处理与属性、数据源的存取,而IDENetworkDataset更专注于数据的组织。
后者是数据的集合,是真正的网络数据源、网络属性等的容器,而前者更合适称为“分析对象”,它专注于网络属性和网络数据源的访问。
因为后者名中的“DE”就是DataElement的简称,所以IDENetworkDataset是“数据元素网络数据集”。
2. 如何设置数据元素网络数据集(IDENetworkDataset)的属性以创建网络数据集
再贴一张IDENetworkDataset的属性图(就上篇文章):

重点需要设置的属性是:Attributes、Directions、Sources
这对应了桌面创建网络数据集的三个重要步骤:网络属性、导航设置、网络数据源。
其中网络数据源又可分为三种:线要素、点要素、转弯要素。
其他需要注意的属性是:Buildable;
2.1 涉及的接口、类、枚举


在接下来的介绍中,会用到的核心接口和类、枚举先列出:
涉及的接口:共计18个
IDENetworkDataset、INetworkDataset、INetworkSource、INetworkAttribute、INetworkDirection、IEvaluatedNetworkAttribute、
INetworkSourceDirections、IStreetNameFields、IEdgeFeatureSource、INetworkFieldEvaluator、INetworkEvaluator、INetworkConstantEvaluator
IArray
INetworkBuild、IDEDataset、IDatasetContainer、IFeatureDatasetExtension、IFeatureDatasetExtensionContainer
涉及到的类:共计9个
DENetworkDatasetClass、StreetNameFieldsClass、NetworkSourceDirectionsClass
TurnFeatureSourceClass、EdgeFeatureSourceClass(INetworkSource的实现类)
EvaluatedNetworkAttributeClass、NetworkFieldEvaluatorClass、NetworkConstantEvaluatorClass
ArrayClass
涉及到的枚举:共计6个
esriNetworkElementType、esriNetworkAttributeUnits、esriNetworkEdgeDirection、esriNetworkAttributeDataType、esriNetworkAttributeUsageType、esriNetworkEdgeConnectivityPolicy


别害怕,我会逐一解释这些类对应桌面创建网络数据集时,分别是什么。
2.2 创建一个IDENetworkDataset对象
为了创建一个装着网络数据集所有素材的“数据元素网络数据集”,我们需要的东西是:一个IFeatureDataset(即桌面上的要素数据集)对象,网络数据集的名称。
我们创建一个这样的方法:
public IDENetworkDataset CreateDENetworkDataset(IFeatureDataset featureDataset, string networkName)
{
IDENetworkDataset deNetworkDataset = new DENetworkDatasetClass();// ...设置数据要素网络数据集的必须参数 return deNetworkDataset;}
注意,这个时候并不需要这个要素数据集中有要素数据。而在桌面软件中基于要素数据集创建网络数据集,是要求要素数据集中存在最基本的点线要素的。
那是因为,在AO中,要创建数据元素网络数据集,只需要获取IFeatureDataset即可,至于网络数据集中的点、线、转弯,则是下一步添加Sources(网络数据源)的事情。
我直接给出数据元素网络数据集必须设置的属性,和分别来自哪些接口:

从上图可以看出为了创建DENetworkDataset这个类的实例,默认使用IDENetworkDataset接口来定义变量。
需要给的默认属性有:
IDENetworkDataset接口下的Buildable属性、NetworkType属性
IDEGeoDataset接口下的Extent属性、SpatialReference属性
IDataElement接口下的Name属性
其中,Buildable设置为true,表示可以构建;
NetworkType设置为枚举值esriNetworkDatasetType.esriNDTGeodatabase,表示是基于数据库的网络数据集;
Extent和SpatialReference属性表示网络数据集的地理外接矩形和空间参考系,可以从传入的要素数据集的父级接口IGeoDataset中获取。
Name表示网络数据集的名称,由传入参数给定。
完整的方法如下:
/// <summary>
/// 创建IDENetworkDataset(数据元素网络数据集)对象
/// </summary>
/// <param name="featureDataset">传入:要素数据集</param>
/// <param name="NetworkName">传入:网络数据集名称</param>
/// <returns>返回:数据元素网络数据集</returns>
public IDENetworkDataset CreateDENetworkDataset(IFeatureDataset featureDataset, string NetworkName)
{
//判断传入参数是否为空
if (string.IsNullOrEmpty(NetworkName) || null == featureDataset)
{
return null;
}

// 若传入参数不为空,实例化数据元素网络数据集对象
IDENetworkDataset deNetworkDataset = new DENetworkDatasetClass();
// 设置数据集类型、可以被构建
deNetworkDataset.Buildable = true;
deNetworkDataset.NetworkType = esriNetworkDatasetType.esriNDTGeodatabase;

// 设置数据集的空间参考、空间范围
IDEGeoDataset deGeoDataset = deNetworkDataset as IDEGeoDataset;
IGeoDataset geoDataset = featureDataset as IGeoDataset;
deGeoDataset.Extent = geoDataset.Extent;
deGeoDataset.SpatialReference = geoDataset.SpatialReference;

// 设置名称
IDataElement dataElement = deNetworkDataset as IDataElement;
dataElement.Name = NetworkName;

return deNetworkDataset;
}
可以直接封装在一个类里。
2.3 添加Sources属性(网络数据源)——添加边线与转弯
涉及到的接口:INetworkSource、IEdgeFeatureSource、IJunctionFeatureSource、ITurnFeatureSource、IArray
涉及到的类:EdgeFeatureSourceClass、JunctionFeatureSourceClass、TurnFeatureSourceClass、ArrayClass
还记得桌面端如何设置网络数据集的数据源吗?
就勾选点、线、转弯要素即可。
这里对应的EdgeFeatureSourceClass、JunctionFeatureSourceClass、TurnFeatureSourceClass,以及他们的接口,就是他们的编程中的类。
画一张类图吧:

通过实例化不同的INetworkSource对象,设置其连通性和名称,再添加到IArray容器中,就可以给IDENetworkDataset的Sources属性赋值啦!
代码以后附上。
2.4 添加Attributes属性(网络属性)——以长度或时间为单位的属性为例(成本属性)
涉及的接口:INetworkAttribute3、IEvaluatedNetworkAttribute
涉及的类:NetworkAttributeClass、EvaluatedNetworkAttributeClass、NetworkConstantEvaluatorClass、NetworkFieldEvaluatorClass、NetworkScriptEvaluatorClass
这一步比较复杂。回忆一下在桌面软件中是如何设置网络属性的?
对,要添加一个网络属性,要设置其类型(成本、限制等),要设置其单位,要设置各个要素给网络属性的赋值(字段、脚本等),十分复杂。
在这里,网络属性是INetworkAttribute3,而网络属性的具体数据则由IEvaluatedNetworkAttribute去组织和存放,后者,叫作数据组织器。这对接口的作用颇似INetworkDataset和IDENetworkDataset。
以后慢慢谈。
2.5 设置Directions属性(导航)
涉及到的接口:INetworkDirections
涉及到的类:NetworkDirectionsClass
转弯就比较简单啦。
2.6 创建并构建INetworkDataset对象(大功告成!)
只能通过IDatasetContainer.CreateDataset()方法创建,传入的参数是IDEDataset类型的变量,返回的是IDataset对象。
这一步,也是最后的一步,将数据集合(DENetworkDataset)转化为分析对象(NetworkDataset)。
当然别忘了构建一下~
直接上代码:
/// <summary>
/// 由数据元素网络数据集创建网络数据集
/// </summary>
/// <param name="featureDataset">传入:要素数据集</param>
/// <param name="deNetworkDataset">传入:数据元素网络数据集</param>
/// <returns></returns>
public INetworkDataset CreateBuildingDataset(IFeatureDataset featureDataset, IDENetworkDataset2 deNetworkDataset)
{
IFeatureDatasetExtensionContainer featureDatasetExtensionContainer = featureDataset as IFeatureDatasetExtensionContainer;
IFeatureDatasetExtension featureDatasetExtension = featureDatasetExtensionContainer.FindExtension(esriDatasetType.esriDTNetworkDataset);
IDatasetContainer2 datasetContainer2 = featureDatasetExtension as IDatasetContainer2;
IDEDataset deDataset = deNetworkDataset as IDEDataset;
//创建网络数据集
INetworkDataset networkDataset = datasetContainer2.CreateDataset(deDataset) as INetworkDataset;
return networkDataset;
}

/// <summary>
/// 构建网络数据集,成功则返回true
/// </summary>
/// <param name="networkDataset">传入:网络数据集</param>
/// <param name="geoDataset">传入:要素数据集</param>
public bool BuildNetwork(INetworkDataset networkDataset, IFeatureDataset featureDataset)
{
// 空间数据集转换为IGeoDataset 接口
IGeoDataset geoDataset = featureDataset as IGeoDataset;
if (null == geoDataset)
{
return false;
}
INetworkBuild networkBuild = networkDataset as INetworkBuild;
//构建网络数据集
networkBuild.BuildNetwork(geoDataset.Extent);

return true;
}
创建成功的结果如下:

我传的网络数据集名称为STH_ND,结果就如上图咯。
3. 流程图
这是我做过最复杂的AO开发了,涉及到的类和接口实在太庞大...趁年轻多搞搞,提升一下逻辑组织能力。
在后阶段的整合中,我会给出一个实例,就用本篇的各种方法,包装成一个工具类,并完整地对比桌面创建网络数据集做一个demo。
文章来源:http://www.cnblogs.com/onsummer/p/6998121.html

0 个评论

要回复文章请先登录注册