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
 
 }
}

ArcGIS 最短路径计算的更多相关文章

  1. ArcGis 字段计算表达式写法注意事项

    在ArcGis中,经常用到字段的计算.对于复杂的字段计算,需要写代码来实现,在使用ESRI.ArcGIS.DataManagementTools.CalculateField 类时,Python代码中 ...

  2. Python绘制拓扑图(无向图)、有向图、多重图。最短路径计算

    前言: 数学中,“图论”研究的是定点和边组成的图形. 计算机中,“网络拓扑”是数学概念中“图”的一个子集.因此,计算机网络拓扑图也可以由节点(即顶点)和链路(即边)来进行定义和绘制. 延伸: 无向图 ...

  3. [地图代数]处理DEM中的高程异常值——ArcGIS栅格计算的应用

    接了一个任务,要处理DEM原始数据中的高程异常值,如图中的异常亮点. 想了一下,以前处理过建筑物附近的DEM铲平,那么高程异常值应该如何处理呢? 显然直接铲平时不太合理的,需要利用异常值周围的高程进行 ...

  4. arcgis engine计算点到线的最短距离

    IProximityOperator接口用于获取两个几何图形的距离,以及给定一个Point,求另一个几何图形上离离给定点最近的点.IProximityOperator接口的主要方法有:QueryNea ...

  5. ArcGis设置到 Oracle 的连接

    设置到 Oracle 的连接 地理数据 » 管理地理数据库 » Oracle 中的地理数据库 要建立从客户端计算机到 Oracle 数据库的连接,必须在客户端计算机上安装 Oracle 客户端应用程序 ...

  6. 算法:最短路径之弗洛伊德(Floyd)算法

    https://cloud.tencent.com/developer/article/1012420 为了能讲明白弗洛伊德(Floyd)算法的主要思想,我们先来看最简单的案例.图7-7-12的左图是 ...

  7. 最短路径 - 弗洛伊德(Floyd)算法

    为了能讲明白弗洛伊德(Floyd)算法的主要思想,我们先来看最简单的案例.图7-7-12的左图是一个简单的3个顶点的连通网图. 我们先定义两个二维数组D[3][3]和P[3][3], D代表顶点与顶点 ...

  8. JS实现最短路径之弗洛伊德(Floyd)算法

    弗洛伊德算法是实现最小生成树的一个很精妙的算法,也是求所有顶点至所有顶点的最短路径问题的不二之选.时间复杂度为O(n3),n为顶点数. 精妙之处在于:一个二重初始化,加一个三重循环权值修正,完成了所有 ...

  9. 【ArcGIS遇上Python】ArcGIS Python批处理入门到精通实用教程目录

    目录 1. 专栏简介 2. 专栏地址 3. 专栏目录 1. 专栏简介 Python语言是目前很火热的语言,极大的促进了人工智能发展.你知道在ArcGIS中也会有python的身影吗?事实上,在ArcG ...

随机推荐

  1. 73. Set Matrix Zeroes

    题目: Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. Fo ...

  2. 构建新版本APP上传流程

    //既然是构建新版本的 APP,那么所有的证书都是已经存在了的,因此以下不再重复描述证书申请过程,如有需要请自行 Google 相关流程. 1)更改版本号: 2)去掉工程内的全局断点,同时关闭僵尸调试 ...

  3. UICollectionView cellForItemAtIndexPath 方法不走

    在storyboard 中 UICollectionView cellForItemAtIndexPath not called 被坑了好久,各种问题点查找,终于解决了 解决办法: self.auto ...

  4. ASP.net绑定文本框Enter事件到按钮 ASP.NET执行后台执行JS方法

    txtAccountBarcode.Attributes.Add("onkeydown", "if(event.which || event.keyCode){if (( ...

  5. iOS注册collcetionViewFlowLayout

    self.arr = [[NSMutableArray alloc] init]; for (int i = 0; i < 9; i++) { [self.arr addObject:[UIIm ...

  6. java动态生成excel打包下载

    @SuppressWarnings("unchecked") public String batchExport() throws DBException{ @SuppressWa ...

  7. 字典树(codevs 4189)

    4189 字典  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 大师 Master 题解  查看运行结果     题目描述 Description 最经,skyzhong得到了 ...

  8. java向oracle数据库中插入当前时间

    public class Test{public static void main (String args []){ java.util.Date a = new java.util.Date(); ...

  9. jq div鼠标放上、离开马上展开、收缩方法

    <body> <div id="aa" style="width:500px; height:30px; border:1px solid #000&q ...

  10. 与你相遇好幸运,async解决循环回调问题

    由于使用的sailsjs框架,用的是sailsjs自身带的ORm(就是waterline),ORM的默认数据库的返回值在回调里面. > arg是一个数组 count用来计数用 tmpArr临时存 ...