实例介绍
【实例简介】
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小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论