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. 分页Bean终极封装

    package org.guangsoft.vo; import java.util.List; public class Page { private Integer pageNum; privat ...

  2. js递归

    先从外层往里调,再反. 要想明白,必须明白执行过程. 如果再不理解,就看函数功能.   函数里自己调自己就是递归!

  3. XMPP框架下微信项目总结(1)环境配置

    xmpp介绍 xmpp基于模块开发的 无须自己写请求 (登陆,注册,获取好友列表,添加/删除好友等) ------>简介 ------------------------- ----->工 ...

  4. 001课-java_web开发入门

    一.Tomcat服务器常见启动问题:(1).Java_home环境变量,由于tomcat服务器的bin目录中的一些jar文件必须使用到java类库,所以必须先配置Java_home环境变量.(2).端 ...

  5. hadoop 2.5 hdfs namenode –format 出错Usage: java NameNode [-backup] |

    在 cd  /home/hadoop/hadoop-2.5.2/bin 下 执行的./hdfs namenode -format 报错[hadoop@node1 bin]$ ./hdfs nameno ...

  6. 理解KMP算法

    母串:S[i] 模式串:T[i] 标记数组:Next[i](Next[i]表示T[0~i]最长前缀/后缀数) 先来讲一下最长前缀/后缀的概念 例如有字符串T[6]=abcabd接下来讨论的全部是真前缀 ...

  7. 关闭 Visual Studio 2013 的 Browser Link 功能

    最近公司弄新项目需要用 MVC,就把 IDE 升级到了 Visual Studio 2013,在开发的时候发现有好多请求一个本地49925的端口 . 很奇怪,一开始以为是 Visual Studio ...

  8. 在RedHat.Enterprise.Linux_v6.3系统中安装Oracle_11gR2教程

    在RedHat.Enterprise.Linux_v6.3系统中安装Oracle_11gR2教程 本教程提供PDF格式下载: 在RedHat.Enterprise.Linux_v6.3系统中安装Ora ...

  9. 【PHP用户的错误日志】

    将产生的错误保存在日志中的方法:使用error_log方法,其中,当日志类型是3的时候,下一个参数将会是日志文件的保存路径 使用示例: <?php function myerror($level ...

  10. Asyncio中的Task管理

    #!/usr/bin/env python # -*- coding: utf-8 -*- import asyncio import datetime import time from random ...