using System; using System.Collections.Generic; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Geometry; namespace Kingo.PluginServiceInterface.Helper { public static class GeometryComparator { // 默认空间关系检测容差(单位与几何坐标系一致) private const double DEFAULT_TOLERANCE = 0.001; // 用于坐标差异比较的极小容差(防止浮点数精度误差导致的误判) private const double COORDINATE_TOLERANCE = 1e-9; /// /// 图形对比分析:检测目标几何体与相邻几何体集合是否存在满足以下条件的顶点对: /// 1. 空间距离小于等于指定容差 /// 2. 实际坐标差异大于精度容差(排除坐标系转换导致的微小差异) /// /// 需要分析的目标几何体 /// 相邻几何体集合 /// 空间关系判定容差(默认1mm) /// /// true: 存在符合条件的顶点对 | false: 未找到符合条件的顶点对或输入无效 /// /// /// 算法复杂度:O(n*m) (建议对大规模数据使用空间索引优化) /// 坐标系要求:投影坐标系(保证距离计算准确) /// public static bool SpatialRelationshipAnalysis( IGeometry targetGeometry, IEnumerable adjacentGeometries, double tolerance = DEFAULT_TOLERANCE) { // 参数有效性验证 if (targetGeometry == null || adjacentGeometries == null || tolerance < 0) return false; // 提取目标几何体的拓扑正确顶点集合 var targetVertices = ExtractTopologicalVertices(targetGeometry); if (targetVertices.Count == 0) return false; // 预计算容差平方值用于快速比较 var squaredTolerance = tolerance * tolerance; // 遍历所有相邻几何体进行对比分析 foreach (var adjacentGeometry in adjacentGeometries) { // 跳过无效几何体 if (adjacentGeometry == null) continue; // 提取相邻几何体的拓扑正确顶点集合 var adjacentVertices = ExtractTopologicalVertices(adjacentGeometry); if (adjacentVertices.Count == 0) continue; // 双层循环比对顶点(可优化为空间索引查询) foreach (var targetVertex in targetVertices) { foreach (var adjacentVertex in adjacentVertices) { // 快速平方距离计算(避免Math.Sqrt开销) if (CalculateSquaredDistance(targetVertex, adjacentVertex) > squaredTolerance) continue; // 精确坐标差异验证(排除容差范围内的坐标舍入误差) if (HasSignificantCoordinateDifference(targetVertex, adjacentVertex)) { return true; } } } } return false; } /// /// 从几何体中提取拓扑正确的顶点集合 /// /// 输入的几何对象 /// 顶点集合(可能为空) /// /// 处理流程: /// 1. 创建几何副本避免修改原始数据 /// 2. 执行拓扑简化确保几何有效性 /// 3. 提取顶点信息 /// private static List ExtractTopologicalVertices(IGeometry geometry) { var vertices = new List(); try { // 创建几何副本(隔离原始对象) var clonedGeometry = (geometry as IClone)?.Clone() as IGeometry; if (clonedGeometry == null) return vertices; // 拓扑规范化处理 if (clonedGeometry is ITopologicalOperator topology) { if (!topology.IsKnownSimple) topology.Simplify(); } // 顶点提取策略选择 switch (clonedGeometry) { case IPoint point: vertices.Add(point); break; case IPointCollection pointCollection: ExtractVerticesFromCollection(pointCollection, vertices); break; // 可扩展其他几何类型(如IMultiPatch等)的处理逻辑 } } catch (Exception ex) { // 实际应用中应添加日志记录 System.Diagnostics.Debug.WriteLine($"顶点提取异常:{ex.Message}"); } return vertices; } /// /// 从点集合中提取顶点信息 /// private static void ExtractVerticesFromCollection(IPointCollection source, ICollection destination) { if (source == null || destination == null) return; for (int i = 0; i < source.PointCount; i++) { var point = source.get_Point(i); if (point != null) destination.Add(point); } } /// /// 计算两点间的平方平面距离(优化性能) /// private static double CalculateSquaredDistance(IPoint a, IPoint b) { if (a == null || b == null) return double.PositiveInfinity; var dx = a.X - b.X; var dy = a.Y - b.Y; return dx * dx + dy * dy; } /// /// 验证坐标是否具有显著差异(排除浮点误差) /// private static bool HasSignificantCoordinateDifference(IPoint a, IPoint b) { return Math.Abs(a.X - b.X) > COORDINATE_TOLERANCE || Math.Abs(a.Y - b.Y) > COORDINATE_TOLERANCE; } } }