2021-11-19------c#在arcgis-engine中使用BFS算法实现连通分析

99 阅读1分钟

1.数据结构说明

sde库线表image.png

2.核心代码

  /// <summary>
        /// 获取是否连通,与方向无关
        /// </summary>
        /// <param name="sourceFea">源要素,线</param>
        /// <param name="targetFea">目标要素,线</param>
        /// <param name="pMap">地图对象,非必要</param>
        /// <param name="pFeaLayer">管线图层</param>
        /// <param name="token">task的token,使用委托来更新进度条</param>
        /// <param name="setValue">委托函数</param>
        /// <returns>是否连通</returns>
 public static bool getIfConnect(IFeature sourceFea, IFeature targetFea,IMap pMap,IFeatureLayer pFeaLayer,CancellationToken token,Action<float> setValue)
        {
            bool isconnect = false;
            //创建一个队列
            Queue<IFeature> q = new Queue<IFeature>();
            q.Enqueue(sourceFea);
            IFields fields = pFeaLayer.FeatureClass.Fields;
            int index_start = fields.FindField("startpoint");
            int index_end = fields.FindField("endpoint");
            int index_id = fields.FindField("objectId");
            IFeature newFea = null;
            IFeature pFea = null;
            IFeatureCursor feaCursor = null;
            //WaitDialogForm wdf = new WaitDialogForm("提示", "正在进行连通分析......");
            int i = 0;
            ArrayList list = new ArrayList(); 
            while (q.Count > 0)
            {
                i++;
                //wdf.SetCaption("已经分析" + i + "次,最多需要分析"+ pFeaLayer.FeatureClass.FeatureCount(null).ToString()+"次");
                //队列出来一个元素,
                setValue(i/10);
                newFea = (IFeature)q.Dequeue();
                pMap.SelectFeature(pFeaLayer, newFea);
                list.Add(newFea);
               
                //如果是target要素,则连通,否则获取下一个要素加入队列
                if (newFea.Value[index_id].ToString() == targetFea.Value[index_id].ToString())
                {
                    isconnect = true;
                    break; ;
                }
                else
                {
                    String objectid = newFea.Value[0].ToString();
                  
                    //获取源节点的下一个节点列表
                    feaCursor = getNextFeatures(newFea, pFeaLayer.FeatureClass, index_end, index_start);
                    //遍历下一个节点,如果等于targetId,就结束,连通,否则,将节点放入队列中
                    pFea = feaCursor.NextFeature();
                    int all = 0;
                    int insert = 0;
                    while (pFea != null)
                    {
                        String nextId = pFea.Value[0].ToString();
                        //if (nextId == objectid)
                        //{
                           
                        //    bool qContain = getIfContain(q,pFea);
                        //    bool listContain = getIfContain(list, pFea);
                        //    bool isContain = qContain|| listContain;

                        //}
                        if (!(getIfContain(q, pFea)|| getIfContain(list, pFea)))
                        {
                            q.Enqueue(pFea);
                            insert++;
                        }
                        all++;
                        pFea = feaCursor.NextFeature();
                    }
                   
                }
                
            
               
               

            }
            Marshal.ReleaseComObject(feaCursor);
            //wdf.Close();

            
            return isconnect;
        }


        public static bool getIfContain(Queue<IFeature> q, IFeature pFea)
        {
            bool isContain = false;
            foreach(IFeature fea in q)
            {
                if(fea.Value[0].ToString()== pFea.Value[0].ToString())
                {
                    isContain = true;
                    break;
                }
            }
            return isContain;
        }

        public static  bool getIfContain(ArrayList list, IFeature pFea)
        {
            bool isContain = false;
            foreach (IFeature fea in list)
            {
                if (fea.Value[0].ToString() == pFea.Value[0].ToString())
                {
                    isContain = true;
                    break;
                }
            }
            return isContain;
        }




        /// <summary>
        /// 获取下一个节点
        /// </summary>
        /// <param name="sourceId"></param>
        /// <returns></returns>
        public static IFeatureCursor getNextFeatures(IFeature newFea, IFeatureClass pFeaClass, int index_end,int index_start)
        {
            IQueryFilter filter = new QueryFilter();
            filter.WhereClause = "startpoint='" + newFea.Value[index_end].ToString() + "' or endpoint='" + newFea.Value[index_end].ToString() + "' or startpoint='" + newFea.Value[index_start].ToString() + "' or endpoint='" + newFea.Value[index_start].ToString() + "'";


            IFeatureCursor feaCursor= pFeaClass.Search(filter, false);
            Marshal.ReleaseComObject(filter);
            return feaCursor; 

        }