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. Java抽象类接口、内部类题库

    一.    选择题 1. Person类和Test类的代码如下所示,则代码中的错误语句是(  C  ).(选择一项)   public class Person { public String nam ...

  2. 重写List集合的ToString方法

    重写方法: public class MyList<T> : List<T> where T : IConvertible { public override string T ...

  3. Mysql 基于BinaryLog的复制

    .Mysql Master将更新[Update]和变化[Change]作为事件[events]写入Binary log.Mysql slaves 被配置为读取Binary log from maste ...

  4. Mac 下 gradle 路径

    /Users/yourname/.gradle/wrapper/dists cmd:cd ~/.gradle/wrapper/dists/

  5. android DisplayMetrics 获取屏幕分辨率

    Android 提供DisplayMetircs 类可以很方便的获取分辨率.下面介绍 DisplayMetics 类: Andorid.util 包下的DisplayMetrics 类提供了一种关于显 ...

  6. Java中length,length(),size()区别

    length属性:用于获取数组长度. eg: int ar[] = new int{1,2,3} /** * 数组用length属性取得长度 */ int lenAr = ar.length;//此处 ...

  7. jQuery - 9.Ajax

    9.1 Ajax 的 XMLHttpRequest 对象 9.2 JQuery中的Ajax 9.2.1 load()方法 9.2.2 $.get() 9.2.3 $.post() 9.2.4 $.ge ...

  8. attributeError:'module' object has no attribute ** 解决办法

    写了一个小脚本,执行的时候报错: Traceback (most recent call last): File "F:/test/qrcode.py", line 109, in ...

  9. Elasticsearch在Windows下的安装

    下载Elasticsearch,地址:elasticsearch.org/download 下载jdk,百度搜索jdk下载即可 配置JAVA_HOME变量,配置方法在此文:http://jingyan ...

  10. 【openGL】画正弦函数图像

    #include "stdafx.h" #include <GL/glut.h> #include <stdlib.h> #include <math ...