using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geometry;
using KGIS.Framework.Utils.ExtensionMethod;
namespace Kingo.PluginServiceInterface.Helper
{
    /// 
    /// 多边形边界对齐工具(针对ArcEngine 10.2.2优化版本)
    /// 主要功能:调整目标多边形的顶点坐标,使其与相邻几何体的边界对齐
    /// 优化重点:空间索引结构、COM对象管理、批量坐标操作
    /// 
    public static class PolygonBoundaryAligner
    {
        #region 公共常量与接口
        private const double DEFAULT_TOLERANCE = 0.001;  // 默认捕捉容差(地图单位)
        private static readonly object _syncRoot = new object();  // 线程安全锁
        #endregion
        #region 主入口方法
        /// 
        /// 对齐多边形边界的主方法
        /// 
        /// 目标多边形
        /// 相邻几何体集合
        /// 捕捉容差(默认0.001)
        /// 调整后的多边形
        public static IGeometry AlignPolygonBoundary(IGeometry target, List adjacentGeometries, double tolerance = DEFAULT_TOLERANCE)
        {
            // 参数校验
            ValidateParameters(target, adjacentGeometries);
            // 克隆原始几何体(避免修改输入参数)
            IPolygon originalPolygon = (IPolygon)((IClone)target).Clone();
            IPolygon newPolygon = new PolygonClass();
            newPolygon.SpatialReference = originalPolygon.SpatialReference;
            try
            {
                // 步骤1:收集相邻几何体的边界要素
                List adjacentBoundaries = CollectAdjacentBoundaries(adjacentGeometries);
                // 步骤2:构建空间索引(顶点索引和线段索引)
                ITopologicalOperator topological = originalPolygon as ITopologicalOperator;
                var (vertexIndex, segmentIndex) = BuildSpatialIndexes(adjacentBoundaries, topological.Boundary, tolerance);
                if (vertexIndex.IsEmpty && segmentIndex.IsEmpty)
                {
                    return target;
                    //(vertexIndex, segmentIndex) = BuildSpatialIndexes(adjacentBoundaries, tolerance);  
                }
                // 步骤3:调整多边形顶点
                //IPointCollection points = (IPointCollection)originalPolygon;                
                List points = new List();
                IGeometryCollection geometryCollection = (IGeometryCollection)originalPolygon;
                for (int i = 0; i < geometryCollection.GeometryCount; i++)
                {
                    IRing ring = (IRing)geometryCollection.get_Geometry(i);
                    IPointCollection ringPoints = (IPointCollection)ring;
                    points.Add(ringPoints);
                }
                newPolygon = AdjustWithLegacyMethod(points, vertexIndex, segmentIndex, tolerance, adjacentBoundaries);
                // 步骤4:拓扑验证与简化
                EnsureTopologyValidity(ref newPolygon);
                return (IGeometry)newPolygon;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                // 显式释放COM对象(重要!防止内存泄漏)
                SafeReleaseComObject(originalPolygon);
            }
        }
        #endregion
        #region 核心处理逻辑
        /// 
        /// 获取调整后的所有环(外环+内环)
        /// 
        private static IEnumerable GetAdjustedRings(IPolygon polygon, VertexSpatialIndex vertexIndex, SegmentSpatialIndex segmentIndex, double tolerance, List boundaries)
        {
            IGeometryCollection geomColl = (IGeometryCollection)polygon;
            for (int i = 0; i < geomColl.GeometryCount; i++)
            {
                if (geomColl.get_Geometry(i) is IRing ring && !ring.IsEmpty)
                {
                    yield return AdjustRingVertices(ring, vertexIndex, segmentIndex, tolerance, boundaries);
                }
            }
        }
        private static IPolygon AdjustRingVertices(IRing ring, VertexSpatialIndex vertexIndex, SegmentSpatialIndex segmentIndex, double tolerance, List boundaries)
        {
            // 获取点集合接口(兼容10.2.2)
            IPointCollection points = (IPointCollection)ring;
            return AdjustWithLegacyMethod(new List { points }, vertexIndex, segmentIndex, tolerance, boundaries);
        }
        /// 
        /// 兼容方法:传统逐个点操作(ArcEngine 10.0 以下备用)
        /// 
        private static IPolygon AdjustWithLegacyMethod(List allPoints, VertexSpatialIndex vertexIndex, SegmentSpatialIndex segmentIndex, double tolerance, List boundaries)
        {
            IPolygon newPolygon = new PolygonClass();
            IGeometryCollection newGeomColl = (IGeometryCollection)newPolygon;
            for (int k = 0; k < allPoints.Count; k++)
            {
                int pointCount = allPoints[k].PointCount;
                bool modified = false;
                var coords = new List<(double X, double Y)>();
                for (int i = 0; i < pointCount; i++)
                {
                    IPoint p = allPoints[k].get_Point(i);
                    //string aa1 = GeometryConvertHelper.ConvertIGeoemtryToWKT(p);
                    try
                    {
                        coords.Add((p.X, p.Y));
                    }
                    finally
                    {
                        Marshal.ReleaseComObject(p);
                    }
                }
                // 坐标调整逻辑
                Dictionary keyValuePairs = new Dictionary();
                for (int i = 0; i < coords.Count; i++)
                {
                    var (x, y) = coords[i];
                    var snappedPoints = vertexIndex.FindAllVertices(x, y, tolerance).Distinct().ToList();
                    if (snappedPoints != null && snappedPoints.Count == 2)
                    {
                        double distSq0 = (coords[i].X - snappedPoints[0].X) * (coords[i].X - snappedPoints[0].X) + (coords[i].Y - snappedPoints[0].Y) * (coords[i].Y - snappedPoints[0].Y);
                        double distSq1 = (coords[i].X - snappedPoints[1].X) * (coords[i].X - snappedPoints[1].X) + (coords[i].Y - snappedPoints[1].Y) * (coords[i].Y - snappedPoints[1].Y);
                        if (distSq0 > distSq1)
                        {
                            coords[i] = snappedPoints[1];
                            keyValuePairs.Add(i, snappedPoints[0]);
                        }
                        else
                        {
                            coords[i] = snappedPoints[0];
                            keyValuePairs.Add(i, snappedPoints[1]);
                        }
                        continue;
                    }
                    var snappedPoint = vertexIndex.FindClosestVertex(x, y, tolerance);
                    if (snappedPoint == null)
                    {
                        snappedPoint = segmentIndex.FindClosestPoint(x, y, tolerance);
                    }
                    else
                    {
                        var currents = coords.Where(current => current.X != x && current.Y != y).ToList();
                        var coordscoords = currents.FirstOrDefault(kvp => Math.Abs(kvp.X - x) < 0.001 && Math.Abs(kvp.Y - y) < 0.001);
                        if ((coords.Contains(snappedPoint.Value) && coords[0] != snappedPoint.Value) || (coordscoords.X != 0 && coordscoords.Y != 0))
                        {
                            snappedPoint = segmentIndex.FindClosestPoint(x, y, tolerance);
                        }
                    }
                    if (snappedPoint.HasValue)
                    {
                        if (coords.Contains(snappedPoint.Value) && coords[0] != snappedPoint.Value)
                        {
                            int firstIndex = coords.Select((item, idx) => new { item, idx }).
                                FirstOrDefault(pair => pair.item.X == snappedPoint.Value.X && pair.item.Y == snappedPoint.Value.Y)?.idx ?? -1;
                            if (firstIndex != -1 && i > firstIndex)
                            {
                                coords[i] = (0, 0);
                                continue;
                            }
                        }
                        var currents = coords.Where(current => current.X != x && current.Y != y).ToList();
                        var coordscoords = currents.FirstOrDefault(kvp => Math.Abs(kvp.X - x) < 0.1 && Math.Abs(kvp.Y - y) < 0.1);
                        //var dSnappedPoint = CalculateDistance(snappedPoint.Value.X, snappedPoint.Value.Y, x, y);
                        //var dCoordscoords = CalculateDistance(coordscoords.X, coordscoords.Y, x, y);
                        //var gap = Math.Abs(dSnappedPoint - dCoordscoords);
                        //if (coordscoords.X != 0 && coordscoords.Y != 0 && dSnappedPoint > dCoordscoords && gap > 0.001)
                        //    continue;
                        coords[i] = snappedPoint.Value;
                        modified = true;
                    }
                }
                // 更新坐标
                if (modified)
                {
                    allPoints[k].RemovePoints(0, pointCount);
                    IPoint newPoint = new PointClass();
                    if (keyValuePairs.Count > 0)
                    {
                        foreach (var item in keyValuePairs)
                        {
                            coords.Insert(item.Key, item.Value);
                        }
                    }
                    foreach (var (X, Y) in coords)
                    {
                        if (X == 0 || Y == 0) continue;
                        newPoint.PutCoords(X, Y);
                        allPoints[k].AddPoint(newPoint);
                    }
                    Marshal.ReleaseComObject(newPoint);
                }
                newGeomColl.AddGeometry((IGeometry)allPoints[k]);
                string aa = GeometryConvertHelper.ConvertIGeoemtryToWKT(newPolygon);
                Addnode(newPolygon, boundaries);
            }
            return newPolygon;
            //IGeometryCollection geomColl = (IGeometryCollection)newPolygon;
            //for (int i = 0; i < geomColl.GeometryCount; i++)
            //{
            //    IGeometry geometry = geomColl.get_Geometry(i);
            //    IRing ring1 = geometry as IRing;
            //    if (ring1 == null || ring1.IsEmpty || ring1.Length < 0.01) continue;
            //    return ring1;
            //}
            //return null;
        }
        public static double CalculateDistance(double x1, double y1, double x2, double y2)
        {
            // 计算坐标差值的平方和
            double deltaX = x2 - x1;
            double deltaY = y2 - y1;
            double distanceSquared = deltaX * deltaX + deltaY * deltaY;
            // 开平方根得到距离(使用Math.Sqrt)
            return Math.Sqrt(distanceSquared);
        }
        #endregion
        #region 空间索引构建
        private static (VertexSpatialIndex vertexIndex, SegmentSpatialIndex segmentIndex) BuildSpatialIndexes(List boundaries, IGeometry targetBoundary, double tolerance)
        {
            double xRange = targetBoundary.Envelope.XMax - targetBoundary.Envelope.XMin;
            double yRange = targetBoundary.Envelope.YMax - targetBoundary.Envelope.YMin;
            int totalVertices = boundaries.Sum(g => (g as IPointCollection)?.PointCount ?? 0);
            double density = totalVertices / (xRange * yRange); // 顶点密度(点/单位面积)
            double baseCellSize = Math.Max(xRange, yRange) / 100;
            double cellSize = density > 100 ? baseCellSize / 2 : // 高密度:缩小网格
                       density < 10 ? baseCellSize * 2 :   // 低密度:扩大网格
                       baseCellSize;
            var vertexIndex = new VertexSpatialIndex(cellSize);
            var segmentIndex = new SegmentSpatialIndex(cellSize);
            double maxDistance = tolerance * 20; // 设定最大距离阈值
            int threshold = Math.Max(Environment.ProcessorCount * 100, 1000); // 最小阈值1000
            foreach (var geom in boundaries)
            {
                if (geom is IPointCollection pointColl)
                {
                    if (pointColl.PointCount > threshold)
                    {
                        Parallel.For(0, pointColl.PointCount, i =>
                        {
                            IPoint point = pointColl.get_Point(i);
                            try
                            {
                                double distance = CalculateDistance(point, targetBoundary);
                                if (distance <= maxDistance)
                                {
                                    vertexIndex.AddPoint(point); // 线程安全
                                }
                            }
                            finally
                            {
                                Marshal.ReleaseComObject(point);
                            }
                        });
                    }
                    else
                    {
                        for (int i = 0; i < pointColl.PointCount; i++)
                        {
                            IPoint point = pointColl.get_Point(i);
                            try
                            {
                                // 计算点到目标边界的距离
                                double distance = CalculateDistance(point, targetBoundary);
                                if (distance <= maxDistance)
                                {
                                    vertexIndex.AddPoint(point);
                                }
                            }
                            finally
                            {
                                Marshal.ReleaseComObject(point);
                            }
                        }
                    }
                }
                if (geom is ISegmentCollection segColl)
                {
                    for (int i = 0; i < segColl.SegmentCount; i++)
                    {
                        ISegment segment = segColl.get_Segment(i);
                        try
                        {
                            IPolyline polyline1 = new PolylineClass();
                            polyline1.FromPoint = segment.FromPoint;
                            polyline1.ToPoint = segment.ToPoint;
                            polyline1.SpatialReference = targetBoundary.SpatialReference;
                            double distancepolyline1 = CalculateDistance(polyline1, targetBoundary);
                            if (distancepolyline1 <= maxDistance && distancepolyline1 >= 0)
                            {
                                segmentIndex.AddSegment(segment);
                            }
                        }
                        catch
                        {
                        }
                        finally
                        {
                            Marshal.ReleaseComObject(segment);
                        }
                    }
                }
            }
            return (vertexIndex, segmentIndex);
        }
        // 计算几何体到目标边界的距离
        private static double CalculateDistance(IGeometry geom, IGeometry targetBoundary)
        {
            if (geom == null || targetBoundary == null) return double.MaxValue;
            //if (geom is IPoint point && targetBoundary is IPolygon polygon)
            //{
            //    return CalculateDistanceLocal(point, polygon); // 本地计算
            //}
            // 其他类型回退到COM调用
            try
            {
                IProximityOperator proximityOp = (IProximityOperator)targetBoundary;
                return proximityOp.ReturnDistance(geom);
            }
            catch
            {
                return double.MaxValue;
            }
        }
        #endregion
        #region 空间索引实现类
        /// 
        /// 顶点空间索引(使用双层字典的网格索引)
        /// 优化点:提高网格查询速度,减少距离计算次数
        /// 
        private class VertexSpatialIndex
        {
            private readonly Dictionary>> _grid;
            private readonly double _cellSize;
            private int _totalPoints = 0;
            public bool IsEmpty => _totalPoints == 0;
            public VertexSpatialIndex(double cellSize)
            {
                _cellSize = cellSize;
                _grid = new Dictionary>>();
            }
            /// 
            /// 添加顶点到索引(自动网格化)
            /// 
            public void AddPoint(IPoint point)
            {
                long xCell = (long)(point.X / _cellSize);
                long yCell = (long)(point.Y / _cellSize);
                lock (_syncRoot)
                {
                    if (!_grid.TryGetValue(xCell, out var yDict))
                    {
                        yDict = new Dictionary>();
                        _grid[xCell] = yDict;
                    }
                    if (!yDict.TryGetValue(yCell, out var points))
                    {
                        points = new List<(double X, double Y)>();
                        yDict[yCell] = points;
                    }
                    // 去重逻辑:检查容差范围内是否已有重复点
                    bool isDuplicate = false;
                    double toleranceSq = _cellSize * _cellSize; // 基于网格精度的容差
                    foreach (var p in points)
                    {
                        double dx = p.X - point.X;
                        double dy = p.Y - point.Y;
                        if (dx * dx + dy * dy <= toleranceSq) // 平方距离比较(避免开方)
                        {
                            isDuplicate = true;
                            break;
                        }
                    }
                    if (!isDuplicate)
                    {
                        points.Add((point.X, point.Y));
                        _totalPoints++;
                    }
                }
            }
            /// 
            /// 查找最近顶点(带容差范围)
            /// 
            public (double X, double Y)? FindClosestVertex(double x, double y, double tolerance)
            {
                long centerX = (long)(x / _cellSize);
                long centerY = (long)(y / _cellSize);
                int radius = (int)Math.Ceiling(tolerance / _cellSize);
                double minDist = tolerance * tolerance;
                (double X, double Y)? closest = null;
                // 网格搜索范围扩展
                for (long dx = -radius; dx <= radius; dx++)
                {
                    if (!_grid.TryGetValue(centerX + dx, out var yDict)) continue;
                    for (long dy = -radius; dy <= radius; dy++)
                    {
                        if (!yDict.TryGetValue(centerY + dy, out var points)) continue;
                        foreach (var (pX, pY) in points)
                        {
                            double dxVal = pX - x;
                            double dyVal = pY - y;
                            double distSq = dxVal * dxVal + dyVal * dyVal;
                            if (distSq < minDist)
                            {
                                minDist = distSq;
                                closest = (pX, pY);
                            }
                        }
                    }
                }
                return closest;
            }
            /// 
            /// 根据坐标获取相邻范围内的所有点
            /// 
            /// 
            /// 
            /// 
            /// 
            public List<(double X, double Y)> FindAllVertices(double x, double y, double tolerance)
            {
                long centerX = (long)(x / _cellSize);
                long centerY = (long)(y / _cellSize);
                int radius = (int)Math.Ceiling(tolerance / _cellSize);
                var result = new List<(double X, double Y)>();
                double toleranceSq = tolerance * tolerance;
                // 遍历邻近网格
                for (long dx = -radius; dx <= radius; dx++)
                {
                    if (!_grid.TryGetValue(centerX + dx, out var yDict)) continue;
                    for (long dy = -radius; dy <= radius; dy++)
                    {
                        if (!yDict.TryGetValue(centerY + dy, out var points)) continue;
                        // 筛选所有容差内的点
                        foreach (var (pX, pY) in points)
                        {
                            double distSq = (pX - x) * (pX - x) + (pY - y) * (pY - y);
                            if (distSq <= toleranceSq)
                            {
                                result.Add((pX, pY));
                            }
                        }
                    }
                }
                return result;
            }
        }
        /// 
        /// 线段空间索引(使用网格索引+包围盒预计算)
        /// 优化点:减少不必要的线段距离计算
        /// 
        private class SegmentSpatialIndex
        {
            private readonly Dictionary>> _grid;
            private readonly List _allSegments;
            private readonly double _cellSize;
            public bool IsEmpty => _grid.Count == 0;
            public SegmentSpatialIndex(double cellSize)
            {
                _cellSize = cellSize;
                _grid = new Dictionary>>();
                _allSegments = new List();
            }
            /// 
            /// 添加线段到索引(自动计算影响网格)
            /// 
            public void AddSegment(ISegment segment)
            {
                var segData = new SegmentData(segment.FromPoint.X, segment.FromPoint.Y, segment.ToPoint.X, segment.ToPoint.Y);
                lock (_syncRoot)
                {
                    _allSegments.Add(segData);  // 全局列表存储引用
                                                // 计算网格范围
                    long minXCell = (long)(Math.Min(segData.StartX, segData.EndX) / _cellSize);
                    long maxXCell = (long)(Math.Max(segData.StartX, segData.EndX) / _cellSize);
                    long minYCell = (long)(Math.Min(segData.StartY, segData.EndY) / _cellSize);
                    long maxYCell = (long)(Math.Max(segData.StartY, segData.EndY) / _cellSize);
                    // 添加到所有覆盖的网格(引用传递,无副本)
                    for (long x = minXCell; x <= maxXCell; x++)
                    {
                        for (long y = minYCell; y <= maxYCell; y++)
                        {
                            if (!_grid.TryGetValue(x, out var yDict))
                            {
                                yDict = new Dictionary>();
                                _grid[x] = yDict;
                            }
                            if (!yDict.TryGetValue(y, out var list))
                            {
                                list = new List();
                                yDict[y] = list;
                            }
                            // 避免重复添加(若外部可能重复调用AddSegment)
                            if (!list.Contains(segData))
                            {
                                list.Add(segData);
                            }
                        }
                    }
                }
            }
            /// 
            /// 查找最近线段点(两阶段查询:先网格后全局)
            /// 
            public (double X, double Y)? FindClosestPoint(double x, double y, double tolerance)
            {
                long centerX = (long)(x / _cellSize);
                long centerY = (long)(y / _cellSize);
                int radius = (int)Math.Ceiling(tolerance / _cellSize);
                var candidates = new HashSet();
                double minDist = tolerance * tolerance;
                (double X, double Y)? closest = null;
                // 阶段1:收集附近网格中的候选线段
                for (long dx = -radius; dx <= radius; dx++)
                {
                    if (!_grid.TryGetValue(centerX + dx, out var yDict)) continue;
                    for (long dy = -radius; dy <= radius; dy++)
                    {
                        if (yDict.TryGetValue(centerY + dy, out var segList))
                        {
                            foreach (var seg in segList)
                            {
                                candidates.Add(seg);
                            }
                        }
                    }
                }
                // 阶段2:如果附近没有候选,则遍历全部线段
                if (candidates.Count == 0)
                {
                    candidates = new HashSet(_allSegments);
                }
                // 计算最近点
                foreach (var seg in candidates)
                {
                    var (cx, cy, distSq) = CalculateClosestPoint(x, y, seg);
                    if (distSq < minDist)
                    {
                        minDist = distSq;
                        closest = (cx, cy);
                    }
                }
                return closest;
            }
            /// 
            /// 计算点到线段的最短距离(向量投影法)
            /// 
            private static (double X, double Y, double DistanceSq) CalculateClosestPoint(
                double x, double y, SegmentData seg)
            {
                double dx = seg.EndX - seg.StartX;
                double dy = seg.EndY - seg.StartY;
                double lengthSq = dx * dx + dy * dy;
                // 处理零长度线段
                if (lengthSq < 1e-10)
                {
                    double distSq1 = (x - seg.StartX) * (x - seg.StartX) + (y - seg.StartY) * (y - seg.StartY);
                    return (seg.StartX, seg.StartY, distSq1);
                }
                // 计算投影参数
                double t = ((x - seg.StartX) * dx + (y - seg.StartY) * dy) / lengthSq;
                t = Math.Max(0, Math.Min(1, t));  // 限制在线段范围内
                double projX = seg.StartX + t * dx;
                double projY = seg.StartY + t * dy;
                double distSq = (x - projX) * (x - projX) + (y - projY) * (y - projY);
                return (projX, projY, distSq);
            }
            /// 
            /// 线段数据结构(引用类型)
            /// 
            private sealed class SegmentData
            {
                public double StartX { get; }
                public double StartY { get; }
                public double EndX { get; }
                public double EndY { get; }
                public SegmentData(double sx, double sy, double ex, double ey)
                {
                    StartX = sx;
                    StartY = sy;
                    EndX = ex;
                    EndY = ey;
                }
            }
        }
        #endregion
        #region 辅助方法
        /// 
        /// 参数有效性校验
        /// 
        private static void ValidateParameters(IGeometry target, List adjacentGeometries)
        {
            if (target == null)
                throw new ArgumentNullException(nameof(target), "目标几何体不能为空");
            if (adjacentGeometries == null)
                throw new ArgumentNullException(nameof(adjacentGeometries), "相邻几何体集合不能为空");
            if (target.GeometryType != esriGeometryType.esriGeometryPolygon)
                throw new ArgumentException("目标几何体必须是多边形类型");
        }
        /// 
        /// 收集相邻几何体的边界要素(多线程安全)
        /// 
        private static List CollectAdjacentBoundaries(IEnumerable geometries)
        {
            var boundaries = new ConcurrentBag(); // 线程安全集合
            Parallel.ForEach(geometries.Where(g => g?.IsEmpty == false), geom =>
            {
                switch (geom.GeometryType)
                {
                    case esriGeometryType.esriGeometryPolygon:
                        var polyColl = (IGeometryCollection)geom;
                        for (int i = 0; i < polyColl.GeometryCount; i++)
                        {
                            if (polyColl.get_Geometry(i) is IRing ring && !ring.IsEmpty)
                            {
                                ring.SpatialReference = geom.SpatialReference;
                                boundaries.Add(ring); // 线程安全添加
                            }
                        }
                        break;
                    case esriGeometryType.esriGeometryPolyline:
                        boundaries.Add(geom);
                        break;
                }
            });
            return boundaries.ToList(); // 转换为普通列表
        }
        /// 
        /// 确保多边形拓扑有效性
        /// 
        private static void EnsureTopologyValidity(ref IPolygon polygon)
        {
            ITopologicalOperator topoOp = (ITopologicalOperator)polygon;
            if (!topoOp.IsSimple)
            {
                topoOp.Simplify();
            }
            // 二次验证几何完整性
            if (polygon.IsEmpty)
            {
                throw new InvalidOperationException("拓扑简化导致几何体无效");
            }
        }
        /// 
        /// 安全释放COM对象(带空值检查)
        /// 
        private static void SafeReleaseComObject(object comObj)
        {
            if (comObj != null && Marshal.IsComObject(comObj))
            {
                Marshal.ReleaseComObject(comObj);
            }
        }
        #endregion
        #region MyRegion
        private static void Addnode(IPolygon newPolygon, List adjacentGeometries)
        {
            double maxDistance = 0.1; // 设定最大距离阈值
            //待插入节点坐标及索引
            Dictionary insertionPoints = new Dictionary();
            //原始图形的点坐标及索引
            Dictionary originalpoints = new Dictionary();
            List polylines = new List();
            var coords = new List<(double X, double Y)>();
            try
            {
                IPointCollection points = (IPointCollection)newPolygon;
                var pointCount = points.PointCount;
                for (int i = 0; i < pointCount; i++)
                {
                    IPoint p = points.get_Point(i);
                    try
                    {
                        coords.Add((p.X, p.Y));
                        originalpoints.Add(i, (p.X, p.Y));
                    }
                    finally
                    {
                        Marshal.ReleaseComObject(p);
                    }
                }
                if (newPolygon is ISegmentCollection segColl)
                {
                    for (int i = 0; i < segColl.SegmentCount; i++)
                    {
                        ISegment segment = segColl.get_Segment(i);
                        try
                        {
                            IPolyline polyline1 = new PolylineClass();
                            polyline1.FromPoint = segment.FromPoint;
                            polyline1.ToPoint = segment.ToPoint;
                            polyline1.SpatialReference = newPolygon.SpatialReference;
                            polylines.Add(polyline1);
                        }
                        finally
                        {
                            Marshal.ReleaseComObject(segment);
                        }
                    }
                }
                bool isbreak = false;
                foreach (IGeometry geom in adjacentGeometries)
                {
                    if (geom is IPointCollection pointColl)
                    {
                        for (int i = 0; i < pointColl.PointCount; i++)
                        {
                            IPoint point = pointColl.get_Point(i);
                            try
                            {
                                foreach (var polyline in polylines)
                                {
                                    double distance = CalculateDistance(point, polyline);
                                    if (distance == 0 || distance > 1) continue;
                                    double distanceToPoint = CalculateDistance(point, polyline.ToPoint);
                                    double distanceFromPoint = CalculateDistance(point, polyline.FromPoint);
                                    if (distance == distanceToPoint || distance == distanceFromPoint) continue;
                                    if ((distance < 0.01 && (distanceToPoint < 0.01) || distanceFromPoint < 0.01))
                                        continue;
                                    if (distance <= maxDistance && distance.ToDouble(5) > 0.00001)
                                    {
                                        if (coords.Contains((point.X, point.Y))) continue;
                                        var coordscoords = coords.FirstOrDefault(kvp => Math.Abs(kvp.X - point.X) < 0.1 && Math.Abs(kvp.Y - point.Y) < 0.1);
                                        if (coordscoords.X != 0 && coordscoords.Y != 0) continue;
                                        IPoint ToPoint = polyline.ToPoint;
                                        var keyValuePair2 = originalpoints.FirstOrDefault(kvp => Math.Abs(kvp.Value.X - ToPoint.X) < 0.0001 && Math.Abs(kvp.Value.Y - ToPoint.Y) < 0.0001);
                                        var pointindex = keyValuePair2.Equals(default(KeyValuePair)) ? -1 : keyValuePair2.Key;
                                        if (insertionPoints.ContainsKey(pointindex)) continue;
                                        insertionPoints.Add(pointindex, (point.X, point.Y));
                                        isbreak = true;
                                        break;
                                    }
                                }
                                if (isbreak) break;
                            }
                            finally
                            {
                                Marshal.ReleaseComObject(point);
                            }
                        }
                    }
                    if (isbreak) break;
                }
                if (insertionPoints.Count > 0)
                {
                    foreach (var item in insertionPoints)
                        coords.Insert(item.Key, item.Value);
                    points.RemovePoints(0, pointCount);
                    IPoint newPoint = new PointClass();
                    foreach (var (X, Y) in coords)
                    {
                        newPoint.PutCoords(X, Y);
                        points.AddPoint(newPoint);
                    }
                    Marshal.ReleaseComObject(newPoint);
                    Addnode(newPolygon, adjacentGeometries);
                }
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion
    }
}