You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							160 lines
						
					
					
						
							6.3 KiB
						
					
					
				
			
		
		
	
	
							160 lines
						
					
					
						
							6.3 KiB
						
					
					
				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; | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 图形对比分析:检测目标几何体与相邻几何体集合是否存在满足以下条件的顶点对: | 
						|
        /// 1. 空间距离小于等于指定容差 | 
						|
        /// 2. 实际坐标差异大于精度容差(排除坐标系转换导致的微小差异) | 
						|
        /// </summary> | 
						|
        /// <param name="targetGeometry">需要分析的目标几何体</param> | 
						|
        /// <param name="adjacentGeometries">相邻几何体集合</param> | 
						|
        /// <param name="tolerance">空间关系判定容差(默认1mm)</param> | 
						|
        /// <returns> | 
						|
        /// true: 存在符合条件的顶点对 | false: 未找到符合条件的顶点对或输入无效 | 
						|
        /// </returns> | 
						|
        /// <remarks> | 
						|
        /// 算法复杂度:O(n*m) (建议对大规模数据使用空间索引优化) | 
						|
        /// 坐标系要求:投影坐标系(保证距离计算准确) | 
						|
        /// </remarks> | 
						|
        public static bool SpatialRelationshipAnalysis( | 
						|
            IGeometry targetGeometry, | 
						|
            IEnumerable<IGeometry> 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; | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 从几何体中提取拓扑正确的顶点集合 | 
						|
        /// </summary> | 
						|
        /// <param name="geometry">输入的几何对象</param> | 
						|
        /// <returns>顶点集合(可能为空)</returns> | 
						|
        /// <remarks> | 
						|
        /// 处理流程: | 
						|
        /// 1. 创建几何副本避免修改原始数据 | 
						|
        /// 2. 执行拓扑简化确保几何有效性 | 
						|
        /// 3. 提取顶点信息 | 
						|
        /// </remarks> | 
						|
        private static List<IPoint> ExtractTopologicalVertices(IGeometry geometry) | 
						|
        { | 
						|
            var vertices = new List<IPoint>(); | 
						|
            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; | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 从点集合中提取顶点信息 | 
						|
        /// </summary> | 
						|
        private static void ExtractVerticesFromCollection(IPointCollection source, ICollection<IPoint> 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); | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 计算两点间的平方平面距离(优化性能) | 
						|
        /// </summary> | 
						|
        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; | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 验证坐标是否具有显著差异(排除浮点误差) | 
						|
        /// </summary> | 
						|
        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; | 
						|
        } | 
						|
    } | 
						|
} |