基於C#的ArcEngine二次開發24:檢查數據是否超出圖廓範圍

目錄

1 需求說明與實現思路

1.1 需求說明

1.2 需求實現思路

2 源碼實現

2.1 點是否在圖廓範圍內

2.2 獲取點面要素的集合

2.3 獲取要素 - IFeatureClass

2.4 判斷某個要素是否在節點範圍內

2.5 對圖層進行檢查


1 需求說明與實現思路

1.1 需求說明

要素超出圖廓錯誤是不允許的,作業過程需要將這些要素提示出來,供人工檢查改正

注:本文設計方法思路,僅適用於矩形圖廓的檢查,對於不規則圖廓,則不適用

1.2 需求實現思路

  • 對於點要素,直接根據圖廓座標確定的矩形範圍的角點座標,判斷其是否在圖廓範圍內
  • 對於線要素,我們將線要素拆解爲一組有序的點集,判斷點集中的每一個點是否在圖廓範圍內
  • 對於面要素,獲取構成面的所有節點集合,判斷點集中的每一個點是否在圖廓範圍內

基於上述分析,我們判斷的關鍵就是點是否在圖廓點確定的範圍內的問題

2 源碼實現

2.1 點是否在圖廓範圍內

圖廓點集:

源碼實現:

  • 給定一個點pt,判斷其是否在ranges圍成的範圍內
        /// <summary>
        /// 檢查點是否在圖廓點確定的數據範圍內
        /// </summary>
        /// <param name="pt"></param>
        /// <param name="ranges"></param>
        /// <returns></returns>
        public bool checkPointIsInner(PointF pt, List<PointF> ranges)
        {
            if (pt.X < ranges[0].X || pt.X > ranges[2].X)
            {
                return false;
            }

            if (pt.Y < ranges[0].Y || pt.Y > ranges[2].Y)
            {
                return false;
            }
            return true;
        }

2.2 獲取點面要素的集合

        /// <summary>
        /// 獲取線面要素節點集
        /// </summary>
        /// <param name="fea">要素</param>
        /// <returns>返回要素節點集合</returns>
        public List<PointF> getFeatureVerticePts(IFeature fea)
        {
            IPointCollection feaPtsColl = fea.Shape as IPointCollection;
            List<PointF> feaPts = new List<PointF>();
            for (int i = 0; i < feaPtsColl.PointCount; i++)
            {
                feaPts.Add(new PointF((float)(feaPtsColl.Point[i].X), (float)(feaPtsColl.Point[i].Y)));
            }
            return feaPts;
        }

2.3 獲取要素 - IFeatureClass

       /// <summary>
        /// mdb數據庫中提取指定名稱的要素
        /// </summary>
        /// <param name="wsPath">mdb數據庫</param>
        /// <param name="layerName">要素層名稱</param>
        /// <returns>返回的要素</returns>
        public IFeatureClass getIFeatureClass(string wsPath, string layerName)
        {
            IWorkspaceFactory workspaceFactory = new AccessWorkspaceFactory();
            IWorkspace workspace = workspaceFactory.OpenFromFile(wsPath, 0);
            IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace;
            //2. 打開要素層
            return featureWorkspace.OpenFeatureClass(layerName);
        }

2.4 判斷某個要素是否在節點範圍內

此函數的思路是:判斷給定IFeature對象是否在outline對象規定的範圍內

        /// <summary>
        /// 檢查線(面)要素是否超出圖廓線範圍
        /// </summary>
        /// <param name="outline">圖廓線要素</param>
        /// <param name="feaLine">線(面)要素</param>
        /// <returns>false表示在圖廓內部,true表示在圖廓外邊</returns>
        public bool lineIsBeyondOutline(IFeature outline, IFeature feaLine)
        {
           List<PointF> outlinePts = getFeatureVerticePts(outline);
           List<PointF> feaLinePts = getFeatureVerticePts(feaLine);
           for (int i = 0; i < feaLinePts.Count; i++)
           {
               if (!checkPointIsInner(feaLinePts[i], outlinePts))
               {
                   return true;
               }
           }
           return false;
        }

2.5 對圖層進行檢查

        /// <summary>
        /// 檢查點圖層
        /// </summary>
        /// <param name="wsPath">數據庫名稱</param>
        /// <param name="layerName">圖層名稱</param>
        public void checkPointsLayer(string wsPath, string layerName)
        {
            IFeatureClass pFeaterClass = getIFeatureClass(wsPath, layerName)

            IFeature outline = getOutlineFromCPTL(wsPath);
            //3. 獲取投影信息
            IGeoDataset geoDatabase = pFeaterClass as IGeoDataset;

            //4. 查詢所有要素
            string where = "";
            IQueryFilter filter = new QueryFilterClass();
            filter.WhereClause = where;
            //5.定義查詢遊標並循環迭代
            IFeatureCursor pFeatcursor = pFeaterClass.Search(filter, false);
            IFeature pFeature = pFeatcursor.NextFeature();

            //6. 運算結果存儲
            List<IFeature> errLists = new List<IFeature>();
            while (pFeature != null)
            {
                if (lineIsBeyondOutline(outline, pFeature))
                {
                    errLists.Add(pFeature);
                }
                pFeature = pFeatcursor.NextFeature();
            }
            ExportPtsToShapefile(wsPath, errLists, layerName, esriGeometryType.esriGeometryPoint);
        }

支持作者歡迎關注公衆號

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章