public class PolygonGapChecker : CheckProgressMessageSender, IChecker, ICheckProgressChangeEvent { private IFeatureLayer featureLayer; /// <summary> /// 待檢查的面要素類圖層 /// </summary> public IFeatureLayer FeatureLayer { set { if (value != null) { if (value.FeatureClass.ShapeType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon) featureLayer = value; else throw new ArgumentException("要素類不是期望的類型,應是面要素類。"); } else throw new ArgumentException("要素類對象傳入的是null"); } } private int featureCount = -1; /// <summary> /// 受檢要素類的要素個數 /// </summary> public int FeatureCount { get { return featureCount; } } //private double distance = 0.2; /// <summary> /// 距離值,一個大於零的值 /// </summary> public double Distance { set { } } private double tolerance = 0.001; /// <summary> /// 容差值,一個大於零的值 /// </summary> public double Tolerance { set { if (value <= 0 ) throw new ArgumentException("容差應是一個大於0的小數。"); else tolerance = value; } } //private double angle = 10.0; /// <summary> /// 角度值,一個大於零的值 /// </summary> public double Angle { set { } } private string workspacePath = string.Empty; /// <summary> /// FGDB或文件夾的路徑 /// </summary> public string WorkspacePath { set { if (System.IO.Directory.Exists(value)) workspacePath = value; else throw new ArgumentException("給定FGDB或文件夾的路徑不存在!"); } } private readonly CheckerType checkerType = CheckerType.面縫隙或孔洞; /// <summary> /// 檢查類型 /// </summary> public CheckerType CheckerType { get { return checkerType; } } /// <summary> /// 檢查方法 /// </summary> /// <returns>檢查結果要素類</returns> public IFeatureClass Check() { IFeatureClass featureClass_cover; //IFeatureClass featureClass_erase; //IFeatureClass featureClass_erase_explode; IFeatureClass featureClass_result; IWorkspaceFactory workspaceFactory = new ShapefileWorkspaceFactory(); string featureClass_cover_Name=featureLayer.Name+"_cover.shp"; string featureClass_erase_Name = $"{workspacePath}\\{featureLayer.Name}_erase.shp"; string featureClass_result_Name = $"{workspacePath}\\{featureLayer.Name}_gap.shp"; if (workspacePath.Split('.').Last().ToLower() == "gdb") { //確定要素類的名稱,如workspace是文件地理數據庫那么要素類名字最后沒有有.shp。 featureClass_cover_Name= featureClass_cover_Name.Replace(".shp", ""); featureClass_erase_Name=featureClass_erase_Name.Replace(".shp", ""); featureClass_result_Name=featureClass_result_Name.Replace(".shp", ""); //若是文件地理數據庫,應實例化FileGDBWorkspaceFactoryClass對象。 workspaceFactory = new FileGDBWorkspaceFactoryClass(); } IFeatureWorkspace featureWorkspace = workspaceFactory.OpenFromFile(workspacePath, 0) as IFeatureWorkspace; #region 創建Cover要素類,用於被擦除 FeatureClassCreator featureClassCreator = new FeatureClassCreator(featureLayer, featureClass_cover_Name, esriGeometryType.esriGeometryPolygon, workspacePath); featureClass_cover = featureClassCreator.Create(); OnCheckProgresChange(checkProgressChangeEventHandler, ">>>成功創建Cover。"); IPolygon polygon_cover = new PolygonClass(); IPoint pointUpperLeft = new PointClass { X = (featureLayer.FeatureClass as IGeoDataset).Extent.UpperLeft.X - 100, Y = (featureLayer.FeatureClass as IGeoDataset).Extent.UpperLeft.Y-100 }; IPoint pointUpperRight = new PointClass { X = (featureLayer.FeatureClass as IGeoDataset).Extent.UpperRight.X + 100, Y = (featureLayer.FeatureClass as IGeoDataset).Extent.UpperRight.Y-100 }; IPoint pointLowerRight = new PointClass { X = (featureLayer.FeatureClass as IGeoDataset).Extent.LowerRight.X + 100, Y = (featureLayer.FeatureClass as IGeoDataset).Extent.LowerRight.Y+100 }; IPoint pointLowerLeft = new PointClass { X = (featureLayer.FeatureClass as IGeoDataset).Extent.LowerLeft.X - 100, Y = (featureLayer.FeatureClass as IGeoDataset).Extent.LowerLeft.Y+100 }; IPointCollection pointCollection_cover = polygon_cover as IPointCollection; pointCollection_cover.AddPoint(pointUpperLeft); pointCollection_cover.AddPoint(pointUpperRight); pointCollection_cover.AddPoint(pointLowerRight); pointCollection_cover.AddPoint(pointLowerLeft); pointCollection_cover.AddPoint(pointUpperLeft); IFeature feature_cover= featureClass_cover.CreateFeature(); feature_cover.Shape = polygon_cover; feature_cover.Store(); OnCheckProgresChange(checkProgressChangeEventHandler, ">>>成功創建Cover要素,准備執行Erase。"); #endregion Geoprocessor.Geoprocessor gp = new Geoprocessor.Geoprocessor { AddOutputsToMap = false, OverwriteOutput = true }; Erase erase = new Erase { in_features = $"{workspacePath}\\{featureClass_cover_Name}", erase_features = featureLayer, out_feature_class = featureClass_erase_Name, cluster_tolerance = this.tolerance, }; gp.Execute(erase, null); OnCheckProgresChange(checkProgressChangeEventHandler, ">>>成功創建Erase,准備執行Explode。"); MultipartToSinglepart multipartToSinglepart = new MultipartToSinglepart { in_features = featureClass_erase_Name, out_feature_class = featureClass_result_Name }; gp.Execute(multipartToSinglepart, null); featureClass_result = featureWorkspace.OpenFeatureClass(featureClass_result_Name.Replace($"{workspacePath}\\", "")); CheckAuxiliaryHelper.SpatialSearchAndDeleteFeatures(featureClass_result, pointUpperLeft, esriSpatialRelEnum.esriSpatialRelIntersects); featureClass_result.DeleteField(featureClass_result.Fields.Field[featureClass_result.FindField("ORIG_FID")]); CheckAuxiliaryHelper.DeleteFeatureClass(featureClass_cover_Name, featureWorkspace); CheckAuxiliaryHelper.DeleteFeatureClass(featureClass_erase_Name, featureWorkspace); return featureClass_result; } private CheckProgressChangeEventHandler checkProgressChangeEventHandler; /// <summary> /// 進度改變事件 /// </summary> public event CheckProgressChangeEventHandler CheckProgressChangeEvent { add { this.checkProgressChangeEventHandler += value; } remove { this.checkProgressChangeEventHandler-=value; } } }