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线文 ...
随机推荐
- Android不规则点击区域详解
Android不规则点击区域详解 摘要 今天要和大家分享的是Android不规则点击区域,准确说是在视觉上不规则的图像点击响应区域分发. 其实这个问题比较简单,对于很多人来说根本不值得做为一篇博文写出 ...
- c# socket 解决粘包,半包
处理原理: 半包:即一条消息底层分几次发送,先有个头包读取整条消息的长度,当不满足长度时,将消息临时缓存起来,直到满足长度再解码 粘包:两条完整/不完整消息粘在一起,一般是解码完上一条消息,然后再判断 ...
- Til the Cows Come Home(最短路)
Til the Cows Come Home Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I ...
- windbg入门
1.下载安装windbg Windows 10 调试工具 (WinDbg) 如果你仅需要 Windows 10 调试工具,而不需要 WDK 10 或 Visual Studio 2015,你可以将调试 ...
- Raspberry Pi 3 Model B 安装 OSMC
Raspberry Pi 3 Model B 自身搭载 WIFI 芯片,可直接连接无线网络. 准备 NOOBS 你可以购买预装有 NOOBS 的 SD 卡,或者从树莓派官网 下载 NOOBS.zip ...
- WCF安全1-开篇
概述: WCF安全简介 1.在企业级应用中什么是“安全” 答: (1)应用能够识别用户的身份-认证Authentication (2)应用能够将用户的操作和可访问的资源限制在其允许的权限范围之内-授权 ...
- 【入门必备】最佳的 Node.js 学习教程和资料书籍
Web 开发人员对 Node.js 的关注日益增多,更多的公司和开发者开始尝试使用 Node.js 来实现一些对实时性要求高,I/O密集型的业务.这篇文章中,我们整理了一批优秀的资源,你可以得到所有你 ...
- SQL 表变量和临时表
SQL 表变量和临时表 表变量:存储在内存中,作用域是脚本的执行过程中,脚本执行完毕之后就会释放内存,适合短时间内存储数据量小的数据集. 优点:使用灵活,使用完之后立即释放,不占用物理存储空间 缺点: ...
- 【Beta阶段】团队源代码管理
0. 快速上手与理解 如果你的团队来了一个新队员,有一台全新的机器,你们是否有一个文档,只要设置了相应的权限,她就可以根据文档,从头开始搭建环境,并成功地把最新.最稳定版本的软件编译出来,并运行必要的 ...
- Week2 Bing词典Android客户端案例分析
一.软件调研 运行平台:Android 4.4.4 必应版本:5.2.2 1.bug发现 1.1 bug标题:单词挑战无法加载和刷新 bug详细描述:学习界面中的单词挑战模块,点击后没有任何反映,并且 ...