zoukankan      html  css  js  c++  java
  • ArcEngine 最短路径分析(源码)【转载】

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

  • 相关阅读:
    EasyUI datagrid动态加载json数据
    利用EasyUI combobox实现模糊搜索
    SQL动态拼接字符串生成分页存储过程
    JavaScript函数表达式
    JavaScript继承
    JavaScript创建对象的常用模式
    JavaScript引用类型
    JavaScript执行环境
    JavaScript变量及数据类型
    jackson序列化和反序列化Json
  • 原文地址:https://www.cnblogs.com/lauer0246/p/1338810.html
Copyright © 2011-2022 走看看