实例介绍
【实例简介】
GIS最短路径实例
【实例截图】
【核心代码】
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.IO; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.DataSourcesFile; using ESRI.ArcGIS.DataSourcesGDB; using ESRI.ArcGIS.ADF; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Controls; using ESRI.ArcGIS.Display; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Geometry; using ESRI.ArcGIS.NetworkAnalyst; using ESRI.ArcGIS.NetworkAnalysis; using ESRI.ArcGIS.SystemUI; using ESRI.ArcGIS.CartoUI; using ESRI.ArcGIS.CatalogUI; using ESRI.ArcGIS.Catalog; namespace shortPath { public partial class Form1 : Form { private IGeometricNetwork My_IGeometricNetwork;//声明一个几何网络 //private IMap My_IMap;//声明一个IMap接口用于控制地图数据和相关的元素,是完成与Map有关任务的起点。可以添加,删除图层,访问各种数据源和Map的各种特性,以及通过各种方式选择要素。 private IPointCollection My_IPoints;//输入点集合 private IPointToEID My_IPointToEID;//根据指定点发现距离其最近的网络元素的标志码(ID) private double My_PathCost;//路径分析的成本 private IEnumNetEID My_IEnumNetEID_Junctions;//接点 private IEnumNetEID My_IEnumNetEID_Edges;//边 private IPolyline My_IPolyline;//多边形 // private IActiveView My_IActiveView;//获取当前的视图,包括所有的画操作。常用其Refresh方法。 private bool clicked;//判断是否点击 public Form1() { InitializeComponent(); // My_IActiveView = this.axMapControl1.ActiveView;//获得当前地图的视图 // My_IMap = My_IActiveView.FocusMap;//获得当前的地图 clicked = false; //MyGC = My_IMap as IGraphicsContainer; } private void CloseWorkspace() { My_IGeometricNetwork = null; My_IPoints = null; My_IPointToEID = null; My_IEnumNetEID_Junctions = null; My_IEnumNetEID_Edges = null; My_IPolyline = null; } private void JunctionSolvePath(string WeightName) { try { int JunctionEID; int UserClassID, UserID, UserSubID; IPoint My_FoundJunctionPoint; ITraceFlowSolverGEN My_TraceFlowSolver = new TraceFlowSolverClass() as ITraceFlowSolverGEN; INetSolver My_NetSolver = My_TraceFlowSolver as INetSolver; INetwork My_Network = My_IGeometricNetwork.Network; if (My_Network == null) { MessageBox.Show("My_Network为空,退出!"); return; } My_NetSolver.SourceNetwork = My_Network; INetElements My_NetElements = My_Network as INetElements; int count = My_IPoints.PointCount; if (count == 0) { MessageBox.Show("点集为空,退出!"); return; } //定义一个Junction旗数组 IJunctionFlag[] My_JunctionFlags = new JunctionFlagClass[count]; for (int i = 0; i < count; i ) { INetFlag My_NetFlag = new JunctionFlagClass() as INetFlag; //此处若是地图上的点就不处理若,不是就把屏幕上的点转换成地图中的点 IActiveView activeView = this.axMapControl1.ActiveView as IActiveView; double x = this.My_IPoints.get_Point(i).X; double y = this.My_IPoints.get_Point(i).Y; IPoint point = activeView.ScreenDisplay.DisplayTransformation.ToMapPoint(Convert.ToInt32(x), Convert.ToInt32(y)); IPoint My_JunctionPoint; if(My_IPoints.get_Point(i).X>2000) { My_JunctionPoint = My_IPoints.get_Point(i); } else { My_JunctionPoint= point; } if (My_JunctionPoint == null) { MessageBox.Show("输入的点值为空,返回!"); return; } //MessageBox.Show(My_EdgePoint.X.ToString()); //MessageBox.Show(My_EdgePoint.Y.ToString()); //查找输入点的最近的Junction My_IPointToEID.GetNearestJunction(My_JunctionPoint,out JunctionEID,out My_FoundJunctionPoint); if (JunctionEID == 0) { MessageBox.Show("查找最近的Junction出错,返回!"); return; } My_NetElements.QueryIDs(JunctionEID,esriElementType.esriETJunction,out UserClassID,out UserID,out UserSubID); My_NetFlag.UserClassID = UserClassID; My_NetFlag.UserID = UserID; My_NetFlag.UserSubID = UserSubID; My_JunctionFlags[i] = My_NetFlag as IJunctionFlag; } //找到距输入点最近的Junction My_TraceFlowSolver.PutJunctionOrigins(ref My_JunctionFlags); //要用到网络的权重,所以要到INetSchema接口 INetSchema My_NetSchema = My_Network as INetSchema; //网络权重 INetWeight My_NetWeight = My_NetSchema.get_WeightByName(WeightName); if (My_NetWeight == null) { MessageBox.Show("网络权重为空,退出!"); return; } INetSolverWeights My_NetSolverWeight = My_TraceFlowSolver as INetSolverWeights; if (My_NetSolverWeight == null) { MessageBox.Show("My_NetSolverWeight为空!"); return; } //开始边线的权重 My_NetSolverWeight.FromToEdgeWeight = My_NetWeight; //终止边线的权重 My_NetSolverWeight.ToFromEdgeWeight = My_NetWeight; object[] vaRes = new object[count - 1]; //通过findPath得到的边线和交汇点的集合 My_TraceFlowSolver.FindPath(esriFlowMethod.esriFMConnected, esriShortestPathObjFn.esriSPObjFnMinSum, out My_IEnumNetEID_Junctions, out My_IEnumNetEID_Edges, count - 1, ref vaRes); //My_TraceFlowSolver.FindPath(esriFlowMethod.esriFMUpstream, esriShortestPathObjFn.esriSPObjFnMinSum, out My_IEnumNetEID_Junctions, out My_IEnumNetEID_Edges, count - 1, ref vaRes); if (My_IEnumNetEID_Edges == null) { MessageBox.Show("查找路径出错,返回!"); return; } else { //获取几何列 My_IPolyline = new PolylineClass() as IPolyline; IGeometryCollection My_NewGeometryColl = My_IPolyline as IGeometryCollection; ISpatialReference My_SpatialReference = this.axMapControl1.SpatialReference; IEIDHelper My_EIDHelper = new EIDHelperClass() as IEIDHelper; My_EIDHelper.GeometricNetwork = My_IGeometricNetwork; My_EIDHelper.OutputSpatialReference = My_SpatialReference; My_EIDHelper.ReturnGeometries = true; IEnumEIDInfo My_EnumEIDInfo; My_EnumEIDInfo = My_EIDHelper.CreateEnumEIDInfo(My_IEnumNetEID_Edges); int InfoCount; InfoCount = My_EnumEIDInfo.Count; My_EnumEIDInfo.Reset(); for (int i = 0; i < InfoCount; i ) { IEIDInfo My_EIDInfo; My_EIDInfo = My_EnumEIDInfo.Next(); IGeometry My_Geometry; My_Geometry = My_EIDInfo.Geometry; IGeometryCollection GeoColl = My_Geometry as IGeometryCollection; My_NewGeometryColl.AddGeometryCollection(GeoColl); } if (My_IPolyline == null) { MessageBox.Show("线集合为空,返回!"); return; } if (clicked) { IScreenDisplay My_ScreenDisplay; ILineSymbol My_LineSymbol = new CartographicLineSymbolClass() as ILineSymbol; IMap My_Map; IActiveView My_ActiveView = this.axMapControl1.ActiveView; My_Map = My_ActiveView.FocusMap; My_ScreenDisplay = My_ActiveView.ScreenDisplay; if (My_ScreenDisplay == null) return; //My_NetPT = My_IActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y); //设置显示的颜色和线宽特征 IRgbColor My_RgbCol = new RgbColorClass() as IRgbColor; My_RgbCol.Red = 255; My_LineSymbol.Color = My_RgbCol; My_LineSymbol.Width = 5; //在屏幕上显示网络分析结果 //My_ScreenDisplay.StartDrawing(My_ActiveView.ScreenDisplay.hDC, (short)esriScreenCache.esriNoScreenCache); ISymbol My_Symbol; My_Symbol = My_LineSymbol as ISymbol; if (My_Symbol == null) return; My_ScreenDisplay.StartDrawing(My_ActiveView.ScreenDisplay.hDC, (short)esriScreenCache.esriNoScreenCache); My_ScreenDisplay.SetSymbol(My_Symbol); My_ScreenDisplay.DrawPolyline(My_IPolyline); My_ScreenDisplay.FinishDrawing(); } } //计算元素的成本 My_PathCost = 0; for (int i = 0; i < vaRes.Length; i ) { double My_Va = Convert.ToDouble(vaRes[i]); My_PathCost = My_Va; } //取生成的成本的小数点后的两位 string PathCost = My_PathCost.ToString(); string CutStr = PathCost.Substring(PathCost.LastIndexOf('.') 1, 2); string s = Convert.ToInt32(My_PathCost).ToString() "." CutStr; MessageBox.Show("总的最小成本为:" s); } catch (Exception ee) { MessageBox.Show(ee.Source ee.Message); } } private void EdgeSolvePath(string WeightName) { try { int EdgeUserClassID, EdgeUserID, EdgeUserSubID, EdgeID; double dblEdgePercent; //ISpatialReference My_SpatialReference; IPoint My_FoundEdgePoint; ITraceFlowSolverGEN My_TraceFlowSolver = new TraceFlowSolverClass() as ITraceFlowSolverGEN; INetSolver My_NetSolver = My_TraceFlowSolver as INetSolver; INetwork My_Network = My_IGeometricNetwork.Network; if (My_Network == null) { MessageBox.Show("My_Network为空,退出!"); return; } My_NetSolver.SourceNetwork = My_Network; INetElements My_NetElements = My_Network as INetElements; int count = My_IPoints.PointCount; if (count == 0) { MessageBox.Show("点集为空,退出!"); return; } //IMap My_Map = this.axMapControl1.ActiveView.FocusMap; //My_SpatialReference = My_Map.SpatialReference; //if (My_SpatialReference == null) return; //定义一个边线旗数组 IEdgeFlag[] My_EdgeFlags = new EdgeFlagClass[count]; for (int i = 0; i < count; i ) { INetFlag My_NetFlag = new EdgeFlagClass() as INetFlag; //此处的点必须转换成地图中的点 //My_NetPT = this.axMapControl1.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y); //int x, y; //x=My_IPoints.get_Point(i).X; //y=My_IPoints.get_Point(i).Y; //IPoint My_EdgePoint = this.axMapControl1.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x,y); IActiveView activeView = this.axMapControl1.ActiveView as IActiveView; double x = this.My_IPoints.get_Point(i).X; double y = this.My_IPoints.get_Point(i).Y; IPoint point = activeView.ScreenDisplay.DisplayTransformation.ToMapPoint(Convert.ToInt32(x), Convert.ToInt32(y)); IPoint My_EdgePoint; if (My_IPoints.get_Point(i).X > 2000) { My_EdgePoint = My_IPoints.get_Point(i); } else { My_EdgePoint = point; } //IPoint My_EdgePoint = My_IPoints.get_Point(i); if (My_EdgePoint == null) { MessageBox.Show("输入的点值为空,返回!"); return; } //MessageBox.Show(My_EdgePoint.X.ToString()); //MessageBox.Show(My_EdgePoint.Y.ToString()); //查找输入点的最近的边 My_IPointToEID.GetNearestEdge(My_EdgePoint, out EdgeID, out My_FoundEdgePoint, out dblEdgePercent); if (EdgeID == 0) { MessageBox.Show("查找最进的边出错,返回!");return; } //MessageBox.Show(EdgeID.ToString()); My_NetElements.QueryIDs(EdgeID, esriElementType.esriETEdge, out EdgeUserClassID, out EdgeUserID, out EdgeUserSubID); My_NetFlag.UserClassID = EdgeUserClassID; My_NetFlag.UserID = EdgeUserID; My_NetFlag.UserSubID = EdgeUserSubID; My_EdgeFlags[i] = My_NetFlag as IEdgeFlag; //MessageBox.Show(My_NetFlag.ToString()); } My_TraceFlowSolver.PutEdgeOrigins(ref My_EdgeFlags); //要用到网络的权重,所以要到INetSchema接口 INetSchema My_NetSchema = My_Network as INetSchema; //网络权重 INetWeight My_NetWeight = My_NetSchema.get_WeightByName(WeightName); if (My_NetWeight == null) { MessageBox.Show("网络权重为空,退出!"); return; } INetSolverWeights My_NetSolverWeight = My_TraceFlowSolver as INetSolverWeights; if (My_NetSolverWeight == null) { MessageBox.Show("My_NetSolverWeight为空!"); return; } //开始边线的权重 My_NetSolverWeight.FromToEdgeWeight = My_NetWeight; //终止边线的权重 My_NetSolverWeight.ToFromEdgeWeight = My_NetWeight; object[] vaRes = new object[count-1]; //通过findPath得到的边线和交汇点的集合 My_TraceFlowSolver.FindPath(esriFlowMethod.esriFMConnected, esriShortestPathObjFn.esriSPObjFnMinSum, out My_IEnumNetEID_Junctions, out My_IEnumNetEID_Edges, count - 1, ref vaRes); if (My_IEnumNetEID_Edges == null) { MessageBox.Show("查找路径出错,返回!"); return; } else { //获取几何列 My_IPolyline = new PolylineClass() as IPolyline; IGeometryCollection My_NewGeometryColl = My_IPolyline as IGeometryCollection; ISpatialReference My_SpatialReference = this.axMapControl1.SpatialReference; IEIDHelper My_EIDHelper = new EIDHelperClass() as IEIDHelper; My_EIDHelper.GeometricNetwork = My_IGeometricNetwork; My_EIDHelper.OutputSpatialReference = My_SpatialReference; My_EIDHelper.ReturnGeometries = true; IEnumEIDInfo My_EnumEIDInfo; My_EnumEIDInfo = My_EIDHelper.CreateEnumEIDInfo(My_IEnumNetEID_Edges); int InfoCount; InfoCount = My_EnumEIDInfo.Count; My_EnumEIDInfo.Reset(); for (int i = 0; i < InfoCount; i ) { IEIDInfo My_EIDInfo; My_EIDInfo = My_EnumEIDInfo.Next(); IGeometry My_Geometry; My_Geometry = My_EIDInfo.Geometry; IGeometryCollection GeoColl = My_Geometry as IGeometryCollection; My_NewGeometryColl.AddGeometryCollection(GeoColl); } if (My_IPolyline == null) { MessageBox.Show("线集合为空,返回!"); return; } if (clicked) { IScreenDisplay My_ScreenDisplay; ILineSymbol My_LineSymbol = new CartographicLineSymbolClass() as ILineSymbol; IMap My_Map; IActiveView My_ActiveView = this.axMapControl1.ActiveView; My_Map = My_ActiveView.FocusMap; My_ScreenDisplay = My_ActiveView.ScreenDisplay; if (My_ScreenDisplay == null) return; //My_NetPT = My_IActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y); //设置显示的颜色和线宽特征 IRgbColor My_RgbCol = new RgbColorClass() as IRgbColor; My_RgbCol.Red = 255; My_LineSymbol.Color = My_RgbCol; My_LineSymbol.Width = 5; //在屏幕上显示网络分析结果 //My_ScreenDisplay.StartDrawing(My_ActiveView.ScreenDisplay.hDC, (short)esriScreenCache.esriNoScreenCache); ISymbol My_Symbol; My_Symbol = My_LineSymbol as ISymbol; if (My_Symbol == null) return; //IRubberBand rubberLine = new RubberLineClass(); //IPolyline newPolyline = (IPolyline)rubberLine.TrackNew(My_ScreenDisplay, My_Symbol); //My_IPolyline = newPolyline; My_ScreenDisplay.StartDrawing(My_ActiveView.ScreenDisplay.hDC, (short)esriScreenCache.esriNoScreenCache); My_ScreenDisplay.SetSymbol(My_Symbol); My_ScreenDisplay.DrawPolyline(My_IPolyline); //My_ScreenDisplay.SetSymbol(My_Symbol); //My_ScreenDisplay.DrawPolyline(My_IPolyline); My_ScreenDisplay.FinishDrawing(); } } //计算元素的成本 My_PathCost = 0; for (int i = 0; i < vaRes.Length; i ) { double My_Va = Convert.ToDouble(vaRes[i]); My_PathCost = My_Va; } //取生成的成本的小数点后的两位 string PathCost = My_PathCost.ToString(); string CutStr = PathCost.Substring(PathCost.LastIndexOf('.') 1,2); string s=Convert.ToInt32(My_PathCost).ToString() "." CutStr; MessageBox.Show("总的最小成本为:" s); //清空路径分析结果 //My_IPolyline = null; //clicked = true; //PathPolyLine(); } catch (Exception ee) { MessageBox.Show(ee.Source ee.Message); } } private void 打开ToolStripMenuItem_Click(object sender, EventArgs e) { IGxDialog My_IGxDialog = new GxDialogClass() as IGxDialog; IGxObjectFilter My_IGxObjectFilter = new GxFilterGeometricNetworksClass() as IGxObjectFilter; IEnumGxObject My_IEnumGxObject; IGxObject My_IGxObject; IGeometricNetwork My_GeometricNetwork; IDataset My_IDataset; IGxDataset My_IGxDataset; //bool Result; //设置My_GxDialog,并通过My_GxObjectFilter限制数据源 My_IGxDialog.AllowMultiSelect = false; My_IGxDialog.Title = "选择几何网络数据"; My_IGxDialog.ObjectFilter = My_IGxObjectFilter; object StarLoc = "E:"; My_IGxDialog.set_StartingLocation(ref StarLoc); //打开对话框并选取几何网络 My_IGxDialog.DoModalOpen(0, out My_IEnumGxObject); My_IEnumGxObject.Reset(); My_IGxObject = My_IEnumGxObject.Next(); //如果选取为空或者不是几何网络类型,则退出 if (My_IGxObject == null) { return; } else { My_IGxDataset = My_IGxObject as IGxDataset; } if (My_IGxDataset == null) { return; } else { esriDatasetType My_DatasetType; My_DatasetType = My_IGxDataset.Type; if (My_DatasetType != esriDatasetType.esriDTGeometricNetwork) { return; } } My_IDataset = My_IGxDataset.Dataset; if (My_IDataset == null) { return; } else { //获取几何网络中的网络要素,并加入到地图中 My_GeometricNetwork = My_IDataset as IGeometricNetwork; if (My_GeometricNetwork == null) { return; } IFeatureClass My_IFeatureClass; IMap My_IMap = this.axMapControl1.ActiveView.FocusMap; IFeatureClassContainer My_IFeatureClassContainer = My_GeometricNetwork as IFeatureClassContainer; if (My_IFeatureClassContainer == null) { return; } int Count; Count = My_IFeatureClassContainer.ClassCount; for (int i = 0; i < Count; i ) { My_IFeatureClass = My_IFeatureClassContainer.get_Class(i); if (My_IFeatureClass == null) return; IFeatureLayer My_IFeatureLayer = new FeatureLayerClass() as IFeatureLayer; My_IFeatureLayer.FeatureClass = My_IFeatureClass; My_IMap.AddLayer(My_IFeatureLayer); } IActiveView My_IActiveView = this.axMapControl1.ActiveView; My_IActiveView.Refresh(); //赋值并初始化网络 My_IGeometricNetwork = My_GeometricNetwork; InitializeNetwork(); } } //初始化网络数据 private void InitializeNetwork() { int count, i; IEnvelope My_Env; IEnvelope My_MaxEnv = new EnvelopeClass() as IEnvelope; ILayer My_Layer; IFeatureLayer My_FeaLay; IGeoDataset My_GDS; double dblWidth, dblHeight, dblSearchTol; //计算地图中所有图层范围并取其并集 IMap My_Map = this.axMapControl1.ActiveView.FocusMap; count = My_Map.LayerCount; for (i = 0; i < count; i ) { My_Layer = My_Map.get_Layer(i); if (My_Layer == null) return; My_FeaLay = My_Layer as IFeatureLayer; if (My_FeaLay != null) { My_GDS = My_FeaLay as IGeoDataset; My_Env = My_GDS.Extent; if (My_Env == null) return; My_MaxEnv.Union(My_Env); if (My_MaxEnv == null) return; } } //设置My_PointToEID,并以图层宽度的1%来设置捕捉容限 IPointToEID My_PointToEID = new PointToEIDClass() as IPointToEID; My_IPointToEID = My_PointToEID; My_IPointToEID.SourceMap = My_Map; My_IPointToEID.GeometricNetwork = My_IGeometricNetwork; dblWidth = My_MaxEnv.Width; if (dblWidth == 0) return; dblHeight = My_MaxEnv.Height; if (dblHeight == 0) return; if (dblWidth > dblHeight) { dblSearchTol = dblWidth / 10; } else { dblSearchTol = dblHeight / 10; } if (dblSearchTol == 0) return; My_IPointToEID.SnapTolerance = dblSearchTol; } private void 退出ToolStripMenuItem_Click(object sender, EventArgs e) { this.CloseWorkspace(); this.Close(); }
标签: GIS最短路径
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论