您的位置:首页 > 理论基础 > 计算机网络

网络分析之最短路径分析

2010-10-27 14:49 465 查看
首先点击“最短路径分析”按钮,创建Route图层。

(1)打开ArcSDE工作空间:

//打开工作空间
private IWorkspace OpenArcSdeWorkspace(string server, string instance, string user, string password, string database, string version)
{
IPropertySet propertySet = new PropertySetClass();
propertySet.SetProperty("SERVER", server);
propertySet.SetProperty("INSTANCE", instance);
propertySet.SetProperty("DATABASE", database);
propertySet.SetProperty("USER", user);
propertySet.SetProperty("PASSWORD", password);
propertySet.SetProperty("VERSION", version);
IWorkspaceFactory2 workspaceFactory = new SdeWorkspaceFactoryClass();
return workspaceFactory.Open(propertySet, 0);
}


(2)获取网络数据集

//获取网络数据集
private INetworkDataset OpenSDENetworkDataset(IWorkspace networkDatasetWorkspace, String networkDatasetName, String featureDatasetName) //SDE.Streets_ND, SDE.shanghai
{
IDatasetContainer3 datasetContainer3 = null;
IFeatureWorkspace featureWorkspace = networkDatasetWorkspace as IFeatureWorkspace;
IFeatureDataset featureDataset = featureWorkspace.OpenFeatureDataset(featureDatasetName);
IFeatureDatasetExtensionContainer featureDatasetExtensionContainer = featureDataset as IFeatureDatasetExtensionContainer;
IFeatureDatasetExtension featureDatasetExtension = featureDatasetExtensionContainer.FindExtension(esriDatasetType.esriDTNetworkDataset);
datasetContainer3 = featureDatasetExtension as IDatasetContainer3;
if (datasetContainer3 == null)
return null;
IDataset dataset = datasetContainer3.get_DatasetByName(esriDatasetType.esriDTNetworkDataset, networkDatasetName);
return dataset as INetworkDataset; // Dynamic Cast
}


(3)创建路径图层

//创建路径图层
private INALayer CreateRouteAnalysisLayer(String layerName, INetworkDataset networkDataset)
{
INARouteSolver naRouteSolver = new NARouteSolverClass();
INASolverSettings naSolverSettings = naRouteSolver as INASolverSettings;
INASolver naSolver = naRouteSolver as INASolver;
//获得网络数据集数据元素
IDatasetComponent datasetComponent = networkDataset as IDatasetComponent;
IDENetworkDataset deNetworkDataset = datasetComponent.DataElement as IDENetworkDataset;
//创建网络分析上下文并且绑定
INAContext naContext;
naContext = naSolver.CreateContext(deNetworkDataset, layerName);
INAContextEdit naContextEdit = naContext as INAContextEdit;
naContextEdit.Bind(networkDataset, new GPMessagesClass());
//创建路径图层
INALayer naLayer;
naLayer = naSolver.CreateLayer(naContext);
(naLayer as ILayer).Name = layerName;
//设置路径属性
if (!naLayer.Context.Solver.CanAccumulateAttributes)
{
naRouteSolver.FindBestSequence = true;
naRouteSolver.PreserveFirstStop = true;
naRouteSolver.PreserveLastStop = false;
naRouteSolver.UseTimeWindows = false;
naRouteSolver.OutputLines = esriNAOutputLineType.esriNAOutputLineTrueShapeWithMeasure;
IStringArray restrictions = naSolverSettings.RestrictionAttributeNames;
restrictions.Add("Oneway");
naSolverSettings.RestrictionAttributeNames = restrictions;
//基于上述设置更新Solver
naSolver.UpdateContext(naContext, deNetworkDataset, new GPMessagesClass());
}


(4)如果Route图层不为NULL则,清除路径

//清除路径
private void ClearBeforeAnalysis()
{
//获得路径图层
ILayer routeLayer = findLayer(m_hookHelper.ActiveView.FocusMap, "Route");
if (routeLayer == null)
return;
IEngineNAWindow naWindow = naEnv.NAWindow;

INALayer naLayer = null;
//获取图层
if (naWindow != null)
naLayer = naWindow.ActiveAnalysis;
INAContext naContext = naLayer.Context;
// 设置活动的当前的网络分析图层
if (naWindow.ActiveAnalysis != naLayer)
naWindow.ActiveAnalysis = naLayer;
try
{
// 记住当前的类别
IEngineNAWindowCategory currentCategory = naWindow.ActiveCategory;
// 循环删除所有的网络分析结果
INamedSet naClasses = naContext.NAClasses;
IEngineNetworkAnalystHelper naHelper = naEnv as IEngineNetworkAnalystHelper;
for (int i = 0; i < naClasses.Count; i++)
{
IEngineNAWindowCategory category = naWindow.get_CategoryByNAClassName(naClasses.get_Name(i));
naWindow.ActiveCategory = category;
naHelper.DeleteAllNetworkLocations();
}
//重置当前类别
naWindow.ActiveCategory = currentCategory;
//刷新地图
IMap map = m_hookHelper.FocusMap;
IActiveView activeView = m_hookHelper.ActiveView;
activeView.Refresh();
}
catch (Exception exception)
{
//MessageBox.Show(exception.Message, "Error");
//todo:异常信息添加到log
}
}


2.并在地图上添加旗标,当第二个旗标添加完后,生成最短路径

public override void OnMouseDown(int Button, int Shift, int X, int Y)
{
try
{
mouseDownCount++;
IEngineNAWindow naWindow = naEnv.NAWindow;
INALayer naLayer = null;
//获取图层
if (naWindow != null)
naLayer = naWindow.ActiveAnalysis;
INAContext naContext = naLayer.Context;
//naContext.Name
INALocator naLocator = naContext.Locator;
IFeatureClass featureClass = naContext.NAClasses.get_ItemByName("Stops") as IFeatureClass;

//获得点击处点
IMap map = m_hookHelper.FocusMap;
IActiveView activeView = m_hookHelper.ActiveView;
IPoint inputPoint = activeView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
INALocation naLocation = new NALocationClass();
IPoint outputPoint = new PointClass();
double distanceToLocation = 99999999;
naLocator.QueryLocationByPoint(inputPoint, ref naLocation, ref outputPoint, ref distanceToLocation);
if (outputPoint == null)
outputPoint = inputPoint;
// 获取要更新要素的字段
int nameFieldIndex = featureClass.FindField("Name");
int statusFieldIndex = featureClass.FindField("Status");
int sequenceFieldIndex = featureClass.FindField("Sequence");

// 开始编辑操作(for undo/redo)
naWindow.StartOperation(naContext);
// 创建地理要素并QI到INALocationObject
IFeature feature = featureClass.CreateFeature();
INALocationObject naLocationObject = (INALocationObject)feature;
// 设置NALocation
naLocationObject.NALocation = naLocation;
// 设置Shape
feature.Shape = outputPoint;
// 设置Name字段
feature.set_Value(nameFieldIndex, outputPoint.X.ToString() + "," + outputPoint.Y.ToString());
// 设置Status字段
if (naLocation.IsLocated)
feature.set_Value(statusFieldIndex, esriNAObjectStatus.esriNAObjectStatusOK);
else feature.set_Value(statusFieldIndex, esriNAObjectStatus.esriNAObjectStatusNotLocated);
// 设置sequence字段 (仅仅在stops起作用)
if (sequenceFieldIndex > 0)
feature.set_Value(sequenceFieldIndex, ((ITable)featureClass).RowCount(null));
// 存储地理要素
feature.Store();
// 停止编辑操作
naWindow.StopOperation(naContext, "Add " + naWindow.ActiveCategory.Layer.Name);
// 刷新map
activeView.Refresh();
//鼠标点击第二个点是生成最短路径
if (mouseDownCount == 2)
{
try
{
//获得网络分析图层
if (naWindow != null)
naLayer = naWindow.ActiveAnalysis;
//求解器Solver求解
//naContext.Solver.Solve(naContext, new GPMessagesClass(), new CancelTrackerClass());
ICommand networkAnalystDirectionsCommand = new ControlsNetworkAnalystDirectionsCommandClass();
networkAnalystDirectionsCommand.OnCreate(m_hookHelper.Hook);
networkAnalystDirectionsCommand.OnClick();
INAStreetDirectionsAgent streetAgent = naContext.Agents.get_ItemByName("StreetDirectionsAgent") as INAStreetDirectionsAgent;
INAStreetDirectionsContainer directionsContainer = streetAgent.DirectionsContainer;
//directionsContainer.SaveAsXML("E://mydire.xml");

int directionsCount = directionsContainer.DirectionsCount;
string routeIdName = string.Empty;
for (int index = 0; index < directionsCount; index++)
{
INAStreetDirections naStreetDirections = directionsContainer.get_Directions(index);
routeString = getDirectionsString(naStreetDirections);
DataTable dataTable = getDataTableFromRouteString(routeString);
m_DataGridViewControl.DataSource = dataTable;
}
IMapControlDefault mapcontrol = m_hookHelper.Hook as IMapControlDefault;
mapcontrol.CurrentTool = null;
//刷新地图
activeView.Refresh();
}
catch (Exception exception)
{
//MessageBox.Show(exception.Message, "Error");
//todo:异常信息添加到log
}
}
}
catch(Exception exception)
{
//MessageBox.Show(exception.Message  ,"Error");
//todo:异常信息添加到log
}

}


3.最短路径在DataGridView中显示出来:

private string getDirectionsString(INAStreetDirections serverDirections)
{
// 得到总的距离和时间
INAStreetDirection direction = serverDirections.Summary;
string totallength = null, totaltime = null;
for (int k = 0; k < direction.StringCount; k++)
{
if (direction.get_StringType(k) == esriDirectionsStringType.esriDSTLength)
totallength = direction.get_String(k);
if (direction.get_StringType(k) == esriDirectionsStringType.esriDSTTime)
totaltime = direction.get_String(k);
}
//MessageBox.Show("Directions for CFRoute [" + (1) + "] - Total Distance: " + totallength + " Total Time: " + totaltime);
string directionString = string.Empty;
// 加节点到方向
for (int directionIndex = 0; directionIndex < serverDirections.DirectionCount; directionIndex++)
{
direction = serverDirections.get_Direction(directionIndex);
for (int stringIndex = 0; stringIndex < direction.StringCount; stringIndex++)
{
if (direction.get_StringType(stringIndex) == esriDirectionsStringType.esriDSTGeneral ||
direction.get_StringType(stringIndex) == esriDirectionsStringType.esriDSTDepart ||
direction.get_StringType(stringIndex) == esriDirectionsStringType.esriDSTArrive ||
direction.get_StringType(stringIndex) == esriDirectionsStringType.esriDSTSummary
)
{
if (stringIndex == 0)
{
directionString += direction.get_String(stringIndex).ToString() + "|";
}
else if (stringIndex == 2)
{
directionString += direction.get_String(stringIndex).ToString() + "@";
}
}
}
}
return directionString;

}
private DataTable getDataTableFromRouteString(string routesString)
{
routesString = routesString.Substring(0, routesString.Length - 1);
string[] routeArray = routesString.Split(new Char[] { '@' });
string firstSecond = routeArray[0];
string[] firstSeconds = firstSecond.Split(new Char[] { '|' });
string firstString = firstSeconds[0];
string secondDirection = firstSeconds[1];
string secondLength = firstSeconds[2];
string endString = routeArray[routeArray.Length - 1];
DataTable table = CreateTableStructure();
DataRow row;
row = table.NewRow();
row["Direction"] = firstString;
row["Length"] = "起点";
table.Rows.Add(row);
row = table.NewRow();
row["Direction"] = secondDirection;
row["Length"] = secondLength;
table.Rows.Add(row);
for (int i = 1; i < routeArray.Length - 1; i++)
{
//MessageBox.Show(routeArray[i]);
string[] temps = routeArray[i].Split(new Char[] { '|' });
string direction = temps[0];
string length = temps[1];
row = table.NewRow();
row["Direction"] = direction;
row["Length"] = length;
table.Rows.Add(row);
}
row = table.NewRow();
row["Direction"] = endString;
row["Length"] = "终点";
table.Rows.Add(row);
return table;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: