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线文 ...
随机推荐
- 十九、【.Net开源】EFW框架核心类库之WCF控制器
回<[开源]EFW框架系列文章索引> EFW框架源代码下载V1.1:http://pan.baidu.com/s/1qWJjo3U EFW框架实例源代码下载:http://pan.baid ...
- eclipse 手动/自动安装插件
只要你的Eclipse的压缩包,一般为xxx.zip,其内部包含了对应的features和plugins文件夹,(不管是否还有content.jar和artifacts.jar)则都可以: 要么手动解 ...
- fusioncharts图例(legend)属性
图例用来在多系列图和混合图中将图形和对应的系列名称联系起来. 从v3.2开始,每个系列的名称前面会展示对应的icon图标,这些图标具有交互作用,用户可以通过点击这些图标来显示或者隐藏对应的数 ...
- 转iOS中delegate、protocol的关系
iOS中delegate.protocol的关系 分类: iOS Development2014-02-12 10:47 277人阅读 评论(0) 收藏 举报 delegateiosprocotolc ...
- LoRaWAN移植笔记(一)__RTC闹钟链表的实现
近日在阅读semtech的Lora-net/LoRaMac-node.此代码是LoRaWAN MAC层的node段的代码. 此代码中构建了一个定时器链表,此链表构建得非常的巧妙,现在和大家分享. 此定 ...
- 【转载】如何在Ubuntu上安装LAMP服务器系统?
转载自:http://os.51cto.com/art/201307/405333.htm [2013年7月25日 51CTO外电头条]为何应该在Ubuntu上安装LAMP服务器?从事Web开发工作时 ...
- Docker 定制容器镜像的2种方法
一.需求 由于在测试环境中使用了docker官网的centos 镜像,但是该镜像里面默认没有安装ssh服务,在做测试时又需要开启ssh.所以上网也查了查资料.下面详细的纪录下.在centos 容器内安 ...
- rsync同步Nginx日志遇到问题总结
一.目的 将nginx 日志通过普通用户利用rsync公钥认证的方式实时同步到本地服务器上,之后使用elk程序进行处理. 二.遇到问题及解决方法思路 问题1.文件权限:nginx 的日志默认权限如下: ...
- awk分隔符设定为多个字符或字符串
awk -F"[01]" '{}' 这种形式指定的分隔符是或的关系,即0或1作为分隔符:awk -F"[0][1]" '{}' 这种形式指定的分隔符是合并的关 ...
- JavaScript基础概念
1.JavaScript在浏览器中是解释执行的: 2.JavaScript是一中弱类型的语言,在使用变量前,可以不用先申明: 3.JavaScript使用了对象对象程序设计思想: 4.JavaScri ...