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

  • 相关阅读:
    ant 软件包不存在报错
    在 Internet Explorer 中使用 Windows 窗体控件
    智能客户端
    Back to the Future with Smart Clients
    "Automation 服务器不能创建对象" 的解决方案
    Top 10 Reasons for Developers to Create Smart Clients
    Updater Application Block for .NET
    Smart Client Application Model and the .NET Framework 1.1
    Security and Versioning Models in the Windows Forms Engine Help You Create and Deploy Smart Clients
    智能客户端技术总结(二)
  • 原文地址:https://www.cnblogs.com/lauer0246/p/1338810.html
Copyright © 2011-2022 走看看