using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using KGIS.Framework.AE;
using KGIS.Framework.AE.ExtensionMethod;
using KGIS.Framework.Maps;
using KGIS.Framework.Utils;
using KGIS.Framework.Utils.ExtensionMethod;
using NPOI.SS.Formula.Functions;
using NPOI.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Shapes;
namespace Kingo.PluginServiceInterface.Helper
{
    /// 
    /// 边界修复
    /// 
    public static class BoundaryRepairHelper
    {
        /// 
        /// 执行边界套合修复逻辑
        /// 
        /// 待修复的图斑
        /// 修复图层
        /// 参考图层
        /// 
        public static IGeometry ExecuteBoundaryRepair(IGeometry geometry, IFeatureLayer RepairLayer, IFeatureLayer ReferenceLayer, double distance)
        {
            try
            {
                IGeometryCollection geometryCollection = geometry as IGeometryCollection;
                IGeometry insidegeo = null;
                ISegmentCollection final = new PolygonClass();
                for (int p = 0; p < geometryCollection.GeometryCount; p++)
                {
                    insidegeo = geometryCollection.get_Geometry(p);
                    List repairpoints = LayerHelper.GetMultipleRingPoints(insidegeo);
                    var count = 0;
                    foreach (var point in repairpoints)
                    {
                        count++;
                        if (count == 8)
                        {
                            var x = point.X;
                            var Y = point.Y;
                        }
                        var UpdatePoint = GetSnappingpoint(point, ReferenceLayer, distance);
                        if (UpdatePoint.Count == 0)
                        {
                            UpdatePoint = GetSnappingpoint(point, RepairLayer, distance);
                        }
                        if (UpdatePoint.Count == 0) continue;
                        var Listpoint = UpdatePoint.OrderByDescending(x => x.Value).ToList();
                        IPoint moveToPoint = null;
                        if (Listpoint.Count > 0)
                        {
                            #region 如果存在共点>1的,则删除共点=1的
                            var where = Listpoint.Where(x => x.Value > 1).ToList();
                            if (where.Count > 0)
                            {
                                where = Listpoint.Where(x => x.Value == 1).ToList();
                                foreach (var item in where)
                                {
                                    Listpoint.Remove(item);
                                }
                            }
                            #endregion
                            #region 共点个数相同的情况下,取距离最近的点
                            var GroupBy = Listpoint.GroupBy(x => x.Value).ToList();
                            if (Listpoint.Count > 1)
                            {
                                double refdistance = -1;
                                double mindistance = -1;
                                var index = -1;
                                for (int i = 0; i < Listpoint.Count; i++)
                                {
                                    refdistance = Math.Sqrt((point.X - Listpoint[i].Key.X) * (point.X - Listpoint[i].Key.X) + (point.Y - Listpoint[i].Key.Y) * (point.Y - Listpoint[i].Key.Y));
                                    if (mindistance == -1)
                                    {
                                        mindistance = refdistance;
                                        index = i;
                                    }
                                    else if (refdistance < mindistance)
                                    {
                                        mindistance = refdistance;
                                        index = i;
                                    }
                                }
                                if (index != -1)
                                {
                                    moveToPoint = Listpoint[index].Key;
                                    Listpoint.RemoveAt(index);
                                }
                            }
                            else
                            {
                                moveToPoint = Listpoint[0].Key;
                                Listpoint.RemoveAt(0);
                            }
                            #endregion
                        }
                        if (moveToPoint != null)
                        {
                            IPointCollection points = insidegeo as IPointCollection;
                            var index = -1;
                            for (int i = 0; i < points.PointCount - 1; i++)
                            {
                                IPoint tPoint = points.Point[i];
                                var refdistance = Math.Sqrt((point.X - tPoint.X) * (point.X - tPoint.X) + (point.Y - tPoint.Y) * (point.Y - tPoint.Y));
                                if (refdistance == 0 || Math.Abs(refdistance) < (1e-5))
                                {
                                    index = i; break;
                                }
                            }
                            if (index > -1)
                            {
                                var refdistance = Math.Sqrt((point.X - moveToPoint.X) * (point.X - moveToPoint.X) + (point.Y - moveToPoint.Y) * (point.Y - moveToPoint.Y));
                                if (refdistance == 0) continue;
                                points.UpdatePoint(index, moveToPoint);
                            }
                            List firstSnapPointList = Snapping(point, RepairLayer, distance);
                            if (firstSnapPointList != null && firstSnapPointList.Count > 1)
                            {
                                foreach (var item in firstSnapPointList)
                                {
                                    IGeometryCollection collection = item.Geometry as IGeometryCollection;
                                    IGeometry geo = collection.get_Geometry(item.PartIndex);
                                    points = geo as IPointCollection;
                                    IPoint pt = points.get_Point(item.VertexIndex);
                                    points.UpdatePoint(item.VertexIndex, moveToPoint);
                                    item.Feature.Shape = item.Geometry;
                                    item.Feature.Store();
                                }
                            }
                        }
                        if (Listpoint.Count > 0)
                        {
                            IGeometry line = PolygonToPolyline(insidegeo);
                            if (line.GeometryType == esriGeometryType.esriGeometryPolyline)
                            {
                                bool SplitHappened;
                                int newPartIndex;
                                int newSegmentIndex;
                                for (int i = 0; i < Listpoint.Count; i++)
                                {
                                    if (Listpoint[i].Value > 1)
                                    {
                                        IPolyline polyline = line as IPolyline;
                                        IPoint point1 = new PointClass();
                                        var DistanceAlongCurve = 0.0001;
                                        var distanceFromCurve = 0.0001;
                                        bool bRightSide = true;
                                        polyline.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, Listpoint[i].Key, false, point1, ref DistanceAlongCurve, ref distanceFromCurve, bRightSide);
                                        var pointdistance = Math.Sqrt((Listpoint[i].Key.X - point1.X) * (Listpoint[i].Key.X - point1.X) + (Listpoint[i].Key.Y - point1.Y) * (Listpoint[i].Key.Y - point1.Y));
                                        if (pointdistance > 0.1 || pointdistance < 0.01) continue;
                                        (line as IPolyline).SplitAtPoint(Listpoint[i].Key, true, true, out SplitHappened, out newPartIndex, out newSegmentIndex);
                                        insidegeo = ConstructPolygonFromPolyline((line as IPolyline));
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    final.AddSegmentCollection(insidegeo as ISegmentCollection);
                }
                geometry = final as IPolygon;
                #region 判断当前图斑是否压盖多个图斑且存在碎图斑
                var Identify2 = FeatureAPI.Identify2(geometry, ReferenceLayer);
                if (Identify2 != null && Identify2.Count > 0)
                {
                    foreach (var feature1 in Identify2)
                    {
                        #region 相交部分
                        var geo = FeatureAPI.InterSect(geometry, feature1.ShapeCopy);
                        List geometries = FeatureAPI.DissolveGeometryByRing(geo);
                        if (geometries != null && geometries.Count > 0)
                        {
                            foreach (var item in geometries)
                            {
                                ITopologicalOperator topoOpr = item as ITopologicalOperator;
                                topoOpr.Simplify();
                                var mj = item.GetEllipseArea();
                                if (mj < 1 && !item.IsEmpty && mj != 0 && mj > 0.01)
                                    geometry = FeatureAPI.Difference(geometry, item);
                            }
                        }
                        else
                        {
                            continue;
                        }
                        #endregion
                        #region 不相交部分
                        geo = FeatureAPI.Difference(feature1.ShapeCopy, geometry);
                        geometries = FeatureAPI.DissolveGeometryByRing(geo);
                        if (geometries != null && geometries.Count > 0)
                        {
                            foreach (var item in geometries)
                            {
                                ITopologicalOperator topoOpr = item as ITopologicalOperator;
                                topoOpr.Simplify();
                                var mj = item.GetEllipseArea();
                                if (mj < 1 && !item.IsEmpty)
                                {
                                    if (FeatureAPI.LengthOfSide(geometry, item) > 0)
                                        geometry = FeatureAPI.Union(geometry, item);
                                }
                            }
                        }
                        #endregion
                    }
                }
                #endregion
            }
            catch (Exception ex)
            {
                LogAPI.Debug("执行ExecuteRepair异常:" + ex.Message + ex.StackTrace);
                return geometry;
            }
            return geometry;
        }
        /// 
        /// 执行边界套合修复逻辑
        /// 
        /// 待修复的图斑
        /// 修复图层
        /// 参考图层
        /// 
        public static IGeometry ExecuteBoundaryRepair1(IGeometry geometry, IFeatureLayer RepairLayer, IFeatureLayer ReferenceLayer, double distance)
        {
            try
            {
                List Identify = FeatureAPI.Identify(geometry, ReferenceLayer);
                double MaxOccupyArea = -1;//图形占基础图斑面积
                int ReferenceOID = -1;
                foreach (IFeature feature in Identify)
                {
                    var InterSectgeo = FeatureAPI.InterSect(geometry, feature.ShapeCopy);
                    double mj = InterSectgeo.GetEllipseArea();
                    if (MaxOccupyArea == -1)
                    {
                        MaxOccupyArea = mj;
                        ReferenceOID = feature.OID;
                    }
                    else if (mj > MaxOccupyArea)
                    {
                        MaxOccupyArea = mj;
                        ReferenceOID = feature.OID;
                    }
                }
                IGeometryCollection geometryCollection = geometry as IGeometryCollection;
                IGeometry insidegeo = null;
                ISegmentCollection final = new PolygonClass();
                List RepairdPoint = new List();//已修复的点
                for (int p = 0; p < geometryCollection.GeometryCount; p++)
                {
                    insidegeo = geometryCollection.get_Geometry(p);
                    List repairpoints = LayerHelper.GetMultipleRingPoints(insidegeo);
                    var count = 0;
                    foreach (var point in repairpoints)
                    {
                        count++;
                        if (count == 7)
                        {
                            var x = point.X;
                            var Y = point.Y;
                        }
                        var UpdatePoint = GetSnappingpoint1(point, ReferenceLayer, distance);
                        if (UpdatePoint.Count == 0)
                        {
                            UpdatePoint = GetSnappingpoint1(point, RepairLayer, 0.01);
                        }
                        if (UpdatePoint.Count == 0) continue;
                        var Listpoint = UpdatePoint.OrderByDescending(x => x.ConcurrentCount).ToList();
                        IPoint moveToPoint = null;
                        if (Listpoint.Count > 0)
                        {
                            #region 如果存在共点>1的,则删除共点=1的
                            var where = Listpoint.Where(x => x.ConcurrentCount > 1).ToList();
                            if (where.Count > 0)
                            {
                                where = Listpoint.Where(x => x.ConcurrentCount == 1).ToList();
                                foreach (var item in where)
                                {
                                    Listpoint.Remove(item);
                                }
                            }
                            #endregion
                            #region 取距离最近的点
                            if (Listpoint.Count > 1)
                            {
                                double mindistance = -1;
                                var index = -1;
                                for (int i = 0; i < Listpoint.Count; i++)
                                {
                                    if (!Listpoint[i].ListObjectID.Contains(ReferenceOID)) continue;
                                    double refdistance = Math.Sqrt((point.X - Listpoint[i].Point.X) * (point.X - Listpoint[i].Point.X) + (point.Y - Listpoint[i].Point.Y) * (point.Y - Listpoint[i].Point.Y));
                                    if (mindistance == -1)
                                    {
                                        mindistance = refdistance;
                                        index = i;
                                    }
                                    else if (refdistance < mindistance)
                                    {
                                        mindistance = refdistance;
                                        index = i;
                                    }
                                }
                                if (index == -1)
                                {
                                    for (int i = 0; i < Listpoint.Count; i++)
                                    {
                                        var ReferenceIdentify = FeatureAPI.Identify2(point, ReferenceLayer);
                                        if (ReferenceIdentify.Count == 1)
                                        {
                                            foreach (var item in ReferenceIdentify)
                                            {
                                                if (Listpoint[i].ListObjectID.Contains(item.OID))
                                                {
                                                    index = i;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    if (index == -1)
                                    {
                                        for (int i = 0; i < Listpoint.Count; i++)
                                        {
                                            double refdistance = Math.Sqrt((point.X - Listpoint[i].Point.X) * (point.X - Listpoint[i].Point.X) + (point.Y - Listpoint[i].Point.Y) * (point.Y - Listpoint[i].Point.Y));
                                            if (mindistance == -1)
                                            {
                                                mindistance = refdistance;
                                                index = i;
                                            }
                                            else if (refdistance < mindistance)
                                            {
                                                mindistance = refdistance;
                                                index = i;
                                            }
                                        }
                                    }
                                }
                                if (index != -1)
                                {
                                    moveToPoint = Listpoint[index].Point;
                                    Listpoint.RemoveAt(index);
                                    RepairdPoint.Add(moveToPoint);
                                }
                            }
                            else
                            {
                                moveToPoint = Listpoint[0].Point;
                                Listpoint.RemoveAt(0);
                                RepairdPoint.Add(moveToPoint);
                            }
                            #endregion
                        }
                        if (moveToPoint != null)
                        {
                            IPointCollection points = insidegeo as IPointCollection;
                            var index = -1;
                            for (int i = 0; i < points.PointCount - 1; i++)
                            {
                                IPoint tPoint = points.Point[i];
                                var refdistance = Math.Sqrt((point.X - tPoint.X) * (point.X - tPoint.X) + (point.Y - tPoint.Y) * (point.Y - tPoint.Y));
                                if (refdistance == 0 || Math.Abs(refdistance) < (1e-5))
                                {
                                    index = i; break;
                                }
                            }
                            if (index > -1)
                            {
                                var refdistance = Math.Sqrt((point.X - moveToPoint.X) * (point.X - moveToPoint.X) + (point.Y - moveToPoint.Y) * (point.Y - moveToPoint.Y));
                                if (refdistance == 0) continue;
                                points.UpdatePoint(index, moveToPoint);
                            }
                            List firstSnapPointList = Snapping(point, RepairLayer, distance);
                            if (firstSnapPointList != null && firstSnapPointList.Count > 1)
                            {
                                foreach (var item in firstSnapPointList)
                                {
                                    IGeometryCollection collection = item.Geometry as IGeometryCollection;
                                    IGeometry geo = collection.get_Geometry(item.PartIndex);
                                    points = geo as IPointCollection;
                                    IPoint pt = points.get_Point(item.VertexIndex);
                                    points.UpdatePoint(item.VertexIndex, moveToPoint);
                                    item.Feature.Shape = item.Geometry;
                                    item.Feature.Store();
                                }
                            }
                        }
                        if (Listpoint.Count > 0)
                        {
                            IGeometry line = PolygonToPolyline(insidegeo);
                            if (line.GeometryType == esriGeometryType.esriGeometryPolyline)
                            {
                                bool SplitHappened;
                                int newPartIndex;
                                int newSegmentIndex;
                                for (int i = 0; i < Listpoint.Count; i++)
                                {
                                    if (Listpoint[i].ConcurrentCount > 1)
                                    {
                                        IPolyline polyline = line as IPolyline;
                                        IPoint point1 = new PointClass();
                                        var DistanceAlongCurve = 0.0001;
                                        var distanceFromCurve = 0.0001;
                                        bool bRightSide = true;
                                        polyline.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, Listpoint[i].Point, false, point1, ref DistanceAlongCurve, ref distanceFromCurve, bRightSide);
                                        var pointdistance = Math.Sqrt((Listpoint[i].Point.X - point1.X) * (Listpoint[i].Point.X - point1.X) + (Listpoint[i].Point.Y - point1.Y) * (Listpoint[i].Point.Y - point1.Y));
                                        if (pointdistance > 0.1 || pointdistance < 0.01) continue;
                                        IPolyline polyline1 = new PolylineClass();
                                        polyline1.FromPoint = point1;
                                        polyline1.ToPoint = moveToPoint;
                                        polyline1.SpatialReference = moveToPoint.SpatialReference;
                                        if (FeatureAPI.IsContains(line, polyline1)) continue;
                                        (line as IPolyline).SplitAtPoint(Listpoint[i].Point, true, true, out SplitHappened, out newPartIndex, out newSegmentIndex);
                                        insidegeo = ConstructPolygonFromPolyline((line as IPolyline));
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    final.AddSegmentCollection(insidegeo as ISegmentCollection);
                }
                geometry = final as IPolygon;
                #region 判断当前图斑是否压盖多个图斑且存在碎图斑
                var Identify2 = FeatureAPI.Identify2(geometry, ReferenceLayer);
                if (Identify2 != null && Identify2.Count > 0)
                {
                    foreach (var feature1 in Identify2)
                    {
                        #region 相交部分
                        var geo = FeatureAPI.InterSect(geometry, feature1.ShapeCopy);
                        List geometries = FeatureAPI.DissolveGeometryByRing(geo);
                        if (geometries != null && geometries.Count > 0)
                        {
                            foreach (var item in geometries)
                            {
                                ITopologicalOperator topoOpr = item as ITopologicalOperator;
                                topoOpr.Simplify();
                                var mj = item.GetEllipseArea();
                                if (mj < 1 && !item.IsEmpty)
                                    geometry = FeatureAPI.Difference(geometry, item);
                            }
                        }
                        else
                        {
                            continue;
                        }
                        #endregion
                        #region 不相交部分
                        geo = FeatureAPI.Difference(feature1.ShapeCopy, geometry);
                        geometries = FeatureAPI.DissolveGeometryByRing(geo);
                        if (geometries != null && geometries.Count > 0)
                        {
                            foreach (var item in geometries)
                            {
                                ITopologicalOperator topoOpr = item as ITopologicalOperator;
                                topoOpr.Simplify();
                                var mj = item.GetEllipseArea();
                                if (mj < 1 && !item.IsEmpty)
                                {
                                    if (FeatureAPI.LengthOfSide(geometry, item) > 0)
                                        geometry = FeatureAPI.Union(geometry, item);
                                }
                            }
                        }
                        #endregion
                    }
                }
                #endregion
            }
            catch (Exception ex)
            {
                LogAPI.Debug("执行ExecuteRepair异常:" + ex.Message + ex.StackTrace);
                return geometry;
            }
            return geometry;
        }
        /// 
        /// 执行边界套合修复逻辑
        /// 
        /// 待修复的图斑
        /// 修复图层
        /// 参考图层
        /// 
        public static IGeometry ExecuteBoundaryRepair2(IGeometry geometry, List RepairLayer, List ReferenceLayer, double distance)
        {
            try
            {
                IGeometryCollection geometryCollection = geometry as IGeometryCollection;
                IGeometry insidegeo = null;
                ISegmentCollection final = new PolygonClass();
                List RepairdPoint = new List();//已修复的点
                for (int p = 0; p < geometryCollection.GeometryCount; p++)
                {
                    insidegeo = geometryCollection.get_Geometry(p);
                    List repairpoints = LayerHelper.GetMultipleRingPoints(insidegeo);
                    var count = 0;
                    foreach (var point in repairpoints)
                    {
                        count++;
                        if (count == 7)
                        {
                            var x = point.X;
                            var Y = point.Y;
                        }
                        var UpdatePoint = GetSnappingpoint2(point, ReferenceLayer, null, distance);
                        if (UpdatePoint.Count == 0)
                        {
                            UpdatePoint = GetSnappingpoint2(point, RepairLayer, null, 0.01);
                        }
                        if (UpdatePoint.Count == 0) continue;
                        var Listpoint = UpdatePoint.OrderByDescending(x => x.ConcurrentCount).ToList();
                        IPoint moveToPoint = null;
                        if (Listpoint.Count > 0)
                        {
                            #region 如果存在共点>1的,则删除共点=1的
                            var where = Listpoint.Where(x => x.ConcurrentCount > 1).ToList();
                            if (where.Count > 0)
                            {
                                where = Listpoint.Where(x => x.ConcurrentCount == 1).ToList();
                                foreach (var item in where)
                                {
                                    Listpoint.Remove(item);
                                }
                            }
                            #endregion
                            #region 取距离最近的点
                            if (Listpoint.Count > 1)
                            {
                                double mindistance = -1;
                                var index = -1;
                                for (int i = 0; i < Listpoint.Count; i++)
                                {
                                    double refdistance = Math.Sqrt((point.X - Listpoint[i].Point.X) * (point.X - Listpoint[i].Point.X) + (point.Y - Listpoint[i].Point.Y) * (point.Y - Listpoint[i].Point.Y));
                                    if (mindistance == -1)
                                    {
                                        mindistance = refdistance;
                                        index = i;
                                    }
                                    else if (refdistance < mindistance)
                                    {
                                        mindistance = refdistance;
                                        index = i;
                                    }
                                }
                                if (index == -1)
                                {
                                    for (int i = 0; i < Listpoint.Count; i++)
                                    {
                                        //var ReferenceIdentify = FeatureAPI.Identify2(point, ReferenceLayer);
                                        //if (ReferenceIdentify.Count == 1)
                                        //{
                                        //    foreach (var item in ReferenceIdentify)
                                        //    {
                                        //        if (Listpoint[i].ListObjectID.Contains(item.OID))
                                        //        {
                                        //            index = i;
                                        //            break;
                                        //        }
                                        //    }
                                        //}
                                    }
                                    if (index == -1)
                                    {
                                        for (int i = 0; i < Listpoint.Count; i++)
                                        {
                                            double refdistance = Math.Sqrt((point.X - Listpoint[i].Point.X) * (point.X - Listpoint[i].Point.X) + (point.Y - Listpoint[i].Point.Y) * (point.Y - Listpoint[i].Point.Y));
                                            if (mindistance == -1)
                                            {
                                                mindistance = refdistance;
                                                index = i;
                                            }
                                            else if (refdistance < mindistance)
                                            {
                                                mindistance = refdistance;
                                                index = i;
                                            }
                                        }
                                    }
                                }
                                if (index != -1)
                                {
                                    moveToPoint = Listpoint[index].Point;
                                    Listpoint.RemoveAt(index);
                                    RepairdPoint.Add(moveToPoint);
                                }
                            }
                            else
                            {
                                moveToPoint = Listpoint[0].Point;
                                Listpoint.RemoveAt(0);
                                RepairdPoint.Add(moveToPoint);
                            }
                            #endregion
                        }
                        if (moveToPoint != null)
                        {
                            IPointCollection points = insidegeo as IPointCollection;
                            var index = -1;
                            for (int i = 0; i < points.PointCount - 1; i++)
                            {
                                IPoint tPoint = points.Point[i];
                                var refdistance = Math.Sqrt((point.X - tPoint.X) * (point.X - tPoint.X) + (point.Y - tPoint.Y) * (point.Y - tPoint.Y));
                                if (refdistance == 0 || Math.Abs(refdistance) < (1e-5))
                                {
                                    index = i; break;
                                }
                            }
                            if (index > -1)
                            {
                                var refdistance = Math.Sqrt((point.X - moveToPoint.X) * (point.X - moveToPoint.X) + (point.Y - moveToPoint.Y) * (point.Y - moveToPoint.Y));
                                if (refdistance == 0) continue;
                                points.UpdatePoint(index, moveToPoint);
                            }
                            List firstSnapPointList = Snapping2(point, RepairLayer, distance);
                            if (firstSnapPointList != null && firstSnapPointList.Count > 1)
                            {
                                foreach (var item in firstSnapPointList)
                                {
                                    IGeometryCollection collection = item.Geometry as IGeometryCollection;
                                    IGeometry geo = collection.get_Geometry(item.PartIndex);
                                    points = geo as IPointCollection;
                                    IPoint pt = points.get_Point(item.VertexIndex);
                                    points.UpdatePoint(item.VertexIndex, moveToPoint);
                                    item.Feature.Shape = item.Geometry;
                                    item.Feature.Store();
                                }
                            }
                        }
                        if (Listpoint.Count > 0)
                        {
                            IGeometry line = PolygonToPolyline(insidegeo);
                            if (line.GeometryType == esriGeometryType.esriGeometryPolyline)
                            {
                                bool SplitHappened;
                                int newPartIndex;
                                int newSegmentIndex;
                                for (int i = 0; i < Listpoint.Count; i++)
                                {
                                    if (Listpoint[i].ConcurrentCount > 1)
                                    {
                                        IPolyline polyline = line as IPolyline;
                                        IPoint point1 = new PointClass();
                                        var DistanceAlongCurve = 0.0001;
                                        var distanceFromCurve = 0.0001;
                                        bool bRightSide = true;
                                        polyline.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, Listpoint[i].Point, false, point1, ref DistanceAlongCurve, ref distanceFromCurve, bRightSide);
                                        var pointdistance = Math.Sqrt((Listpoint[i].Point.X - point1.X) * (Listpoint[i].Point.X - point1.X) + (Listpoint[i].Point.Y - point1.Y) * (Listpoint[i].Point.Y - point1.Y));
                                        if (pointdistance > 0.1 || pointdistance < 0.01) continue;
                                        IPolyline polyline1 = new PolylineClass();
                                        polyline1.FromPoint = point1;
                                        polyline1.ToPoint = moveToPoint;
                                        polyline1.SpatialReference = moveToPoint.SpatialReference;
                                        if (FeatureAPI.IsContains(line, polyline1)) continue;
                                        (line as IPolyline).SplitAtPoint(Listpoint[i].Point, true, true, out SplitHappened, out newPartIndex, out newSegmentIndex);
                                        insidegeo = ConstructPolygonFromPolyline((line as IPolyline));
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    final.AddSegmentCollection(insidegeo as ISegmentCollection);
                }
                geometry = final as IPolygon;
                #region 判断当前图斑是否压盖多个图斑且存在碎图斑
                foreach (IGeometry geometry1 in ReferenceLayer)
                {
                    #region 相交部分
                    var geo = FeatureAPI.InterSect(geometry, geometry1);
                    List geometries = FeatureAPI.DissolveGeometryByRing(geo);
                    if (geometries != null && geometries.Count > 0)
                    {
                        foreach (var item in geometries)
                        {
                            ITopologicalOperator topoOpr = item as ITopologicalOperator;
                            topoOpr.Simplify();
                            var mj = item.GetEllipseArea();
                            if (mj < 1 && !item.IsEmpty)
                                geometry = FeatureAPI.Difference(geometry, item);
                        }
                    }
                    else
                    {
                        continue;
                    }
                    #endregion
                    #region 不相交部分
                    geo = FeatureAPI.Difference(geometry1, geometry);
                    geometries = FeatureAPI.DissolveGeometryByRing(geo);
                    if (geometries != null && geometries.Count > 0)
                    {
                        foreach (var item in geometries)
                        {
                            ITopologicalOperator topoOpr = item as ITopologicalOperator;
                            topoOpr.Simplify();
                            var mj = item.GetEllipseArea();
                            if (mj < 1 && !item.IsEmpty)
                            {
                                geometry = FeatureAPI.Union(geometry, item);
                            }
                        }
                    }
                    #endregion
                }
                #endregion
            }
            catch (Exception ex)
            {
                LogAPI.Debug("执行ExecuteRepair异常:" + ex.Message + ex.StackTrace);
                return geometry;
            }
            return geometry;
        }
        public static List ExecuteBoundaryRepair3(IGeometry OriginalGeo, List ReferenceLayer, List jcdltb_features, double distance)
        {
            List ResultgeometryList = new List();
            List geometryList = null;
            try
            {
                geometryList = FeatureAPI.DissolveGeometryByRing(OriginalGeo);//拆分多部件
                foreach (IGeometry Splitgeo in geometryList)
                {
                    IGeometry geometry = Splitgeo;
                    if (geometry == null || geometry.IsEmpty || geometry.GetEllipseArea() == 0) continue;
                    IGeometry repaird = NodeRepair(geometry, ReferenceLayer, distance);
                    if (repaird != null && !repaird.IsEmpty)
                    {
                        geometry = repaird;
                        geometry.SpatialReference = OriginalGeo.SpatialReference;
                    }
                    ITopologicalOperator geotopoOpr1 = geometry as ITopologicalOperator;
                    geotopoOpr1.Simplify();
                    if (geometry == null || geometry.IsEmpty) continue;
                    #region 节点修复完成后,删除多部件中面积小于1的
                    var multi = FeatureAPI.DissolveGeometryByRing(geometry);//拆分多部件
                    if (multi != null && multi.Count > 1)
                    {
                        foreach (IGeometry geo in multi)
                        {
                            var mj = geo.GetEllipseArea();
                            if (mj < 1)
                            {
                                geometry = FeatureAPI.Difference(geometry, geo);
                            }
                        }
                    }
                    else if (multi == null)
                        continue;
                    #endregion
                    #region 检查图形是否存在尖锐角/狭长图形等问题
                    List pointList = null;
                    double angle = 0;
                    if (AECommonHelper.SharpAngleDataCheck(geometry, ref pointList, ref angle))
                    {
                        if (pointList != null && angle < 10)
                        {
                            if (ReferenceLayer.Count == 1)
                            {
                                geometry = ResolveAcuteAngle(geometry, pointList, angle, ReferenceLayer[0], true);
                            }
                            else
                            {
                                geometry = ResolveAcuteAngle(geometry, pointList, angle);
                            }
                        }
                    }
                    #endregion
                    #region 判断当前图斑是否压盖多个图斑且存在碎图斑
                    foreach (IGeometry jcgeometry in jcdltb_features)
                    {
                        #region 相交部分
                        var geo = FeatureAPI.InterSect(geometry, jcgeometry);
                        List geometries = FeatureAPI.DissolveGeometryByRing(geo);
                        if (geometries != null && geometries.Count > 0)
                        {
                            foreach (var item in geometries)
                            {
                                ITopologicalOperator topoOpr = item as ITopologicalOperator;
                                topoOpr.Simplify();
                                var mj = item.GetEllipseArea();
                                if (mj < 1 && !item.IsEmpty)
                                    geometry = FeatureAPI.Difference(geometry, item);
                            }
                        }
                        else
                        {
                            continue;
                        }
                        #endregion
                        #region 不相交部分
                        geo = FeatureAPI.Difference(jcgeometry, geometry);
                        geometries = FeatureAPI.DissolveGeometryByRing(geo);
                        if (geometries != null && geometries.Count > 0)
                        {
                            foreach (var item in geometries)
                            {
                                ITopologicalOperator topoOpr = item as ITopologicalOperator;
                                topoOpr.Simplify();
                                List pointList1 = null;
                                double angle1 = 0;
                                var mj = item.GetEllipseArea();
                                //与基础库不想交的部分面积小于30平且相邻的情况下 合并
                                if (mj < 30 && !item.IsEmpty && FeatureAPI.IsAdjacent(geometry, item))
                                {
                                    geometry = FeatureAPI.Union(geometry, item);
                                    continue;
                                }
                                else
                                {
                                    if (AECommonHelper.SharpAngleDataCheck(item, ref pointList1, ref angle1))
                                    {
                                        if (angle1 > 10)//狭长图形
                                        {
                                            continue;
                                        }
                                        else
                                        {
                                            var completedgeo = SharpAngleMerge(item, pointList1);
                                            if (FeatureAPI.IsAdjacent(geometry, completedgeo))
                                            {
                                                if (completedgeo.GetEllipseArea() > 30)
                                                {
                                                }
                                                var uniongeo = FeatureAPI.Union(geometry, completedgeo);
                                                if (AECommonHelper.SharpAngleDataCheck(uniongeo, ref pointList, ref angle))
                                                {
                                                    geometry = ResolveAcuteAngle(uniongeo, pointList, angle, item, true);
                                                }
                                            }
                                            else
                                            {
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        #endregion
                    }
                    #endregion
                    #region 检查图形是否存在尖锐角/狭长图形等问题
                    if (AECommonHelper.SharpAngleDataCheck(geometry, ref pointList, ref angle))
                    {
                        geometry = BoundaryRepairHelper.ResolveAcuteAngle(geometry, pointList, angle);
                    }
                    #endregion
                    var Dissolve = FeatureAPI.DissolveGeometryByRing(geometry);//拆分多部件
                    if (Dissolve != null && Dissolve.Count > 1)
                    {
                        foreach (var item in Dissolve)
                        {
                            ResultgeometryList.Add(item);
                        }
                    }
                    else
                    {
                        ResultgeometryList.Add(geometry);
                    }
                }
            }
            catch (Exception ex)
            {
                ResultgeometryList = geometryList;
                LogAPI.Debug("执行ExecuteRepair异常:" + ex.Message + ex.StackTrace);
                return ResultgeometryList;
            }
            return ResultgeometryList;
        }
        private static IGeometry NodeRepair(IGeometry OriginalGeo, List ReferenceLayer, double distance)
        {
            IGeometry geometry = OriginalGeo;
            try
            {
                List repairpoints = LayerHelper.GetMultipleRingPoints(geometry);
                var count = 0;
                List listmoveToPoint = new List();
                foreach (var point in repairpoints)
                {
                    count++;
                    var xx = point.X;
                    var yy = point.Y;
                    IPoint PrevPoint = null;
                    IPoint NextPoint = null;
                    var pointangle = GetRelativeAngle(geometry, point, ref PrevPoint, ref NextPoint);
                    var UpdatePoint = GetSnappingpoint2(point, ReferenceLayer, listmoveToPoint, distance);
                    if (UpdatePoint.Count == 0) continue;
                    var Listpoint = UpdatePoint.OrderByDescending(x => x.ConcurrentCount).ToList();
                    IPoint moveToPoint = null;
                    if (Listpoint.Count > 0)
                    {
                        bool isContains = true;
                        foreach (var item in Listpoint)
                        {
                            if (!listmoveToPoint.Contains($"{item.Point.X},{item.Point.Y}"))
                            {
                                bool isbreak = false;
                                foreach (var iPoint in listmoveToPoint)
                                {
                                    var x = iPoint.Split(',')[0].ToDouble();
                                    var y = iPoint.Split(',')[1].ToDouble();
                                    //两个距离相近的点修复到同一个位置时,删除当前图形中的一个点
                                    var refdistance = Math.Sqrt((item.Point.X - x) * (item.Point.X - x) + (item.Point.Y - y) * (item.Point.Y - y));
                                    if (refdistance == 0 || Math.Abs(refdistance) < (1e-3))
                                    {
                                        isbreak = true;
                                        break;
                                    }
                                }
                                if (isbreak) break;
                                isContains = false; break;
                            }
                        }
                        if (isContains)
                        {
                            IPointCollection points = geometry as IPointCollection;
                            var index = -1;
                            for (int i = 0; i < points.PointCount - 1; i++)
                            {
                                IPoint tPoint = points.Point[i];
                                var refdistance = Math.Sqrt((point.X - tPoint.X) * (point.X - tPoint.X) + (point.Y - tPoint.Y) * (point.Y - tPoint.Y));
                                if (refdistance == 0 || Math.Abs(refdistance) < (1e-5))
                                {
                                    index = i; break;
                                }
                            }
                            if (index > -1)
                            {
                                points.RemovePoints(index, 1);
                                continue;
                            }
                        }
                        if (Listpoint.Count > 1)
                        {
                            if (Listpoint.FirstOrDefault(x => x.FootPoint == false) != null)
                            {
                                for (int i = 0; i < Listpoint.Count; i++)
                                {
                                    if (Listpoint[i].FootPoint == true)
                                    {
                                        Listpoint.RemoveAt(i);
                                        i = 0; continue;
                                    }
                                }
                            }
                            //多个相近的参考点在不同的参考图形上,根据距离最近的取参考点
                            if (ReferenceLayer.Count > 1)
                            {
                                double mindistance = -1;
                                var index = -1;
                                for (int i = 0; i < Listpoint.Count; i++)
                                {
                                    double refdistance = Math.Sqrt((point.X - Listpoint[i].Point.X) * (point.X - Listpoint[i].Point.X) + (point.Y - Listpoint[i].Point.Y) * (point.Y - Listpoint[i].Point.Y));
                                    if (mindistance == -1)
                                    {
                                        mindistance = refdistance;
                                        index = i;
                                    }
                                    else if (refdistance < mindistance)
                                    {
                                        mindistance = refdistance;
                                        index = i;
                                    }
                                }
                                if (index != -1)
                                {
                                    moveToPoint = Listpoint[index].Point;
                                    Listpoint.RemoveAt(index);
                                }
                            }
                            else
                            {
                                #region 出现多个相近的点
                                var nearUpdatePoint = Listpoint.OrderBy(n => Math.Abs(n.angle - pointangle)).FirstOrDefault();
                                moveToPoint = nearUpdatePoint.Point;
                                #endregion
                            }
                        }
                        else if (Listpoint.Count == 1)
                        {
                            //if (Listpoint[0].FootPoint)
                            //{
                            //    IPolyline polyline = new PolylineClass();
                            //    try
                            //    {
                            //        double refdistance = Math.Sqrt((point.X - Listpoint[0].Point.X) * (point.X - Listpoint[0].Point.X) + (point.Y - Listpoint[0].Point.Y) * (point.Y - Listpoint[0].Point.Y));
                            //        if (Math.Abs(refdistance) < (1e-5))
                            //        {
                            //            continue;
                            //        }
                            //        polyline.SpatialReference = geometry.SpatialReference;
                            //        polyline.FromPoint = point;
                            //        polyline.ToPoint = Listpoint[0].Point;
                            //        polyline = getExtendLine(polyline, 2, 1);
                            //        if (FeatureAPI.IsInterSect(geometry, polyline))
                            //        {
                            //            //List Cutgeometries = FeatureAPI.CutGeometry(geometry, polyline);
                            //            //if (Cutgeometries != null && Cutgeometries.Count > 1)
                            //            //{
                            //            //    bool isbreak = false;
                            //            //    foreach (var item in Cutgeometries)
                            //            //    {
                            //            //        if (item.IsEmpty || item.GetEllipseArea() == 0)
                            //            //        {
                            //            //            isbreak = true; break;
                            //            //        }
                            //            //    }
                            //            //    if (!isbreak)
                            //            //        continue;
                            //            //}
                            //        }
                            //    }
                            //    catch (Exception ex) { }
                            //    finally
                            //    {
                            //        if (polyline != null)
                            //            Marshal.ReleaseComObject(polyline);
                            //    }
                            //}
                            moveToPoint = Listpoint[0].Point;
                            Listpoint.RemoveAt(0);
                        }
                    }
                    if (moveToPoint != null)
                    {
                        IPointCollection points = geometry as IPointCollection;
                        var index = -1;
                        for (int i = 0; i < points.PointCount - 1; i++)
                        {
                            IPoint tPoint = points.Point[i];
                            var refdistance = Math.Sqrt((point.X - tPoint.X) * (point.X - tPoint.X) + (point.Y - tPoint.Y) * (point.Y - tPoint.Y));
                            if (refdistance == 0 || Math.Abs(refdistance) < (1e-5))
                            {
                                index = i; break;
                            }
                        }
                        if (index > -1)
                        {
                            var refdistance = Math.Sqrt((point.X - moveToPoint.X) * (point.X - moveToPoint.X) + (point.Y - moveToPoint.Y) * (point.Y - moveToPoint.Y));
                            if (refdistance == 0) continue;
                            points.UpdatePoint(index, moveToPoint);
                            listmoveToPoint.Add($"{moveToPoint.X},{moveToPoint.Y}");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                return null;
            }
            return geometry;
        }
        /// 
        /// 延长线段
        /// 
        /// 传入去的线
        /// 模式,1为从FromPoint处延长,2为从ToPint处延长,3为两端延长
        /// 延长的距离
        /// 
        /// 创建人:懒羊羊
        public static IPolyline getExtendLine(IPolyline passLine, int mode, double dis)
        {
            IPointCollection pPointCol = passLine as IPointCollection;
            switch (mode)
            {
                case 1:
                    IPoint fromPoint = new PointClass();
                    passLine.QueryPoint(esriSegmentExtension.esriExtendAtFrom, -1 * dis, false, fromPoint);
                    pPointCol.InsertPoints(0, 1, ref fromPoint);
                    break;
                case 2:
                    IPoint endPoint = new PointClass();
                    object missing = Type.Missing;
                    passLine.QueryPoint(esriSegmentExtension.esriExtendAtTo, dis + passLine.Length, false, endPoint);
                    pPointCol.AddPoint(endPoint, ref missing, ref missing);
                    break;
                case 3:
                    IPoint fPoint = new PointClass();
                    IPoint ePoint = new PointClass();
                    object missing2 = Type.Missing;
                    passLine.QueryPoint(esriSegmentExtension.esriExtendAtFrom, -1 * dis, false, fPoint);
                    pPointCol.InsertPoints(0, 1, ref fPoint);
                    passLine.QueryPoint(esriSegmentExtension.esriExtendAtTo, dis + passLine.Length, false, ePoint);
                    pPointCol.AddPoint(ePoint, ref missing2, ref missing2);
                    break;
                default:
                    return pPointCol as IPolyline;
            }
            return pPointCol as IPolyline;
        }
        /// 
        /// 捕捉
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        private static List Snapping(IPoint point, IFeatureLayer m_featureLayer, double distance)
        {
            double tol = 0.1;
            ITopologicalOperator pTopo = point as ITopologicalOperator;
            IGeometry pGeometry = pTopo.Buffer(tol).Envelope as IGeometry;
            IIdentify indentify = m_featureLayer as IIdentify;
            if (indentify == null)
                return null;
            IArray pIDs = indentify.Identify(pGeometry);
            if (pIDs == null || pIDs.Count == 0)
                return null;
            List pointList = new List();
            for (int index = 0; index < pIDs.Count; index++)
            {
                IFeatureIdentifyObj pFeatIdObj = pIDs.get_Element(index) as IFeatureIdentifyObj;
                IRowIdentifyObject pRowObj = pFeatIdObj as IRowIdentifyObject;
                IFeature iF = pRowObj.Row as IFeature;
                IPoint iHitPt = new ESRI.ArcGIS.Geometry.Point();
                IHitTest iHitTest = iF.Shape as IHitTest;
                double hitDist = 0;
                int partIndex = 0;
                int vertexIndex = 0;
                bool bRightSide = false;
                if (iHitTest.HitTest(point, tol, esriGeometryHitPartType.esriGeometryPartVertex,
                    iHitPt, ref hitDist, ref partIndex, ref vertexIndex, ref bRightSide))
                {
                    //var distance1 = Math.Sqrt((point.X - iHitPt.X) * (point.X - iHitPt.X) + (point.Y - iHitPt.Y) * (point.Y - iHitPt.Y));
                    //if (distance1 == 0) continue;
                    point = iHitPt;
                    pointList.Add(new MovePointStruct()
                    {
                        Feature = iF,
                        Geometry = iF.Shape,
                        PartIndex = partIndex,
                        VertexIndex = vertexIndex
                    });
                }
            }
            //this.m_hookHelper.ActiveView.Refresh();
            return pointList;
        }
        private static List Snapping2(IPoint point, List m_featureLayer, double distance)
        {
            double tol = 0.1;
            ITopologicalOperator pTopo = point as ITopologicalOperator;
            IGeometry pGeometry = pTopo.Buffer(tol).Envelope as IGeometry;
            IIdentify indentify = m_featureLayer as IIdentify;
            if (indentify == null)
                return null;
            IArray pIDs = indentify.Identify(pGeometry);
            if (pIDs == null || pIDs.Count == 0)
                return null;
            List pointList = new List();
            foreach (IGeometry geometry in m_featureLayer)
            {
                IPoint iHitPt = new ESRI.ArcGIS.Geometry.Point();
                IHitTest iHitTest = geometry as IHitTest;
                double hitDist = 0;
                int partIndex = 0;
                int vertexIndex = 0;
                bool bRightSide = false;
                if (iHitTest.HitTest(point, tol, esriGeometryHitPartType.esriGeometryPartVertex,
                    iHitPt, ref hitDist, ref partIndex, ref vertexIndex, ref bRightSide))
                {
                    point = iHitPt;
                    pointList.Add(new MovePointStruct()
                    {
                        Geometry = geometry,
                        PartIndex = partIndex,
                        VertexIndex = vertexIndex
                    });
                }
            }
            return pointList;
        }
        private static Dictionary GetSnappingpoint(IPoint point, IFeatureLayer m_featureLayer, double distance = 1)
        {
            Dictionary pointList = new Dictionary();
            try
            {
                ITopologicalOperator pTopo = point as ITopologicalOperator;
                IGeometry pGeometry = pTopo.Buffer(distance).Envelope as IGeometry;
                IIdentify indentify = m_featureLayer as IIdentify;
                if (indentify == null)
                    return pointList;
                IArray pIDs = indentify.Identify(pGeometry);
                if (pIDs == null || pIDs.Count == 0)
                    return pointList;
                for (int index = 0; index < pIDs.Count; index++)
                {
                    IFeatureIdentifyObj pFeatIdObj = pIDs.get_Element(index) as IFeatureIdentifyObj;
                    IRowIdentifyObject pRowObj = pFeatIdObj as IRowIdentifyObject;
                    IFeature iF = pRowObj.Row as IFeature;
                    IPoint iHitPt = new Point();
                    IHitTest iHitTest = iF.Shape as IHitTest;
                    double hitDist = 0;
                    int partIndex = 0;
                    int vertexIndex = 0;
                    bool bRightSide = false;
                    if (iHitTest.HitTest(point, distance, esriGeometryHitPartType.esriGeometryPartVertex,
                        iHitPt, ref hitDist, ref partIndex, ref vertexIndex, ref bRightSide))
                    {
                        //point = iHitPt;
                        IPolyline tempLine = new PolylineClass();
                        tempLine.FromPoint = iHitPt;
                        bool isExit = false;
                        foreach (var tempPoint in pointList.Keys)
                        {
                            tempLine.ToPoint = tempPoint;
                            if (tempLine.Length < 0.00005) isExit = true;
                        }
                        if (!isExit)
                        {
                            IArray pTempIDs = indentify.Identify(iHitPt);
                            int num = 0;
                            for (int i = 0; i < pTempIDs.Count; i++)
                            {
                                pFeatIdObj = pTempIDs.get_Element(i) as IFeatureIdentifyObj;
                                pRowObj = pFeatIdObj as IRowIdentifyObject;
                                iHitTest = ((pRowObj.Row as IFeature).Shape) as IHitTest;
                                IPoint iHitPt1 = new ESRI.ArcGIS.Geometry.Point();
                                if (iHitTest.HitTest(iHitPt, 0.0001, esriGeometryHitPartType.esriGeometryPartVertex,
                            iHitPt1, ref hitDist, ref partIndex, ref vertexIndex, ref bRightSide))
                                {
                                    if (hitDist == 0)
                                        num++;
                                }
                            }
                            if (iHitPt.X == point.X && point.Y == iHitPt.Y)
                                continue;
                            pointList.Add(iHitPt, num);
                        }
                    }
                    else if (iHitTest.HitTest(point, distance, esriGeometryHitPartType.esriGeometryPartBoundary, iHitPt, ref hitDist, ref partIndex, ref vertexIndex, ref bRightSide))
                    {
                        //取距离boundary最近的点
                        IGeometryCollection collection = iF.ShapeCopy as IGeometryCollection;
                        IGeometry geo = collection.get_Geometry(partIndex);
                        ISegmentCollection points = geo as ISegmentCollection;
                        ISegment pt = points.Segment[vertexIndex];
                        IPoint point1 = new PointClass();
                        var DistanceAlongCurve = 0.0001;
                        var distanceFromCurve = 0.0001;
                        bRightSide = true;
                        pt.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, point, false, point1, ref DistanceAlongCurve, ref distanceFromCurve, bRightSide);
                        IPolyline tempLine = new PolylineClass();
                        tempLine.FromPoint = iHitPt;
                        bool isExit = false;
                        foreach (var tempPoint in pointList.Keys)
                        {
                            tempLine.ToPoint = tempPoint;
                            if (tempLine.Length < 0.00005) isExit = true;
                        }
                        if (!isExit)
                        {
                            pointList.Add(point1, 1);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogAPI.Debug($"GetSnappingpoint异常:{ex.Message + ex.StackTrace}");
            }
            return pointList;
        }
        private static List GetSnappingpoint1(IPoint point, IFeatureLayer m_featureLayer, double distance = 1)
        {
            List pointList = new List();
            try
            {
                ITopologicalOperator pTopo = point as ITopologicalOperator;
                IGeometry pGeometry = pTopo.Buffer(distance).Envelope as IGeometry;
                IIdentify indentify = m_featureLayer as IIdentify;
                if (indentify == null)
                    return pointList;
                IArray pIDs = indentify.Identify(pGeometry);
                if (pIDs == null || pIDs.Count == 0)
                    return pointList;
                for (int index = 0; index < pIDs.Count; index++)
                {
                    List listoid = new List();
                    IFeatureIdentifyObj pFeatIdObj = pIDs.get_Element(index) as IFeatureIdentifyObj;
                    IRowIdentifyObject pRowObj = pFeatIdObj as IRowIdentifyObject;
                    IFeature iF = pRowObj.Row as IFeature;
                    IPoint iHitPt = new Point();
                    IHitTest iHitTest = iF.Shape as IHitTest;
                    double hitDist = 0;
                    int partIndex = 0;
                    int vertexIndex = 0;
                    bool bRightSide = false;
                    if (iHitTest.HitTest(point, distance, esriGeometryHitPartType.esriGeometryPartVertex,
                        iHitPt, ref hitDist, ref partIndex, ref vertexIndex, ref bRightSide))
                    {
                        //point = iHitPt;
                        IPolyline tempLine = new PolylineClass();
                        tempLine.FromPoint = iHitPt;
                        bool isExit = false;
                        foreach (var tempPoint in pointList)
                        {
                            tempLine.ToPoint = tempPoint.Point;
                            if (tempLine.Length < 0.00005)
                            {
                                listoid.Add(iF.OID);
                                isExit = true;
                            }
                        }
                        if (!isExit)
                        {
                            IArray pTempIDs = indentify.Identify(iHitPt);
                            int num = 0;
                            for (int i = 0; i < pTempIDs.Count; i++)
                            {
                                pFeatIdObj = pTempIDs.get_Element(i) as IFeatureIdentifyObj;
                                pRowObj = pFeatIdObj as IRowIdentifyObject;
                                IFeature iF1 = pRowObj.Row as IFeature;
                                iHitTest = ((pRowObj.Row as IFeature).Shape) as IHitTest;
                                IPoint iHitPt1 = new ESRI.ArcGIS.Geometry.Point();
                                if (iHitTest.HitTest(iHitPt, 0.0001, esriGeometryHitPartType.esriGeometryPartVertex,
                            iHitPt1, ref hitDist, ref partIndex, ref vertexIndex, ref bRightSide))
                                {
                                    if (hitDist == 0)
                                    {
                                        listoid.Add(iF1.OID);
                                        num++;
                                    }
                                }
                            }
                            if (iHitPt.X == point.X && point.Y == iHitPt.Y)
                                continue;
                            pointList.Add(new ConcurrentClass() { Point = iHitPt, ConcurrentCount = num, ListObjectID = listoid });
                        }
                    }
                    else if (iHitTest.HitTest(point, distance, esriGeometryHitPartType.esriGeometryPartBoundary, iHitPt, ref hitDist, ref partIndex, ref vertexIndex, ref bRightSide))
                    {
                        //取距离boundary最近的点
                        IGeometryCollection collection = iF.ShapeCopy as IGeometryCollection;
                        IGeometry geo = collection.get_Geometry(partIndex);
                        ISegmentCollection points = geo as ISegmentCollection;
                        ISegment pt = points.Segment[vertexIndex];
                        IPoint point1 = new PointClass();
                        var DistanceAlongCurve = 0.0001;
                        var distanceFromCurve = 0.0001;
                        bRightSide = true;
                        pt.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, point, false, point1, ref DistanceAlongCurve, ref distanceFromCurve, bRightSide);
                        IPolyline tempLine = new PolylineClass();
                        tempLine.FromPoint = iHitPt;
                        bool isExit = false;
                        foreach (var tempPoint in pointList)
                        {
                            tempLine.ToPoint = tempPoint.Point;
                            if (tempLine.Length < 0.00005) isExit = true;
                        }
                        if (!isExit)
                        {
                            listoid.Add(iF.OID);
                            pointList.Add(new ConcurrentClass() { Point = point1, ConcurrentCount = 1, ListObjectID = listoid });
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogAPI.Debug($"GetSnappingpoint异常:{ex.Message + ex.StackTrace}");
            }
            return pointList;
        }
        private static List GetSnappingpoint2(IPoint point, List m_featureLayer, List listmoveToPoint = null, double distance = 1)
        {
            List pointList = new List();
            try
            {
                foreach (IGeometry geometry in m_featureLayer)
                {
                    IPoint iHitPt = new Point();
                    IHitTest iHitTest = geometry as IHitTest;
                    double hitDist = 0;
                    int partIndex = 0;
                    int vertexIndex = 0;
                    bool bRightSide = false;
                    if (iHitTest.HitTest(point, distance, esriGeometryHitPartType.esriGeometryPartVertex, iHitPt, ref hitDist, ref partIndex, ref vertexIndex, ref bRightSide))
                    {
                        IPolyline tempLine = new PolylineClass();
                        tempLine.FromPoint = iHitPt;
                        bool isExit = false;
                        foreach (var tempPoint in pointList)
                        {
                            tempLine.ToPoint = tempPoint.Point;
                            if (tempLine.Length < 0.00005)
                            {
                                isExit = true;
                            }
                        }
                        if (!isExit)
                        {
                            int num = 0;
                            foreach (IGeometry item in m_featureLayer)
                            {
                                iHitTest = item as IHitTest;
                                IPoint iHitPt1 = new ESRI.ArcGIS.Geometry.Point();
                                if (iHitTest.HitTest(iHitPt, 0.0001, esriGeometryHitPartType.esriGeometryPartVertex, iHitPt1, ref hitDist, ref partIndex, ref vertexIndex, ref bRightSide))
                                {
                                    if (hitDist == 0)
                                        num++;
                                }
                            }
                            if (iHitPt.X == point.X && point.Y == iHitPt.Y)
                                continue;
                            IPoint PrevPoint = null;
                            IPoint NextPoint = null;
                            pointList.Add(new ConcurrentClass() { Point = iHitPt, ConcurrentCount = num, FootPoint = false, angle = GetRelativeAngle(geometry, iHitPt, ref PrevPoint, ref NextPoint) });
                            if (listmoveToPoint.Contains($"{iHitPt.X}{iHitPt.Y}"))
                            {
                                IPoint PrevPoint1 = null;
                                IPoint NextPoint1 = null;
                                var pointdistance = Math.Sqrt((point.X - PrevPoint.X) * (point.X - PrevPoint.X) + (point.Y - PrevPoint.Y) * (point.Y - PrevPoint.Y));
                                if (pointdistance < 1)
                                    pointList.Add(new ConcurrentClass() { Point = PrevPoint, ConcurrentCount = num, FootPoint = false, angle = GetRelativeAngle(geometry, PrevPoint, ref PrevPoint1, ref NextPoint1) });
                                pointdistance = Math.Sqrt((point.X - NextPoint.X) * (point.X - NextPoint.X) + (point.Y - NextPoint.Y) * (point.Y - NextPoint.Y));
                                if (pointdistance < 1)
                                    pointList.Add(new ConcurrentClass() { Point = NextPoint, ConcurrentCount = num, FootPoint = false, angle = GetRelativeAngle(geometry, NextPoint, ref PrevPoint1, ref NextPoint1) });
                            }
                        }
                    }
                    else if (iHitTest.HitTest(point, distance, esriGeometryHitPartType.esriGeometryPartBoundary, iHitPt, ref hitDist, ref partIndex, ref vertexIndex, ref bRightSide))
                    {
                        //取距离boundary最近的点
                        IGeometryCollection collection = geometry as IGeometryCollection;
                        IGeometry geo = collection.get_Geometry(partIndex);
                        ISegmentCollection points = geo as ISegmentCollection;
                        ISegment pt = points.Segment[vertexIndex];
                        IPoint point1 = new PointClass();
                        var DistanceAlongCurve = 0.0001;
                        var distanceFromCurve = 0.0001;
                        bRightSide = true;
                        pt.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, point, false, point1, ref DistanceAlongCurve, ref distanceFromCurve, bRightSide);
                        IPolyline tempLine = new PolylineClass();
                        tempLine.FromPoint = iHitPt;
                        bool isExit = false;
                        foreach (var tempPoint in pointList)
                        {
                            tempLine.ToPoint = tempPoint.Point;
                            if (tempLine.Length < 0.00005) isExit = true;
                        }
                        if (!isExit)
                        {
                            pointList.Add(new ConcurrentClass() { Point = point1, ConcurrentCount = 1, FootPoint = true });
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogAPI.Debug($"GetSnappingpoint异常:{ex.Message + ex.StackTrace}");
            }
            return pointList;
        }
        /// 
        /// 线转面
        /// 
        /// 线对象
        /// IGeometry 面对象
        public static IGeometry ConstructPolygonFromPolyline(IPolyline pPolyline)
        {
            IGeometry newGeometry = null;
            try
            {
                IGeometryCollection pPolygonGeoCol = new PolygonClass();
                if (pPolyline == null || pPolyline.IsEmpty)
                {
                    return pPolygonGeoCol as IGeometry;
                }
                IGeometryCollection pPolylineGeoCol = pPolyline as IGeometryCollection;
                ISegmentCollection pSegCol = new RingClass();
                ISegment pSegment = null;
                object missing = Type.Missing;
                for (int i = 0; i < pPolylineGeoCol.GeometryCount; i++)
                {
                    ISegmentCollection pPolylineSegCol = pPolylineGeoCol.get_Geometry(i) as ISegmentCollection;
                    for (int j = 0; j < pPolylineSegCol.SegmentCount; j++)
                    {
                        pSegment = pPolylineSegCol.get_Segment(j);
                        pSegCol.AddSegment(pSegment, ref missing, ref missing);
                    }
                    pPolygonGeoCol.AddGeometry(pSegCol as IGeometry, ref missing, ref missing);
                }
                newGeometry = pPolygonGeoCol as IGeometry;
                if (newGeometry != null && !newGeometry.IsEmpty)
                {
                    ITopologicalOperator topologicalOperator = newGeometry as ITopologicalOperator;
                    if (!topologicalOperator.IsKnownSimple)
                    {
                        topologicalOperator.Simplify();
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return newGeometry;
        }
        private static IGeometry PolygonToPolyline(IGeometry pGeo)
        {
            try
            {
                if (pGeo == null)
                {
                    return null;
                }
                if (!(pGeo is Ring ring))
                {
                    return null;
                }
                IPointCollection pointCollection = ring;
                IGeometryCollection geometryCollection = new PolylineClass();
                for (int i = 1; i < pointCollection.PointCount; i++)
                {
                    LineClass lineClass = new LineClass();
                    ((ILine)lineClass).SpatialReference = pGeo.SpatialReference;
                    ((ILine)lineClass).PutCoords(pointCollection.get_Point(i - 1), pointCollection.get_Point(i));
                    ISegment inSegment = lineClass as ISegment;
                    ISegmentCollection segmentCollection = new PathClass();
                    object before = Type.Missing;
                    segmentCollection.AddSegment(inSegment, ref before, ref before);
                    geometryCollection.AddGeometry(segmentCollection as IGeometry, ref before, ref before);
                }
                return geometryCollection as IGeometry;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #region 尖锐角处理
        /// 
        /// 尖锐角处理
        /// 
        /// 
        /// 
        /// 
        /// 
        public static IGeometry ResolveAcuteAngle(IGeometry geometry, List pointList, double angle, IGeometry Repairgeometry = null, bool isjcdltb = false)
        {
            try
            {
                if (pointList != null && angle > 0 && pointList.Count > 0)
                {
                    IPolyline polyline1 = new PolylineClass();
                    IPolyline polyline1_vertical = null;
                    IPolyline polyline2_vertical = null;
                    IPolyline polyline2 = new PolylineClass();
                    if (pointList.Count == 3)
                    {
                        polyline1.SpatialReference = pointList[0].SpatialReference;
                        polyline1.FromPoint = pointList[1];
                        polyline1.ToPoint = pointList[0];
                        polyline1_vertical = GetPerpendicularLine(polyline1, true);//垂线
                        polyline2.SpatialReference = pointList[0].SpatialReference;
                        polyline2.FromPoint = pointList[1];
                        polyline2.ToPoint = pointList[0];
                        polyline2_vertical = GetPerpendicularLine(polyline2, false);
                    }
                    #region 计算点位置
                    IPoint length1Point = new PointClass();
                    if (polyline1_vertical != null)
                        length1Point = polyline1_vertical.ToPoint;
                    IPoint length2Point = new PointClass();
                    if (polyline2_vertical != null)
                        length2Point = polyline2_vertical.ToPoint;
                    #endregion
                    IPointCollection pointCollection1 = new MultipointClass();
                    pointCollection1.AddPoint(length1Point);
                    pointCollection1.AddPoint(pointList[1]);
                    pointCollection1.AddPoint(pointList[0]);
                    IGeometry geometry1 = GenerateGeometryFromPoints(pointCollection1);
                    geometry1.SpatialReference = geometry.SpatialReference;
                    IPointCollection pointCollection2 = new MultipointClass();
                    pointCollection2.AddPoint(length2Point);
                    pointCollection2.AddPoint(pointList[1]);
                    pointCollection2.AddPoint(pointList[0]);
                    IGeometry geometry2 = GenerateGeometryFromPoints(pointCollection2);
                    geometry2.SpatialReference = geometry.SpatialReference;
                    if (Repairgeometry != null)
                    {
                        Repairgeometry.SpatialReference = geometry.SpatialReference;
                        if (isjcdltb)
                        {
                            if (FeatureAPI.IsContains(Repairgeometry, geometry1))
                            {
                            }
                            else
                            {
                                geometry1 = geometry2;
                            }
                        }
                        else
                        {
                            IGeometry InterSect = FeatureAPI.InterSect(Repairgeometry, geometry1);
                            if (InterSect != null && InterSect.GetEllipseArea() == 0)
                            {
                                geometry1 = geometry2;
                            }
                        }
                    }
                    if (FeatureAPI.IsContains(geometry, geometry1))
                    {
                        geometry = FeatureAPI.Difference(geometry, geometry1 as IPolygon);
                    }
                    else
                    {
                        geometry = FeatureAPI.Union(geometry, geometry1 as IPolygon);
                    }
                }
                pointList = null; angle = 0;
                if (AECommonHelper.SharpAngleDataCheck(geometry, ref pointList, ref angle))
                {
                    if (angle < 10)
                        geometry = ResolveAcuteAngle(geometry, pointList, angle, Repairgeometry);
                }
                else
                {
                    return geometry;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return geometry;
        }
        /// 
        /// 解决狭长图形问题
        /// 
        /// 
        /// 
        public static IGeometry ResolveLongAndNarrow(IGeometry geometry)
        {
            List pointList = null;
            double angle = 0;
            try
            {
                ///向内缓冲,如果还存在狭长的图形,暂不做处理
                ITopologicalOperator topo = geometry as ITopologicalOperator;
                IGeometry geo = topo.Buffer(-0.05);
                if (AECommonHelper.SharpAngleDataCheck(geo, ref pointList, ref angle))
                {
                }
                else
                {
                    geometry = geo;
                }
            }
            catch (Exception ex)
            {
                return geometry;
            }
            return geometry;
        }
        public static IGeometry SharpAngleMerge(IGeometry geometry, List points, IGeometry uniongeo = null)
        {
            List pointList = null;
            double angle = 0;
            try
            {
                if (geometry != null && !geometry.IsEmpty && points != null && points.Count == 3)
                {
                    IPointCollection pointCollection2 = new MultipointClass();
                    pointCollection2.AddPoint(points[0]);
                    pointCollection2.AddPoint(points[1]);
                    pointCollection2.AddPoint(points[2]);
                    IGeometry sharpgeo = GenerateGeometryFromPoints(pointCollection2);
                    sharpgeo.SpatialReference = geometry.SpatialReference;
                    var mj = sharpgeo.GetEllipseArea();
                    var geomj = geometry.GetEllipseArea();
                    if (!sharpgeo.IsEmpty && mj < geomj)
                    {
                        geometry = FeatureAPI.Difference(geometry, sharpgeo);
                        if (AECommonHelper.SharpAngleDataCheck(geometry, ref pointList, ref angle))
                        {
                            if (uniongeo == null)
                            {
                                uniongeo = sharpgeo;
                                uniongeo.SpatialReference = geometry.SpatialReference;
                            }
                            else
                            {
                                if (FeatureAPI.IsAdjacent(uniongeo, sharpgeo))
                                {
                                    uniongeo = FeatureAPI.Union(uniongeo, sharpgeo);
                                }
                                else
                                {
                                }
                            }
                            geometry = SharpAngleMerge(geometry, pointList, uniongeo);
                        }
                        else
                        {
                            if (uniongeo != null)
                            {
                                uniongeo = FeatureAPI.Union(uniongeo, sharpgeo);
                                geometry = uniongeo;
                            }
                            return sharpgeo;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                return geometry;
            }
            return geometry;
        }
        /// 
        /// 擦除图形本身存在的尖锐角
        /// 
        /// 
        /// 
        /// 
        /// 
        public static IGeometry SharpAngleErase(IGeometry geometry, List points, IGeometry Erasegeo = null)
        {
            List pointList = null;
            double angle = 0;
            try
            {
                if (geometry != null && !geometry.IsEmpty && points != null && points.Count == 3)
                {
                    IPointCollection pointCollection2 = new MultipointClass();
                    pointCollection2.AddPoint(points[0]);
                    pointCollection2.AddPoint(points[1]);
                    pointCollection2.AddPoint(points[2]);
                    IGeometry sharpgeo = GenerateGeometryFromPoints(pointCollection2);
                    sharpgeo.SpatialReference = geometry.SpatialReference;
                    var mj = sharpgeo.GetEllipseArea();
                    var geomj = geometry.GetEllipseArea();
                    if (!sharpgeo.IsEmpty && mj < geomj)
                    {
                        geometry = FeatureAPI.Difference(geometry, sharpgeo);
                        if (AECommonHelper.SharpAngleDataCheck(geometry, ref pointList, ref angle))
                        {
                            if (Erasegeo == null)
                            {
                                Erasegeo = sharpgeo;
                                Erasegeo.SpatialReference = geometry.SpatialReference;
                            }
                            else
                            {
                                if (FeatureAPI.IsAdjacent(Erasegeo, sharpgeo))
                                {
                                    Erasegeo = FeatureAPI.Union(Erasegeo, sharpgeo);
                                }
                                else
                                {
                                }
                            }
                            geometry = SharpAngleErase(geometry, pointList, Erasegeo);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                return geometry;
            }
            return geometry;
        }
        /// 
        /// 
        /// 
        /// 
        /// clockwise顺时针 true为顺时针/false为逆时针
        /// 
        public static IPolyline GetPerpendicularLine(IPolyline baseLine, bool clockwise)
        {
            // 获取baseLine的第一个点作为起点
            IPoint startPoint = baseLine.FromPoint;
            if (!startPoint.IsEmpty)
            {
                // 获取非起点的任一点
                IPoint endPoint = baseLine.ToPoint;
                // 计算向量
                double vectorX = endPoint.X - startPoint.X;
                double vectorY = endPoint.Y - startPoint.Y;
                // 旋转90度得到垂直向量
                double perpendicularX = 0;
                double perpendicularY = 0;
                if (clockwise)
                {
                    perpendicularX = -vectorY;
                    perpendicularY = vectorX;
                }
                else
                {
                    perpendicularX = vectorY;
                    perpendicularY = -vectorX;
                }
                // 设置垂直向量的长度,这里假设为1
                double length = 1;
                perpendicularX *= length / Math.Sqrt(perpendicularX * perpendicularX + perpendicularY * perpendicularY);
                perpendicularY *= length / Math.Sqrt(perpendicularX * perpendicularX + perpendicularY * perpendicularY);
                // 计算垂直线的终点
                IPoint perpendicularEndPoint = new PointClass();
                perpendicularEndPoint.X = startPoint.X + perpendicularX;
                perpendicularEndPoint.Y = startPoint.Y + perpendicularY;
                // 创建并返回垂直线
                IPolyline perpendicularLine = new PolylineClass();
                IPointCollection pointCollection = perpendicularLine as IPointCollection;
                pointCollection.AddPoint(startPoint);
                pointCollection.AddPoint(perpendicularEndPoint);
                return perpendicularLine;
            }
            return null;
        }
        /// 
        /// 根据点集合生成图形
        /// 
        /// 
        /// 
        public static IGeometry GenerateGeometryFromPoints(IPointCollection Points)
        {
            Ring ring = new RingClass();
            object missing = Type.Missing;
            ring.AddPointCollection(Points);
            IGeometryCollection pointPolygon = new PolygonClass();
            pointPolygon.AddGeometry(ring as IGeometry, ref missing, ref missing);
            IPolygon polyGonGeo = pointPolygon as IPolygon;
            //polyGonGeo.Close();
            polyGonGeo.SimplifyPreserveFromTo();
            return polyGonGeo as IGeometry;
        }
        #endregion
        #region GetRelativeAngle
        /// 
        /// 获取当前点与前后两个点之间的夹角的角度
        /// 
        /// 
        /// 
        /// 
        private static double GetRelativeAngle(IGeometry geometry, IPoint point, ref IPoint PrevPoint, ref IPoint NextPoint)
        {
            double angle = -1;
            try
            {
                IPointCollection pointCollection = geometry as IPointCollection;
                var index = -1;
                for (int i = 0; i < pointCollection.PointCount - 1; i++)
                {
                    if (Math.Abs(point.X - pointCollection.Point[i].X) < 0.0001 && Math.Abs(point.Y - pointCollection.Point[i].Y) < 0.0001)
                    {
                        index = i; break;
                    }
                }
                PrevPoint = new Point();
                if (index > 0)
                    pointCollection.QueryPoint(index - 1, PrevPoint);
                if (index == 0)
                    pointCollection.QueryPoint(pointCollection.PointCount - 2, PrevPoint);
                NextPoint = new Point();
                if (index < pointCollection.PointCount)
                    pointCollection.QueryPoint(index + 1, NextPoint);
                if (PrevPoint != null && !PrevPoint.IsEmpty)
                    angle = AECommonHelper.GetAngle(PrevPoint, point, NextPoint);
            }
            catch (Exception ex)
            {
                angle = -1;
            }
            return angle;
        }
        #endregion
    }
    public class MovePointStruct
    {
        public IFeature Feature { get; set; }
        public IGeometry Geometry { get; set; }
        public int PartIndex { get; set; }
        public int VertexIndex { get; set; }
    }
    public class ConcurrentClass
    {
        /// 
        /// 共点
        /// 
        public IPoint Point { get; set; }
        /// 
        /// 共点个数
        /// 
        public int ConcurrentCount { get; set; }
        /// 
        /// 所在图形
        /// 
        public List ListObjectID { get; set; }
        public bool FootPoint { get; set; }
        public double angle { get; set; }
    }
}