前言
网络数据集(Network Dataset)由Feature要素创建,可以构建无向网络。创建的网络能够用来表现复杂场景,包括Multimodal交通网络,同样也可以包含多个网络属性以模拟网络限制条件和层次结构。
网络数据集创建网络的数据源存储于Personal Geodatabase或者shapefile,其中Personal Geodatabase可以存储很多数据源,因此可以构建Multimodal Network,而基于Shapefile文件创建的Network Dataset,因为不能够支持多种Edge 类型,所以不能用于创建Multimodal Network。
网络数据集的相关元素
1、Connectivity
ArcCatlog中创建Network Dataset,需要设置网络的Connectivity(连通性),连通性有下面3中模式:
- Connecting Edges within a Connectivity Group
可以设置“Endpoint Connectivity”,也可以设置“Any Vertex Connectivity”。第一种方式中,边和边只能在终点处相交,第二种方式则可以在边的任意位置相交。
- Connecting Edges through Junctions across Connectivity Group
能够将不同Connectivity Group中的Edge通过被不同Connectivity Group共享的Junctions连接。
- Elevation Fields
主要用于Network Dataset中检查Line Endpoints的Connectivity。每一个Edge Feature具备两个字段用来描述每一个端点的高程。
2、Network Attribute
Network Attribute主要用于设定网络的流通属性,属性有:
- Name:名称
- Usage Type:usage notes类型
- Unit:Centimeter,Meter等等
- Data Types:Boolean,Integer,Float,Double
- Use by Default:设置为默认
- Cost:例如走过某段路需要花费的时间
- Descriptors:对某条道路的描述信息,例如道路速度的限制,有多少个红绿灯等。
- Restrictions:例如某条线是禁行,或者是单向的
- Hierarchy:例如道路的分级
3、Evaluators
Evaluators用来从Network Source中获取网络属性的值。四种Evaluators为:
- Field Evaluator:利用属性字段的值;
- Field Expression Evaluator:利用属性字段构建计算表达式;
- Constant Evaluators:赋予常数;
- VBscript Evaluators:通过执行VBScript代码,主要用于赋予复杂的属性值每个Junction Source和Turn Source需要一个Evaluator,而每个Edge Source需要两个-Edge的每个方向都需要一个Evaluator。
4、Turns
Turn是通过TurnFeatureClass(转向要素集)转变而来的,这些TurnFeatureClass都是Polyline FeatureClass。TurnFeatureClass必须是与其他Network要素位于同一个Feature Dataset中,具备相同的空间参考,不参与Connectivity Groups,也不具备Elevation信息。Turn至少具备两条Edge,至多 20条Edge。
网络分析
1、无向网络的创建
ArcCatlog中创建Network Dataset步骤:
- 打开网络数据集的向导,定义几何网络的名称
- 选择参与网络数据集的要素类
- 设置是否使用转向数据集
- 连通性设置
- 是否使用高程字段模拟连通性
- 设置权重
- 是否建立行驶方向
- 建立Network Dataset
数据源:
创建网络数据集的实现:
/// <summary>
/// 创建无向网络
/// </summary>
/// <param name="_pWsName">个人数据库的路径</param>
/// <param name="_pDatasetName">要素数据集的路径</param>
/// <param name="_pNetName">建立网络的名称</param>
/// <param name="_pFtName">参与网络的要素类</param>
public void CreateNetworkDataset(string _pWsName, string _pDatasetName,
string _pNetName, string _pFtName)
{
IDENetworkDataset pDENetworkDataset = new DENetworkDatasetClass();
pDENetworkDataset.Buildable = true;
IWorkspace pWs = GetWorkspace(_pWsName);
IFeatureWorkspace pFtWs = pWs as IFeatureWorkspace;
IFeatureDataset pFtDataset = pFtWs.OpenFeatureDataset(_pDatasetName);
//定义空间参考
IDEGeoDataset pDEGeoDataset = (IDEGeoDataset)pDENetworkDataset;
IGeoDataset pGeoDataset = pFtDataset as IGeoDataset;
pDEGeoDataset.Extent = pGeoDataset.Extent;
pDEGeoDataset.SpatialReference = pGeoDataset.SpatialReference;
//网络数据集的名称
IDataElement pDataElement = (IDataElement)pDENetworkDataset;
pDataElement.Name = _pNetName;
//参加建立网络数据集的要素类
INetworkSource pEdgeNetworkSource = new EdgeFeatureSourceClass();
pEdgeNetworkSource.Name = _pFtName;
pEdgeNetworkSource.ElementType = esriNetworkElementType.esriNETEdge;
//要素类的连通性
IEdgeFeatureSource pEdgeFeatureSource =
(IEdgeFeatureSource)pEdgeNetworkSource;
pEdgeFeatureSource.UsesSubtypes = false;
pEdgeFeatureSource.ClassConnectivityGroup = 1;
pEdgeFeatureSource.ClassConnectivityPolicy =
esriNetworkEdgeConnectivityPolicy.esriNECPEndVertex;
//不用转弯数据
pDENetworkDataset.SupportsTurns = false;
IArray pSourceArray = new ArrayClass();
pSourceArray.Add(pEdgeNetworkSource);
pDENetworkDataset.Sources = pSourceArray;
//网络数据集的属性设置
IArray pAttributeArray = new ArrayClass();
IEvaluatedNetworkAttribute pEvalNetAttr;
INetworkAttribute2 pNetAttr2;
INetworkFieldEvaluator pNetFieldEval;
INetworkConstantEvaluator pNetConstEval;
pEvalNetAttr = new EvaluatedNetworkAttributeClass();
pNetAttr2 = (INetworkAttribute2)pEvalNetAttr;
pNetAttr2.Name = "Meters";
pNetAttr2.UsageType = esriNetworkAttributeUsageType.esriNAUTCost;
pNetAttr2.DataType = esriNetworkAttributeDataType.esriNADTDouble;
pNetAttr2.Units = esriNetworkAttributeUnits.esriNAUMeters;
pNetAttr2.UseByDefault = false;
pNetFieldEval = new NetworkFieldEvaluatorClass();
pNetFieldEval.SetExpression("[Shape_Length]", "");
//方向设置
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);
//一个网络数据集可以有多个属性
pAttributeArray.Add(pEvalNetAttr);
pDENetworkDataset.Attributes = pAttributeArray;
// 创建网络数据集
IDENetworkDataset2 _pDENetDataset = pDENetworkDataset as IDENetworkDataset2;
IFeatureDatasetExtensionContainer pFeatureDatasetExtensionContainer =
(IFeatureDatasetExtensionContainer)pFtDataset;
IFeatureDatasetExtension pFeatureDatasetExtension =
pFeatureDatasetExtensionContainer.FindExtension(
esriDatasetType.esriDTNetworkDataset);
IDatasetContainer2 pDatasetContainer2 =
(IDatasetContainer2)pFeatureDatasetExtension;
IDEDataset pDENetDataset = (IDEDataset)_pDENetDataset;
INetworkDataset pNetworkDataset =
(INetworkDataset)pDatasetContainer2.CreateDataset(pDENetDataset);
//建立网络
INetworkBuild pNetworkBuild = (INetworkBuild)pNetworkDataset;
pNetworkBuild.BuildNetwork(pGeoDataset.Extent);
}
创建网络数据集后数据变为:
2、最短路径分析
无向网络分析中需要用到两个主要接口:INAContext和INASolver。INAContext主要用来获取网络分析的对象,这些对象包含NetworkDataset、NASolver、NAClasses、NATraversalResult、 NALocator以及任何实现INAAgent接口的对象;INASolver主要用来创建NAContext和NALayer对象来执行实际的网络分析。
INAContext的数据成员为:
INASolver的数据成员为:
最短路径分析的实现:
1、获取网络数据集
/// <summary>
/// 获取网络数据集
/// </summary>
/// <param name="pFeatureDataset">要素集</param>
/// <param name="_pDatasetName">数据集名称</param>
/// <param name="_pNetDatasetName">网络数据集名称</param>
/// <returns>网络数据集</returns>
public INetworkDataset GetNetDataset(IFeatureDataset pFeatureDataset,
string _pDatasetName, string _pNetDatasetName)
{
IFeatureDatasetExtensionContainer pFeatureDatasetExtensionContainer =
pFeatureDataset as IFeatureDatasetExtensionContainer;
IFeatureDatasetExtension pFeatureDatasetExtension =
pFeatureDatasetExtensionContainer.FindExtension(
esriDatasetType.esriDTNetworkDataset);
IDatasetContainer3 pDatasetContainer = pFeatureDatasetExtension as
IDatasetContainer3;
IDataset pNetWorkDataset =
pDatasetContainer.get_DatasetByName(
esriDatasetType.esriDTNetworkDataset, _pNetDatasetName);
return pNetWorkDataset as INetworkDataset;
}
2、创建网络分析上下文
/// <summary>
/// 创建网络分析上下文
/// </summary>
/// <param name="networkDataset">网络数据集</param>
/// <returns>网络分析上下文</returns>
public INAContext CreateNAContext(INetworkDataset networkDataset)
{
IDatasetComponent datasetComponent = networkDataset as IDatasetComponent;
IDENetworkDataset pDENetworkDataset = datasetComponent.DataElement as
IDENetworkDataset;
INASolver pNASolver = new NARouteSolverClass();
INAContextEdit pNAContextEdit = pNASolver.CreateContext(pDENetworkDataset,
pNASolver.Name) as INAContextEdit;
pNAContextEdit.Bind(networkDataset, new GPMessagesClass());
return pNAContextEdit as INAContext;
}
3、添加网络分析图层
/// <summary>
/// 添加网络分析图层
/// </summary>
/// <param name="pNaContext">网络分析上下文</param>
/// <param name="Mainmap">Map控件</param>
public void AddNALayer(INAContext pNaContext,AxMapControl Mainmap)
{
INALayer naLayer = pNaContext.Solver.CreateLayer(pNaContext);
ILayer pLayer = naLayer as ILayer;
pLayer.Name = pNaContext.Solver.DisplayName;
MainMap.AddLayer(pLayer, 0);
}
4、设置Stops要素类
/// <summary>
/// 设置Stops要素类
/// </summary>
/// <param name="_pNaContext">网络分析上下文</param>
/// <param name="_pFtClass">Stops的要素类</param>
/// <param name="_pPointC">路径点集合</param>
/// <param name="_pDist">捕捉距离 </param>
public void NAStops(INAContext _pNaContext, IFeatureClass _pFtClass,
IPointCollection _pPointC, double _pDist)
{
INALocator pNAlocator = _pNaContext.Locator;
for (int i = 0; i < _pPointC.PointCount; i++)
{
IFeature pFt = _pFtClass.CreateFeature();
IRowSubtypes pRowSubtypes = pFt as IRowSubtypes;
pRowSubtypes.InitDefaultValues();
pFt.Shape = _pPointC.get_Point(i) as IGeometry;
IPoint pPoint = null;
INALocation pNalocation = null;
pNAlocator.QueryLocationByPoint(_pPointC.get_Point(i), ref pNalocation,
ref pPoint, ref _pDist);
INALocationObject pNAobject = pFt as INALocationObject;
pNAobject.NALocation = pNalocation;
int pNameFieldIndex = _pFtClass.FindField("Name");
pFt.set_Value(pNameFieldIndex, pPoint.X.ToString() + " , "
+ pPoint.Y.ToString());
int pStatusFieldIndex = _pFtClass.FindField("Status");
pFt.set_Value(pStatusFieldIndex,
esriNAObjectStatus.esriNAObjectStatusOK);
int pSequenceFieldIndex = _pFtClass.FindField("Sequence");
pFt.set_Value(_pFtClass.FindField("Sequence"),
((ITable)_pFtClass).RowCount(null));
pFt.Store();
}
}
5、获取分析信息
IGPMessages gpMessages = new GPMessagesClass();
bool pBool = pNaContext.Solver.Solve(pNaContext, gpMessages, null);
实现结果: