网络分析之最短路径分析

  1. 首先点击“最短路径分析”按钮,创建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; }  

 

 

 

 

 

 

 

 

你可能感兴趣的:(ArcGIS,Engine)