📄 pathfinder.cs
字号:
using System;
using System.Collections.Generic;
using System.Text;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.NetworkAnalysis;
using ESRI.ArcGIS.DataSourcesGDB;
using System.Diagnostics;
using System.Windows.Forms;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
namespace Tom.GIS.ArcEngine.NetworkAnalysis
{
/// <summary>
/// 最佳路径分析类(提供分析的方法,结果及一些静态方法)
/// </summary>
public class PathFinder
{
#region 构造函数和变量
private IGeometricNetwork _geometricNetwork;
private IMap _map;
private IPointToEID _pointToEID;
private IEnumNetEID _enumNetEID_Junctions;
private IEnumNetEID _enumNetID_Edges;
private INetElements _netElements;
//保存用户设定的经过和不经过和路口(Junction)及道路(Edge)
public List<IJunctionFlag> junctionFlagList = new List<IJunctionFlag>();
public List<IEdgeFlag> edgeFlagList = new List<IEdgeFlag>();
public List<IJunctionFlag> junctionFlagUnList = new List<IJunctionFlag>();
public List<IEdgeFlag> edgeFlagUnList = new List<IEdgeFlag>();
/// <summary>
/// 生成的最佳路径的长度
/// </summary>
public double PathLength
{
get
{
if (_polyLine != null)
{
return ((int)_polyLine.Length * 100) / 100;
}
else
{
return 0.0;
}
}
}
/// <summary>
/// 用于进行道路引导的描述文字
/// </summary>
public string GuideText
{
get
{
if (_eidHelper == null || _enumNetID_Edges == null)
return "";
IGeoFeatureLayer featureLayer = FunctionFactory.GetLayerByName("道路中心线",esriLayerType.GeoFeatureLayer, SystemFactory.MapControl.Map) as IGeoFeatureLayer;
if (featureLayer == null)
return "";
//解析结果道路序列
IEnumEIDInfo enumEIDInfo = _eidHelper.CreateEnumEIDInfo(_enumNetID_Edges);
enumEIDInfo.Reset();
IEIDInfo eidInfo = enumEIDInfo.Next();
List<NameLength> nameLengthList = new List<NameLength>();
List<string> dirList = new List<string>();
while (eidInfo != null)
{
IFeature feature = eidInfo.Feature;
IGeometry geometry = eidInfo.Geometry;
IPolyline pline = geometry as IPolyline;
if (pline != null)
{
string name = featureLayer.FeatureClass.GetFeature((int)feature.get_Value(0)).get_Value(3).ToString();
double length = pline.Length;
NameLength nameLength = new NameLength();
nameLength.Name = name == "" ? "无名路" : name;
nameLength.Length = length;
bool addFlag = true;
for (int i = 0; i < nameLengthList.Count; i++)
{
if (nameLengthList[i].Name == name)
{
nameLengthList[i].Length += length;
addFlag = false;
break;
}
}
if (addFlag)
{
nameLengthList.Add(nameLength);
IPoint fromPoint = pline.FromPoint;
IPoint toPoint = pline.ToPoint;
string direction = "";
double ratioXY = Math.Abs(fromPoint.X - toPoint.X) / Math.Abs(fromPoint.Y - toPoint.Y);
if (ratioXY >= Math.Tan(22.5 * Math.PI / 180) && ratioXY <= Math.Tan(67.5 * Math.PI / 180))
{
direction = fromPoint.X > toPoint.X ? "西" : "东";
direction += fromPoint.Y > toPoint.Y ? "北" : "南";
}
else if (ratioXY < Math.Tan(22.5 * Math.PI / 180))
{
direction = fromPoint.Y > toPoint.Y ? "南" : "北";
}
else if (ratioXY > Math.Tan(67.5 * Math.PI / 180))
{
direction = fromPoint.X > toPoint.X ? "东" : "西";
}
dirList.Add(direction);
}
}
eidInfo = enumEIDInfo.Next();
}
//对结果字符串进行处理,生成可理解的道路引导字符串
string resultString = "从起点出发,";
for (int i = 0; i < nameLengthList.Count; i++)
{
resultString += "沿" + nameLengthList[i].Name + "往" + dirList[i] + "走"
+ Convert.ToInt32(nameLengthList[i].Length).ToString() +
"米,再";
}
resultString = resultString.Substring(0, resultString.Length - 2);
resultString += "即可到达目的地。";
return resultString;
}
}
/// <summary>
/// 用于存入数据库的最佳路径描述文字
/// </summary>
public string DescriptionText
{
get
{
if (_eidHelper == null)
return "";
IGeoFeatureLayer featureLayer = FunctionFactory.GetLayerByName("道路中心线", esriLayerType.GeoFeatureLayer, SystemFactory.MapControl.Map) as IGeoFeatureLayer;
if (featureLayer == null)
return "";
//解析结果道路序列
IEnumEIDInfo enumEIDInfo = _eidHelper.CreateEnumEIDInfo(_enumNetID_Edges);
enumEIDInfo.Reset();
IEIDInfo eidInfo = enumEIDInfo.Next();
List<NameLength> nameLengthList = new List<NameLength>();
List<string> dirList = new List<string>();
while (eidInfo != null)
{
IFeature feature = eidInfo.Feature;
IGeometry geometry = eidInfo.Geometry;
IPolyline pline = geometry as IPolyline;
if (pline != null)
{
string name = featureLayer.FeatureClass.GetFeature((int)feature.get_Value(0)).get_Value(3).ToString();
double length = pline.Length;
NameLength nameLength = new NameLength();
nameLength.Name = name == "" ? "无名路" : name;
nameLength.Length = length;
bool addFlag = true;
for (int i = 0; i < nameLengthList.Count; i++)
{
if (nameLengthList[i].Name == name)
{
nameLengthList[i].Length += length;
addFlag = false;
break;
}
}
if (addFlag)
{
nameLengthList.Add(nameLength);
}
}
eidInfo = enumEIDInfo.Next();
}
//对结果字符串进行处理,生成可理解的道路引导字符串
string resultString = "";
nameLengthList.ForEach(delegate(NameLength nl)
{
resultString += nl.Name + "," + Convert.ToInt32(nl.Length).ToString() + "|";
});
resultString = resultString.Substring(0, resultString.Length - 1);
return resultString;
}
}
private ISelectionSetBarriers _selSetBarriers = new SelectionSetBarriersClass();
private IEIDHelper _eidHelper;
private IPolyline _polyLine;
/// <summary>
/// 根据点获取附近的点或线对象
/// </summary>
public IPointToEID PointToEID
{
get
{
return _pointToEID;
}
}
/// <summary>
/// EIDHelper
/// </summary>
public IEIDHelper EIDHelper
{
get
{
return _eidHelper;
}
}
/// <summary>
/// NetWork中的元素
/// </summary>
public INetElements NetElements
{
get
{
return _netElements;
}
}
/// <summary>
/// 适合于构造基于SDE数据的对象
/// </summary>
public PathFinder(IPropertySet iPropertySet,string featureDatasetName)
{
_map = SystemFactory.MapControl.Map;
OpenSdeNetwork(iPropertySet,featureDatasetName);
}
/// <summary>
/// 适合于构造基于Personal Geodatabase数据的对象
/// </summary>
/// <param name="fileName"></param>
/// <param name="featureDatasetName"></param>
public PathFinder(string fileName, string featureDatasetName)
{
_map = SystemFactory.MapControl.Map;
OpenAccessNetwork(fileName, featureDatasetName);
}
public IGeometricNetwork GeometryNetwork
{
get
{
return _geometricNetwork;
}
}
/// <summary>
/// 最佳路径Polyline对象
/// </summary>
public IPolyline ResultPolyline
{
get
{
if (_enumNetID_Edges == null)
return null;
if (_polyLine != null)
return _polyLine;
_polyLine = new PolylineClass();
IGeometryCollection geoCollection = _polyLine as IGeometryCollection;
//解析结果道路序列
IEnumEIDInfo enumEIDInfo = _eidHelper.CreateEnumEIDInfo(_enumNetID_Edges);
enumEIDInfo.Reset();
IEIDInfo eidInfo = enumEIDInfo.Next();
while (eidInfo != null)
{
IGeometry geometry = eidInfo.Geometry;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -