using System; using System.Collections.Generic; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.Geometry; using KGIS.Framework.AE.ExtensionMethod; using KGIS.Framework.AE; namespace Kingo.PluginServiceInterface.Helper { public class PolygonNarrowCheck { public static bool CheckNarrowArea1(IGeometry geometry) { bool isSharpAngle = false; try { if (geometry == null || geometry.IsEmpty) return isSharpAngle; ITopologicalOperator topo = geometry as ITopologicalOperator; IPolyline line1 = topo.Boundary as IPolyline; double length1 = line1.Length; int pointCount1 = (geometry as IPointCollection).PointCount; IGeometry geo = topo.Buffer(-0.05); ITopologicalOperator topo2 = geo as ITopologicalOperator; IPolyline line2 = topo2.Boundary as IPolyline; double length2 = line2.Length; double delta_length = length1 - length2; double avg_halfangle = 180 * (pointCount1 - 1 - 2) / (pointCount1 - 1) / 2; double conner_normal_length = 2 * 0.05 / Math.Tan(avg_halfangle * (Math.PI / 180)); if (delta_length > 8 * conner_normal_length * (pointCount1 - 1)) return true; } catch (Exception) { } finally { //GC.Collect(); } return isSharpAngle; } // 经验阈值判断(8倍安全系数) const double safetyFactor = 8.0; const double bufferDistance = -0.05; // 单位取决于空间参考 public static bool CheckNarrowArea(IGeometry geometry) { // 返回值表示是否检测到狭窄区域,默认为false bool isNarrowAreaDetected = false; try { // 输入校验:确保几何体非空且有效 if (geometry == null || geometry.IsEmpty) return isNarrowAreaDetected; // 类型检查:确保支持拓扑操作 if (!(geometry is ITopologicalOperator topoOperator)) return isNarrowAreaDetected; // 获取原始边界并验证类型 var originalBoundary = topoOperator.Boundary as IPolyline; if (originalBoundary == null) return isNarrowAreaDetected; // 计算原始几何参数 double originalLength = originalBoundary.Length; int vertexCount = (geometry as IPointCollection)?.PointCount ?? 0; // 顶点数不足3时无法构成有效多边形 if (vertexCount < 3) return isNarrowAreaDetected; // 执行负缓冲操作(缩小几何体) IGeometry bufferedGeometry = topoOperator.Buffer(bufferDistance); // 检查缓冲后几何有效性 if (bufferedGeometry?.IsEmpty != false) return isNarrowAreaDetected; // 获取缓冲后边界并验证类型 if (!(bufferedGeometry is ITopologicalOperator bufferedTopo)) return isNarrowAreaDetected; var bufferedBoundary = bufferedTopo.Boundary as IPolyline; if (bufferedBoundary == null) return isNarrowAreaDetected; // 计算缓冲后长度差异 double deltaLength = originalLength - bufferedBoundary.Length; // 计算平均内角半角(几何修正) double avgHalfAngle = 90.0 * (vertexCount - 2) / vertexCount; // 角度接近直角时跳过计算(避免tan(90°)) if (avgHalfAngle >= 89.999) return isNarrowAreaDetected; // 计算拐角缩短长度 double tanValue = Math.Tan(avgHalfAngle * Math.PI / 180.0); double cornerReduction = 2 * Math.Abs(bufferDistance) / tanValue; // 计算总预期缩短长度 double totalExpectedReduction = cornerReduction * vertexCount; isNarrowAreaDetected = deltaLength > safetyFactor * totalExpectedReduction; } catch (Exception ex) { // 异常处理(建议记录日志) // Debug.WriteLine($"几何检测异常: {ex.Message}"); return false; } return isNarrowAreaDetected; } } }