资源描述
. .
AE开发之基于几何网络的最短路径分析
1、实习目的
本次实习目的在于熟练掌握ArcGIS Engine开发工具并能够通过C#语言在VS 2021开发环境中完成查询几何网络的最短路径分析的功能。
2、实习时间
2021 年5月23日星期六
3、实习容
3.1实验环境
操作系统:Windows 2007
二次开发平台:VS 2021开发环境、ArcGIS Desktop10.0、AE开发组件
3.2实验任务
完成基于几何网络分析的最短路径查询功能,即实现通过在几何网络地图中指定起始点,能够查询经过起始点的最短路线,并能够通过缩放功能在地图窗口居中显示。
3.3实验步骤
3.3.1新建工程
选择\文件\新建工程,如图选择工程类型中Visual C#,再选择Windows Application,记为“FindShortPath〞,点击确定。
3.3.2添加控件
3.3.3控件绑定
因为添加的控件只是单独存在,但是程序需要各控件间协同工作,因此要进展控件绑定。
3.3.4创立几何网络
1.在ArcCataLog中新建个人地理数据库—“甘地的个人地理数据库〞,然后新建要素数据集“road〞,接着,鼠标右键选择要素数据集“road〞,选择“导入要素类〞,导入需要创立几何网络的要素类“主要公路〞,输出要素类的名字改为“road〞,如以下图所示:
2.鼠标右键选择要素数据集“road〞,选择新建“几何网络〞,那么出现“新建几何网络〞对话框,作如以下图所示的一系列设置,最终得到几何网络“road_Net〞。
至此,得到几何网络“road_Net〞,如以下图所示:
3.3.5代码实现最短路径分析
① 设置ToolStrip1
② 添加代码
private IActiveView m_ipActiveView;
private IMap m_ipMap;//地图控件中地图
private IGraphicsContainer pGC;//图形对象
private bool clicked = false;
int clickedcount = 0;
private double m_dblPathCost = 0;
private IGeometrietwork m_ipGeometrietwork;
private IPointCollection m_ipPoints;//输入点集合
private IPointToEID m_ipPointToEID;
private IEnumNetEID m_ipEnumNetEID_Junctions;
private IEnumNetEID m_ipEnumNetEID_Edges;
private IPolyline m_ipPolyline;
private IMapControl3 mapctrlMainMap = null;
private void Form1_Load(object sender, EventArgs e)
{
//对象初始化
mapctrlMainMap = (IMapControl3)this.axMapControl1.Object;
m_ipActiveView = axMapControl1.ActiveView;
m_ipMap = m_ipActiveView.FocusMap;
clicked = false;
pGC = m_ipMap as IGraphicsContainer;
}
private void Findpath_Click(object sender, EventArgs e)
{
mapctrlMainMap.CurrentTool = null;
//设置鼠标样式
axMapControl1.MousePointer = esriControlsMousePointer.esriPointerCrosshair;
if (axMapControl1.LayerCount == 0)
{
MessageBox.Show("请先加载几何网络数据!");
return;
}
m_ipActiveView = axMapControl1.ActiveView;
m_ipMap = m_ipActiveView.FocusMap;
clicked = false;
pGC = m_ipMap as IGraphicsContainer;
ILayer ipLayer = m_ipMap.get_Layer(0);
IFeatureLayer ipFeatureLayer = ipLayer as IFeatureLayer;
IFeatureDataset ipFDS = ipFeatureLayer.FeatureClass.FeatureDataset;
OpenFeatureDatasetNetwork(ipFDS);
clicked = true;
clickedcount = 0;
pGC.DeleteAllElements();
}
private void SolvePath_Click(object sender, EventArgs e)
{
axMapControl1.MousePointer = esriControlsMousePointer.esriPointerDefault;
if (SolvePathGan("Weight"))//先解析路径
{
IPolyline ipPolyResult = PathPolyLine();//最后返回最短路径
clicked = false;
if (ipPolyResult.IsEmpty)
{
MessageBox.Show("没有路径可到!!");
}
else
{
IRgbColor color = new RgbColorClass();
color.Red = 255;
color.Blue = 64;
color.Green = 128;
LineElementClass element = new LineElementClass();
ILineSymbol linesymbol = new SimpleLineSymbolClass();
linesymbol.Color = color as IColor;
linesymbol.Width = 3;
element.Geometry = m_ipPolyline;
element.Symbol = linesymbol;
pGC.AddElement(element, 0);
m_ipActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
axMapControl1.FlashShape(element.Geometry);
MessageBox.Show("路径经过" + m_ipEnumNetEID_Edges.Count + "条线" + "\r\n" + "经过节点数为" + m_ipEnumNetEID_Junctions.Count + "\r\n" + "路线长度为" + m_ipPolyline.Length.ToString("#######.##") + "\r\n", "几何路径信息");
}
}
}
//路径缩放功能
private void SuoFang_Click(object sender, EventArgs e)
{
if (m_ipPolyline == null)
{
MessageBox.Show("当前没有执行路径查询!!!请确认!");
}
else
{
this.axMapControl1.Extent = m_ipPolyline.Envelope;
}
}
#region 自定义路径查询函数
public void OpenFeatureDatasetNetwork(IFeatureDataset FeatureDataset)
{
CloseWorkspace();
if (!InitializeNetworkAndMap(FeatureDataset))
Console.WriteLine("翻开network出错");
}
//关闭工作空间
private void CloseWorkspace()
{
m_ipGeometrietwork = null;
m_ipPoints = null;
m_ipPointToEID = null;
m_ipEnumNetEID_Junctions = null;
m_ipEnumNetEID_Edges = null;
m_ipPolyline = null;
}
//初始化几何网络和地图
private bool InitializeNetworkAndMap(IFeatureDataset FeatureDataset)
{
IFeatureClassContainer ipFeatureClassContainer;
IFeatureClass ipFeatureClass;
IGeoDataset ipGeoDataset;
ILayer ipLayer;
IFeatureLayer ipFeatureLayer;
IEnvelope ipEnvelope, ipMaxEnvelope;
double dblSearchTol;
INetworkCollection ipNetworkCollection = FeatureDataset as INetworkCollection;
int count = ipNetworkCollection.GeometrietworkCount;
//获取第一个几何网络工作空间
m_ipGeometrietwork = ipNetworkCollection.get_Geometrietwork(0);
INetwork ipNetwork = m_ipGeometrietwork.Network;
if (m_ipMap != null)
{
ipFeatureClassContainer = m_ipGeometrietwork as IFeatureClassContainer;
count = ipFeatureClassContainer.ClassCount;
for (int i = 0; i < count; i++)
{
ipFeatureClass = ipFeatureClassContainer.get_Class(i);
ipFeatureLayer = new FeatureLayerClass();
ipFeatureLayer.FeatureClass = ipFeatureClass;
for (int j = 0; j < m_ipMap.LayerCount; j++)
{
if (m_ipMap.get_Layer(j).Name.ToUpper() == ipFeatureLayer.Name.ToUpper())
{
continue;
}
}
}
}
count = m_ipMap.LayerCount;
ipMaxEnvelope = new EnvelopeClass();
for (int i = 0; i < count; i++)
{
ipLayer = m_ipMap.get_Layer(i);
ipFeatureLayer = ipLayer as IFeatureLayer;
ipGeoDataset = ipFeatureLayer as IGeoDataset;
ipEnvelope = ipGeoDataset.Extent;
ipMaxEnvelope.Union(ipEnvelope);
}
m_ipPointToEID = new PointToEIDClass();
m_ipPointToEID.SourceMap = m_ipMap;
m_ipPointToEID.Geometrietwork = m_ipGeometrietwork;
double dblWidth = ipMaxEnvelope.Width;
double dblHeight = ipMaxEnvelope.Height;
if (dblWidth > dblHeight)
dblSearchTol = dblWidth / 100;
else
dblSearchTol = dblHeight / 100;
m_ipPointToEID.SnapTolerance = dblSearchTol;
return true;
}
//返回路径的几何体
public IPolyline PathPolyLine()
{
IEIDInfo ipEIDInfo;
IGeometry ipGeometry;
if (m_ipPolyline != null) return m_ipPolyline;
m_ipPolyline = new PolylineClass();
IGeometryCollection ipNewGeometryColl = m_ipPolyline as IGeometryCollection;//引用传递
ISpatialReference ipSpatialReference = m_ipMap.SpatialReference;
IEIDHelper ipEIDHelper = new EIDHelper();
ipEIDHelper.Geometrietwork = m_ipGeometrietwork;
ipEIDHelper.OutputSpatialReference = ipSpatialReference;
ipEIDHelper.ReturnGeometries = true;
IEnumEIDInfo ipEnumEIDInfo = ipEIDHelper.CreateEnumEIDInfo(m_ipEnumNetEID_Edges);
int count = ipEnumEIDInfo.Count;
ipEnumEIDInfo.Reset();
for (int i = 0; i < count; i++)
{
string[] info;
info = new string[count];
ipEIDInfo = ipEnumEIDInfo.Next();
ipGeometry = ipEIDInfo.Geometry;
ipNewGeometryColl.AddGeometryCollection(ipGeometry as IGeometryCollection);
info[i] = m_ipPolyline.Length.ToString();
}
return m_ipPolyline;
}
public bool SolvePathGan(string WeightName)
{
try
{
int intJunctionUserClassID;
int intJunctionUserID;
int intJunctionUserSubID;
int intJunctionID;
IPoint ipFoundJunctionPoint;
ITraceFlowSolverGEN ipTraceFlowSolver = new TraceFlowSolver() as ITraceFlowSolverGEN;
INetSolver ipNetSolver = ipTraceFlowSolver as INetSolver;
if (m_ipGeometrietwork == null)
{
return false;
}
INetwork ipNetwork = m_ipGeometrietwork.Network;
ipNetSolver.SourceNetwork = ipNetwork;
INetElements ipNetElements = ipNetwork as INetElements;
if (m_ipPoints == null)
{ MessageBox.Show("请选择点!!"); return false; }
int intCount = m_ipPoints.PointCount;//这里的points有值吗?
////定义一个边线旗数组
//*********最近点***************//////////
IJunctionFlag[] pJunctionFlagList = new JunctionFlag[intCount];
for (int i = 0; i < intCount; i++)
{
INetFlag ipNetFlag = new JunctionFlag() as INetFlag;
IPoint ipJunctionPoint = m_ipPoints.get_Point(i);
//查找输入点的最近的网络点
m_ipPointToEID.GetNearestJunction(ipJunctionPoint, out intJunctionID, out ipFoundJunctionPoint);
ipNetElements.QueryIDs(intJunctionID, esriElementType.esriETJunction, out intJunctionUserClassID, out intJunctionUserID, out intJunctionUserSubID);
ipNetFlag.UserClassID = intJunctionUserClassID;
ipNetFlag.UserID = intJunctionUserID;
ipNetFlag.UserSubID = intJunctionUserSubID;
IJunctionFlag pTemp = (IJunctionFlag)(ipNetFlag as IJunctionFlag);
pJunctionFlagList[i] = pTemp;
}
ipTraceFlowSolver.PutJunctionOrigins(ref pJunctionFlagList);
INetSchema ipNetSchema = ipNetwork as INetSchema;
INetWeight ipNetWeight = ipNetSchema.get_WeightByName(WeightName);
INetSolverWeights ipNetSolverWeights = ipTraceFlowSolver as INetSolverWeights;
ipNetSolverWeights.FromToEdgeWeight = ipNetWeight;//开场边线的权重
ipNetSolverWeights.ToFromEdgeWeight = ipNetWeight;//终止边线的权重
object[] vaRes = new object[intCount - 1];
//通过findpath得到边线和交汇点的集合
ipTraceFlowSolver.FindPath(esriFlowMethod.esriFMConnected,
esriShortestPathObjFn.esriSPObjFnMinSum,out m_ipEnumNetEID_Junctions, out m_ipEnumNetEID_Edges, intCount - 1, ref vaRes);
m_dblPathCost = 0;
for (int i = 0; i < vaRes.Length; i++)
{
double m_Va = (double)vaRes[i];
m_dblPathCost = m_dblPathCost + m_Va;
}
m_ipPolyline = null;
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message); return false;
}
#endregion
}
private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
{
if (clicked != true)
return;
IPoint ipNew;
if (m_ipPoints == null)
{
m_ipPoints = new Multipoint();
}
ipNew = m_ipActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y);
object o = Type.Missing;
m_ipPoints.AddPoint(ipNew, ref o, ref o);
IElement element;
ITextElement textelement = new TextElementClass();
element = textelement as IElement;
clickedcount++;
textelement.Text = clickedcount.ToString();
element.Geometry = m_ipActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x, e.y);
pGC.AddElement(element, 0);
m_ipActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
}
3.4实验结果
在得到的窗口中加载“甘地的个人地理数据库〞〔在压缩包中有〕中的几何网络“road_Net〞,将几何网络地图加载到地图显示窗口中,如以下图所示:
点击图标添加起始点,效果如以下图:
然后点击图标,计算最短路径,效果如以下图:
最后点击图标得到最短路径的缩放,效果如以下图:
这样就完成了最短路径的查询分析和显示的功能。
4、实习总结
在整个过程中所出现的问题较多,表达出个人根底的缺乏,程序的出错有时候出现在标点符号以及英文字母的大小写上面等等问题,这些都说明了不熟练的问题。因此,二次开发的一个最重要的是勤于练习敲代码,能够对着书本的代码敲二不会出现一些不该犯的错误,然后进展下一步的提高,一步一个踏实的脚印,打下一个坚实的根底是非常重要。另一个重要的体会就是学会自己去查询资料,尽可能的通过自己的能力解决问题,实在不能解决的在向教师请教,这是在大学中一个重要的方法,因此学会独立去解决问题通过查询资料,虽然是一个困难重重的过程,但是能够学到好多有用的能力。
. .word.zl.
展开阅读全文