ArcEngine 最短路径分析C# (转载) - 圣殿GIS

njlhb 2021-08-06 原文


ArcEngine 最短路径分析C# (转载)

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();//最后返回最短路径

发表于
2007-05-31 11:07 
圣殿GIS 
阅读(2185
评论(2
编辑 
收藏 
举报

 

版权声明:本文为njlhb原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/njlhb/archive/2008/05/21/766102.html

ArcEngine 最短路径分析C# (转载) - 圣殿GIS的更多相关文章

  1. ubuntu下chm和PDF阅读器 « 小居

    ubuntu下chm和PDF阅读器 « 小居 ubuntu自带的chm和PDF阅读器不怎么好用,功能有限,而且 […]...

  2. ORACLE NUMBER类型详解 – 想飞的小丑鱼

    ORACLE NUMBER类型详解 1>.NUMBER类型细讲:Oracle number dataty […]...

  3. 字节跳动–今日头条iOS客户端启动速度优化 – 纯情的小公鸡

    字节跳动–今日头条iOS客户端启动速度优化 字节跳动–今日头条iOS客户端启动速度优化 […]...

  4. 一站式自动化测试平台 http://www.Autotestplat.com – zouhui

    一站式自动化测试平台 http://www.Autotestplat.com 2019-05-23 21:11 […]...

  5. python3爬虫入门程序 – 凉云

    python3爬虫入门程序 适用于有且只有一点Python3和网页基础的朋友,大牛&路人请绕道 (本文 […]...

  6. System.Data.SQLite数据库简介 – jack_Meng

    System.Data.SQLite数据库简介 SQLite介绍 在介绍System.Data.SQLite之 […]...

  7. 软件测试流程进阶—-两年软件测试总结 – 虫师

    软件测试流程进阶—-两年软件测试总结 2012-08-04 00:52  虫师  阅读(17126 […]...

  8. XML的创建、解析-C语言 – 逆袭之路666

    XML的创建、解析-C语言   前言:今天在做一个小项目时,客户要求的xml,跟现在有系统要求的不一样,所以要 […]...

随机推荐

  1. 我是如何将linux用在开发环境中的

    1.我为什么要写这篇文章   一直想深入学习一下linux的使用,于是将家里的笔记本装了linux系统,但是要 […]...

  2. linux下的oracle自启动叫本的编写 – 加班费的离开

    View Post linux下的oracle自启动叫本的编写 可能这代码用的人不是很多,不过还是发出来给大家 […]...

  3. MySQL之完整性约束

    完整性约束 完整性约束的定义 为了保证插入数据的正确性和合法性,给表中字段添加,除了数据类型约束以外的其他约束 […]...

  4. 编写高质量代码:改善Java程序的151个建议 –[65~78]

    编写高质量代码:改善Java程序的151个建议 –[65~78] 原始类型数组不能作为asList […]...

  5. 眼见为实,华为鲲鹏架构服务器生态大揭秘

    华为鲲鹏架构服务器推出好几年了,特别是去年鲲鹏920CPU推出后,更是迎来了一个飞跃,全国装机发货量猛增,在各 […]...

  6. 谨慎对待人工智能

      版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖。如要转贴,必须注明原文网址   http:/ […]...

  7. Gradle 1.12用户指南翻译——第四十九章. Build Dashboard 插件 – 牛栏山1

    Gradle 1.12用户指南翻译——第四十九章. Build Dashboard 插件 本文由CSDN博客貌 […]...

  8. dotnet获取PDF文件的页数

    #region 获取PDF文件的页数 private int BytesLastIndexOf(Byte[] […]...

展开目录

目录导航