ArcEngine 最短路径分析(源码)
 

using System;

using ESRI.ArcGIS.Carto;

using ESRI.ArcGIS.Geometry;

using ESRI.ArcGIS.Geodatabase;

using ESRI.ArcGIS.NetworkAnalysis;

namespace GisEditor

{

/// <summary>

/// 最短路径分析

/// </summary>

public class ClsPathFinder

{

private IGeometricNetwork m_ipGeometricNetwork;

private IMap m_ipMap;

private IPointCollection m_ipPoints;

private IPointToEID m_ipPointToEID;

private double m_dblPathCost =0;

private IEnumNetEID m_ipEnumNetEID_Junctions;

private IEnumNetEID m_ipEnumNetEID_Edges;

private IPolyline   m_ipPolyline;

#region Public Function

//返回和设置当前地图

public IMap SetOrGetMap

{

set{ m_ipMap = value;}

get{return   m_ipMap;}

}

//打开几何数据集的网络工作空间

public void OpenFeatureDatasetNetwork(IFeatureDataset FeatureDataset)

{

CloseWorkspace();

if (!InitializeNetworkAndMap(FeatureDataset))

Console.WriteLine( "打开network出错");

}

//输入点的集合

public IPointCollection StopPoints

{

set{m_ipPoints= value;}

get{return   m_ipPoints;}

}

//路径成本

public double PathCost

{

get {return m_dblPathCost;}

}

//返回路径的几何体

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 EIDHelperClass();

ipEIDHelper.GeometricNetwork = m_ipGeometricNetwork;

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++)

{

ipEIDInfo = ipEnumEIDInfo.Next();

ipGeometry = ipEIDInfo.Geometry;

ipNewGeometryColl.AddGeometryCollection( ipGeometry as IGeometryCollection);

}

return m_ipPolyline;

}

//解决路径

public void SolvePath(string WeightName)

{

try

{

int intEdgeUserClassID;

int intEdgeUserID;

int intEdgeUserSubID;

int intEdgeID;

IPoint ipFoundEdgePoint;

double dblEdgePercent;

/*PutEdgeOrigins方法的第二个参数要求是IEdgeFlag类型的数组,

* 在VB等其他语言的代码中,只需传人该类型数组的第一个元素即

* 可,但C#中的机制有所不同,需要作出如下修改:使用

* ITraceFlowSolverGEN替代ITraceFlowSolver

*/

ITraceFlowSolverGEN  ipTraceFlowSolver = new TraceFlowSolverClass() as ITraceFlowSolverGEN;

INetSolver ipNetSolver = ipTraceFlowSolver as INetSolver;

INetwork ipNetwork = m_ipGeometricNetwork.Network;

ipNetSolver.SourceNetwork = ipNetwork;

INetElements ipNetElements = ipNetwork as INetElements;

int intCount = m_ipPoints.PointCount;

//定义一个边线旗数组

IEdgeFlag[] pEdgeFlagList = new EdgeFlagClass[intCount];

for(int i = 0;i<intCount ;i++)

{

INetFlag ipNetFlag = new EdgeFlagClass()as INetFlag;

IPoint  ipEdgePoint = m_ipPoints.get_Point(i);

//查找输入点的最近的边线

m_ipPointToEID.GetNearestEdge(ipEdgePoint, out intEdgeID,out ipFoundEdgePoint, out dblEdgePercent);

ipNetElements.QueryIDs( intEdgeID, esriElementType.esriETEdge, out intEdgeUserClassID, out intEdgeUserID,out intEdgeUserSubID);

ipNetFlag.UserClassID = intEdgeUserClassID;

ipNetFlag.UserID = intEdgeUserID;

ipNetFlag.UserSubID = intEdgeUserSubID;

IEdgeFlag pTemp = (IEdgeFlag)(ipNetFlag as IEdgeFlag);

pEdgeFlagList[i]=pTemp;

}

ipTraceFlowSolver.PutEdgeOrigins(ref pEdgeFlagList);

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;

}

catch(Exception ex)

{

Console.WriteLine(ex.Message);

}

}

#endregion

#region Private Function

//初始化几何网络和地图

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.GeometricNetworkCount;

//获取第一个几何网络工作空间

m_ipGeometricNetwork = ipNetworkCollection.get_GeometricNetwork(0);

INetwork ipNetwork = m_ipGeometricNetwork.Network;

if(m_ipMap!=null)

{

m_ipMap = new MapClass();

ipFeatureClassContainer = m_ipGeometricNetwork as IFeatureClassContainer;

count = ipFeatureClassContainer.ClassCount;

for(int i =0;i<count;i++)

{

ipFeatureClass = ipFeatureClassContainer.get_Class(i);

ipFeatureLayer = new FeatureLayerClass();

ipFeatureLayer.FeatureClass = ipFeatureClass;

m_ipMap.AddLayer( ipFeatureLayer);

}

}

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.GeometricNetwork = m_ipGeometricNetwork;

double dblWidth = ipMaxEnvelope.Width;

double dblHeight = ipMaxEnvelope.Height;

if( dblWidth > dblHeight)

dblSearchTol = dblWidth / 100;

else

dblSearchTol = dblHeight / 100;

m_ipPointToEID.SnapTolerance = dblSearchTol;

return true  ;

}

//关闭工作空间

private void CloseWorkspace()

{

m_ipGeometricNetwork = null;

m_ipPoints = null;

m_ipPointToEID = null;

m_ipEnumNetEID_Junctions = null;

m_ipEnumNetEID_Edges = null;

m_ipPolyline = null;

}

#endregion

}

}

备注:

在调用该类时的次序:

ClsPathFinder  m_ipPathFinder;

if(m_ipPathFinder==null)//打开几何网络工作空间

{

m_ipPathFinder = new ClsPathFinder();

ipMap = this.m_ActiveView.FocusMap;

ipLayer = ipMap.get_Layer(0);

ipFeatureLayer = ipLayer as IFeatureLayer;

ipFDB = ipFeatureLayer.FeatureClass.FeatureDataset;

m_ipPathFinder.SetOrGetMap = ipMap;

m_ipPathFinder.OpenFeatureDatasetNetwork(ipFDB);

}

private void ViewMap_OnMouseDown(object sender, ESRI.ArcGIS.MapControl.IMapControlEvents2_OnMouseDownEvent e)//获取地图上鼠标输入的点

{

IPoint ipNew ;

if( m_ipPoints==null)

{

m_ipPoints = new MultipointClass();

m_ipPathFinder.StopPoints = m_ipPoints;

}

ipNew = ViewMap.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x,e.y);

object o = Type.Missing;

m_ipPoints.AddPoint(ipNew,ref o,ref o);

}

m_ipPathFinder.SolvePath("Weight");//先解析路径

IPolyline ipPolyResult = m_ipPathFinder.PathPolyLine();//最后返回最短路径

Arcgis Engine最短路径分析的更多相关文章

  1. ArcGIS API for JavaScript 4.2学习笔记[27] 网络分析之最短路径分析【RouteTask类】

    要说网页端最经典的GIS应用,非网络分析莫属了. 什么?你没用过?百度高德谷歌地图的路线分析就是活生生的例子啊!只不过它们是根据大实际背景优化了结果显示而已. 这个例子使用RouteTask进行网络分 ...

  2. arcgis api 3.x for js 入门开发系列十三地图最短路径分析(附源码下载)

    前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 3.x for js:esri 官网 api,里面详细的介绍 arcgis api 3.x 各个类 ...

  3. ArcGIS Engine开发前基础知识(1)

    ArcGIS二次开发是当前gis领域的一项重要必不可少的技能.下面介绍它的基本功能 一.ArcGIS Engine功能 在使用之前首先安装和部署arcgis sdk,(在这里不在赘述相关知识)可以实现 ...

  4. 基于Arcgis Engine 10.2(C#)+PostgreSQL 11(Postgis 3)+pgRouting 3.0实现使用数据库进行路径规划

    前言:最近在(被迫)使用ArcGIS Engine10.2(.NET平台)进行二次开发(桌面应用),因为想做一个最短路径查询的功能,而arcgis的网络分析又比较麻烦,于是想到了使用Postgis.但 ...

  5. 以Network Dataset(网络数据集)方式实现的最短路径分析

    转自原文 以Network Dataset(网络数据集)方式实现的最短路径分析 构建网络有两种方式,分别是网络数据集NetworkDataset和几何网络Geometric Network,这个网络结 ...

  6. ArcGIS Engine开发之图形查询

    图形查询是以用户通过鼠标操作生成的图形几何体为输入条件进行查询的查询,其查询结果为该几何体空间范围内的所有要素.常用的查询方式包括点选.线选.多边形选择.圆形选择和矩形选择等. 相关类与接口 图像查询 ...

  7. ArcGIS Engine开发之属性查询

    属性查询即基于空间数据的属性数据的查询,通过用户提交SQL语言中的where语句定义的查询条件,对属性数据进行搜索,从而得到查询结果的操作. 相关的类与接口 与属性查询功能相关的类主要有QureyFi ...

  8. ArcGIS Engine开发之地图基本操作(4)

    ArcGIS Engine开发中数据库的加载 1.加载个人地理数据库数据 个人地理数据库(Personal Geodatabase)使用Miscrosoft Access文件(*.mdb)进行空间数据 ...

  9. ArcGIS Engine开发之地图基本操作(3)

    地图数据的加载 一.加载Shapefile数据 Shapefile文件是目前主流的一种空间数据的文件存储方式,也是不同GIS软件进行数据格式转换常用的中间格式.加载Shapefile数据的方式有两种: ...

随机推荐

  1. res/raw文件的存放和读取

    通常,如果Android开发者有些文件比如音频,视频,.html,.mp3等等这些文件不希望编译器编译而保持原始原貌打包进apk文件(这在游戏开发中很常见和普遍,如游戏用到的游戏音乐.图等资源),那么 ...

  2. JMS消息头

    一个消息对象分为三部分:消息头(Headers),属性(Properties)和消息体(Payload).对于StreamMessage和MapMessage,消息本身就有特定的结构,而对于TextM ...

  3. ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

    测试库一条update语句报错:ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction mysql> ...

  4. 使用jquery控制只能输入数字,并且关闭输入法(转)

    控制文本框只能输入数字是一个很常见的需求,比如电话号码的输入.数量的输入等,这时候就需要我们控制文本框只能输入数字.在用js控制之后在英文输入法的状态下去敲击键盘上的非数字键是输不进去的,然而当你转到 ...

  5. JavaScript string array 数组

    Array类可以如下定义: var aValues = new Array(); 如果预先知道数组的长度,可以用参数传递长度 var aValues = new Array(20); -------- ...

  6. Spring3+hibernate4+struts2整合的 过程中发生如下错误

    严重: Error configuring application listener of class org.springframework.web.context.ContextLoaderLis ...

  7. BZOJ1692: [Usaco2007 Dec]队列变换

    1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 594  Solved: 246[Submit][Sta ...

  8. SQLServer 触发器 同时插入多条记录有关问题

    由于 SQL Server 的触发器, 没有 FOR EACH ROW (ORACL中有)的选项, 有时候不正确的使用 inserted 与deleted 可能会有点麻烦. 下面来一个简单的例子 -- ...

  9. hdu 1056

    水题 ~~  按题目要求直接判断~. /************************************************************************* > A ...

  10. 对于python的内存管理的好文章

    http://www.cnblogs.com/vamei/p/3232088.html 包含了一个绘制关系图的包