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;
        }
    }
}