You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							1634 lines
						
					
					
						
							80 KiB
						
					
					
				
			
		
		
	
	
							1634 lines
						
					
					
						
							80 KiB
						
					
					
				using System; | 
						|
using System.Collections.Generic; | 
						|
using System.Linq; | 
						|
using DevExpress.Mvvm.Native; | 
						|
using ESRI.ArcGIS.esriSystem; | 
						|
using ESRI.ArcGIS.Geometry; | 
						|
using KGIS.Framework.AE; | 
						|
using KGIS.Framework.AE.ExtensionMethod; | 
						|
using KGIS.Framework.Utils.ExtensionMethod; | 
						|
using NetTopologySuite.IO; | 
						|
 | 
						|
namespace Kingo.PluginServiceInterface.Helper | 
						|
{ | 
						|
    /// <summary> | 
						|
    /// 边界修复 | 
						|
    /// </summary> | 
						|
    public static class BoundaryRepairHelperNew | 
						|
    { | 
						|
        private static List<string> XZDW_List = new List<string>() { "1001", "1002", "1003", "1004", "1006", "1009", "1107", "1107A", "1101", "1203" }; | 
						|
 | 
						|
        #region 执行边界修复 | 
						|
        public static List<BoundaryRepairGeometryMessages> ExecuteRepair(BoundaryRepairEntity parameter, ISpatialReference SpatialReference) | 
						|
        { | 
						|
            BoundaryRepairEntity repair = null; | 
						|
            try | 
						|
            { | 
						|
                repair = parameter; | 
						|
                IGeometry geometry = parameter.Geometry; | 
						|
                if (geometry == null || geometry.IsEmpty) | 
						|
                { | 
						|
                    return null; | 
						|
                } | 
						|
 | 
						|
                #region 原始图形存在尖锐角/狭长 | 
						|
                List<IPoint> yspointList = null; | 
						|
                double ysangle = 0; | 
						|
                #region 尖锐角 | 
						|
                //尖锐角检查与修复 | 
						|
                if (SharpAngle.JudgmentSharpAngle(repair.Geometry, ref yspointList, ref ysangle)) | 
						|
                { | 
						|
                    repair.Geometry = SharpAngle.ProcessSharpAngles(repair.Geometry, 3); | 
						|
                } | 
						|
                #endregion | 
						|
                #region 局部狭长 | 
						|
                //if (PolygonNarrowCheck.IsNarrowGeometry(repair.Geometry)) | 
						|
                //{ | 
						|
                //    List<NetTopologySuite.Geometries.Geometry> geometries = new List<NetTopologySuite.Geometries.Geometry>(); | 
						|
                //    foreach (var item in parameter.ListReference) | 
						|
                //    { | 
						|
                //        var wkb = GeometryConvertHelper.ConvertGeometryToWKB(item.Geometry); | 
						|
                //        NetTopologySuite.Geometries.Geometry ntsGeometry = (NetTopologySuite.Geometries.Geometry)new WKBReader().Read(wkb); | 
						|
                //        geometries.Add(ntsGeometry); | 
						|
                //    } | 
						|
                //    TopologyRepairEngine.FullRepair(geometries); | 
						|
                //} | 
						|
                //else | 
						|
                //{ | 
						|
                //    return null; | 
						|
                //} | 
						|
                #endregion | 
						|
 | 
						|
                //狭长图斑检查与修复 | 
						|
                if (SharpAngleDataCheck(repair.Geometry, ref yspointList, ref ysangle)) | 
						|
                { | 
						|
                    //子地块为小于10平且为狭长或尖锐角的图形直接删除 | 
						|
                    if (repair.Geometry.GetEllipseArea() < 30) return repair.ListReference; | 
						|
                    if (ysangle > 10) | 
						|
                    { | 
						|
                        //狭长图形,向内缓冲0.05 | 
						|
                        repair.Geometry = ResolveLongAndNarrow(repair.Geometry); | 
						|
                    } | 
						|
                    else | 
						|
                    { | 
						|
                        //尖锐角 | 
						|
                        if (yspointList != null && yspointList.Count == 3) | 
						|
                        { | 
						|
                            //repair.Geometry = SharpAngleErase(repair.Geometry, yspointList); | 
						|
                            #region  2024.1014新增逻辑 尖锐角位置外扩1米 | 
						|
                            { | 
						|
                                repair.Geometry = Scale_Out(repair.Geometry, yspointList, parameter.ListReference); | 
						|
                                //尖锐角修复完成后 面积小于30平的子地块删除 | 
						|
 | 
						|
                            } | 
						|
                            #endregion | 
						|
                        } | 
						|
                    } | 
						|
                } | 
						|
                #endregion | 
						|
                //尖锐角/狭长图形修复完以后,图形为空直接返回,删除当前子地块 | 
						|
                if (repair.Geometry.IsEmpty) return repair.ListReference; | 
						|
                //尖锐角与狭长图形修复完成后,面积小于10平的 且 | 
						|
                if (repair.Geometry.GetEllipseArea() < 10 && !XZDW_List.Contains(repair.DLBM)) return repair.ListReference; | 
						|
 | 
						|
                #region 压盖带一个参考图形 | 
						|
                if (repair.ListReference != null && repair.ListReference.Count == 1) | 
						|
                { | 
						|
                    BoundaryRepairGeometryMessages jcdltb = repair.ListReference[0]; | 
						|
                    #region 面积相差小于1的 直接使用基础库图形 | 
						|
                    var refmj = jcdltb.Geometry.GetEllipseArea(); | 
						|
                    var geomj = repair.Geometry.GetEllipseArea(); | 
						|
                    if (refmj == geomj || Math.Abs(refmj - geomj) < 1) | 
						|
                    { | 
						|
                        if (!string.IsNullOrEmpty(repair.DLBM)) | 
						|
                        { | 
						|
                            jcdltb.DLBM = repair.DLBM; | 
						|
                            jcdltb.CZCSXM = repair.CZCSXM; | 
						|
                            jcdltb.Modify = true; | 
						|
                            jcdltb.BSM = $"NMK_{parameter.DKID}"; | 
						|
                        } | 
						|
                        return repair.ListReference; | 
						|
                    } | 
						|
                    #endregion | 
						|
 | 
						|
                    #region 图形在基础数据内部 且被动变更图斑不存在尖锐角/狭长图形 | 
						|
                    var Difference = FeatureAPI.Difference(jcdltb.Geometry, repair.Geometry); | 
						|
                    var Differences = FeatureAPI.DissolveGeometryByRing(Difference); | 
						|
                    bool iscontinue = true; | 
						|
                    foreach (var diff in Differences) | 
						|
                    { | 
						|
                        if (diff.IsEmpty) continue; | 
						|
                        var mj = diff.GetEllipseArea(); | 
						|
                        if (mj < 1) | 
						|
                        { | 
						|
                            iscontinue = false; break; | 
						|
                        } | 
						|
                        List<IPoint> pointList = null; | 
						|
                        double angle = 0; | 
						|
                        if (AECommonHelper.SharpAngleDataCheck(diff, ref pointList, ref angle)) | 
						|
                        { | 
						|
                            iscontinue = false; break; | 
						|
                        } | 
						|
                    } | 
						|
                    if (iscontinue) | 
						|
                    { | 
						|
                        //地类编码为空的 不更新年末数据库 | 
						|
                        if (!string.IsNullOrEmpty(repair.DLBM)) | 
						|
                        { | 
						|
                            jcdltb.Geometry = Difference; | 
						|
                            jcdltb.Modify = true; | 
						|
                        } | 
						|
                        repair.ListReference.Add( | 
						|
                            new BoundaryRepairGeometryMessages() | 
						|
                            { | 
						|
                                Objectid = -1, | 
						|
                                BSM = $"NMK_{parameter.DKID}", | 
						|
                                CZCSXM = repair.CZCSXM, | 
						|
                                DLBM = repair.DLBM, | 
						|
                                Geometry = repair.Geometry, | 
						|
                                Modify = true | 
						|
                            }); | 
						|
                        return repair.ListReference; | 
						|
                    } | 
						|
                    #endregion | 
						|
 | 
						|
                } | 
						|
                #endregion | 
						|
 | 
						|
                if (repair.ListReference != null && repair.ListReference.Count >= 1) | 
						|
                { | 
						|
                    foreach (var jcfc in repair.ListReference) | 
						|
                    { | 
						|
                        #region 与基础库相交 | 
						|
                        if (repair.Geometry.IsEmpty) break; | 
						|
                        ITopologicalOperator topoOpr_jc = jcfc.Geometry as ITopologicalOperator; | 
						|
                        topoOpr_jc.Simplify(); | 
						|
                        IGeometry InterArea = FeatureAPI.InterSect(jcfc.Geometry, repair.Geometry); | 
						|
                        if (InterArea == null || InterArea.IsEmpty) continue;//未相交到或相交为空图形的直接跳过 | 
						|
                        List<IGeometry> InterAreas = FeatureAPI.DissolveGeometryByRing(InterArea); | 
						|
                        if (InterAreas == null || InterAreas.Count == 0) continue; | 
						|
                        InterAreas = InterAreas.OrderBy(x => x.GetEllipseArea()).ToList(); | 
						|
                        foreach (var area in InterAreas) | 
						|
                        { | 
						|
                            ITopologicalOperator topoOpr = area as ITopologicalOperator; | 
						|
                            topoOpr.Simplify(); | 
						|
                            if (area.IsEmpty) continue;//空图形不处理 | 
						|
                            var mj = area.GetEllipseArea(); | 
						|
                            if (mj < 1)//相交面积小于1的图形擦除 | 
						|
                            { | 
						|
                                repair.Geometry = FeatureAPI.Difference(repair.Geometry, area); continue; | 
						|
                            } | 
						|
                            else if (mj < 10) | 
						|
                            { | 
						|
                                List<IPoint> pointList = null; | 
						|
                                double angle = 0; | 
						|
                                //相交面积小于10且相交图形为尖锐角或者狭长图形的擦除 | 
						|
                                if (AECommonHelper.SharpAngleDataCheck(area, ref pointList, ref angle)) | 
						|
                                { | 
						|
                                    repair.Geometry = FeatureAPI.Difference(repair.Geometry, area); continue; | 
						|
                                } | 
						|
                                else | 
						|
                                { | 
						|
                                    //if (jcfc.BSM.StartsWith("NMK")) | 
						|
                                    //    repair.Geometry = FeatureAPI.Difference(repair.Geometry, area); | 
						|
                                    //参与图形修复的基础库 | 
						|
                                    jcfc.IsReference = true; | 
						|
                                    continue; | 
						|
                                } | 
						|
                            } | 
						|
                            else | 
						|
                            { | 
						|
                                //if (jcfc.BSM.StartsWith("NMK"))  | 
						|
                                //    repair.Geometry = FeatureAPI.Difference(repair.Geometry, area); | 
						|
                                //参与图形修复的基础库 | 
						|
                                jcfc.IsReference = true; | 
						|
                                continue; | 
						|
                            } | 
						|
                        } | 
						|
                        #endregion | 
						|
 | 
						|
                        if (!jcfc.IsReference) continue; | 
						|
 | 
						|
                        #region 与基础库不相交的面积 | 
						|
                        IGeometry DifferenceArea = FeatureAPI.Difference(jcfc.Geometry, repair.Geometry); | 
						|
                        List<IGeometry> DifferenceAreas = FeatureAPI.DissolveGeometryByRing(DifferenceArea); | 
						|
                        if (DifferenceAreas != null && DifferenceAreas.Count > 0) | 
						|
                        { | 
						|
                            foreach (var diff in DifferenceAreas) | 
						|
                            { | 
						|
                                ITopologicalOperator topoOpr = diff as ITopologicalOperator; | 
						|
                                topoOpr.Simplify(); | 
						|
                                if (diff.IsEmpty) continue; | 
						|
                                var mj = diff.GetEllipseArea(); | 
						|
                                List<IPoint> pointList1 = null; | 
						|
                                double angle = 0; | 
						|
                                if (mj < 1)//未相交面积小于1的图形合并 | 
						|
                                { | 
						|
                                    if (FeatureAPI.IsAdjacent(repair.Geometry, diff)) | 
						|
                                        repair.Geometry = FeatureAPI.Union(repair.Geometry, diff); | 
						|
                                } | 
						|
                                else if (!diff.IsEmpty && mj < 10 && AECommonHelper.SharpAngleDataCheck(diff, ref pointList1, ref angle)) | 
						|
                                { | 
						|
                                    if (FeatureAPI.IsAdjacent(repair.Geometry, diff)) | 
						|
                                        repair.Geometry = FeatureAPI.Union(repair.Geometry, diff); | 
						|
                                } | 
						|
                                else | 
						|
                                { | 
						|
                                    #region 被动变更小于30平且相邻的图斑与当前图斑合并 | 
						|
                                    if (mj <= 30 && FeatureAPI.IsAdjacent(repair.Geometry, diff)) | 
						|
                                    { | 
						|
                                        repair.Geometry = FeatureAPI.Union(repair.Geometry, diff); | 
						|
                                    } | 
						|
                                    #endregion | 
						|
                                } | 
						|
                            } | 
						|
                        } | 
						|
                        #endregion | 
						|
                    } | 
						|
                    if (repair.Geometry.IsEmpty) return repair.ListReference; | 
						|
                    if (repair.ListReference.Where(x => x.IsReference).ToList().Count == 1) | 
						|
                    { | 
						|
                        BoundaryRepairGeometryMessages jcdltb = repair.ListReference.Where(x => x.IsReference).ToList().FirstOrDefault(); | 
						|
 | 
						|
                        #region 压盖带一个参考图形 | 
						|
 | 
						|
                        #region 面积相差小于1的 直接使用基础库图形 | 
						|
                        var refmj = jcdltb.Geometry.GetEllipseArea(); | 
						|
                        var geomj = repair.Geometry.GetEllipseArea(); | 
						|
                        if (refmj == geomj || Math.Abs(refmj - geomj) < 1) | 
						|
                        { | 
						|
                            repair.ListReference.Add(new BoundaryRepairGeometryMessages() | 
						|
                            { | 
						|
                                Objectid = -1, | 
						|
                                BSM = $"NMK_{parameter.DKID.ToTrim().Replace("-", "")}", | 
						|
                                CZCSXM = repair.CZCSXM, | 
						|
                                DLBM = repair.DLBM, | 
						|
                                Geometry = jcdltb.Geometry, | 
						|
                                Modify = true, | 
						|
                                Describe = "图形修复:变更图斑与基础数据库图形差异较小,直接使用基础数据库图形" | 
						|
                            }); | 
						|
                            if (!string.IsNullOrEmpty(repair.DLBM)) | 
						|
                            { | 
						|
                                jcdltb.Geometry = null; | 
						|
                                jcdltb.Modify = true; | 
						|
                            } | 
						|
                            return repair.ListReference; | 
						|
                        } | 
						|
                        #endregion | 
						|
 | 
						|
                        #region 图形在基础数据内部 且被动变更图斑不存在尖锐角/狭长图形 | 
						|
                        var Difference = FeatureAPI.Difference(jcdltb.Geometry, repair.Geometry); | 
						|
                        var Differences = FeatureAPI.DissolveGeometryByRing(Difference); | 
						|
                        bool iscontinue = true; | 
						|
                        if (Differences != null && Differences.Count > 0) | 
						|
                            foreach (var diff in Differences) | 
						|
                            { | 
						|
                                if (diff.IsEmpty) continue; | 
						|
                                var mj = diff.GetEllipseArea(); | 
						|
                                if (mj < 1) | 
						|
                                { | 
						|
                                    iscontinue = false; break; | 
						|
                                } | 
						|
                                List<IPoint> pointList = null; | 
						|
                                double angle = 0; | 
						|
                                if (AECommonHelper.SharpAngleDataCheck(diff, ref pointList, ref angle)) | 
						|
                                { | 
						|
                                    iscontinue = false; break; | 
						|
                                } | 
						|
                                foreach (var item in repair.ListReference) | 
						|
                                { | 
						|
                                    if (item.BSM == jcdltb.BSM) continue; | 
						|
                                    if (FeatureAPI.IsInterSect(item.Geometry, diff)) | 
						|
                                    { | 
						|
                                        iscontinue = false; break; | 
						|
                                    } | 
						|
                                } | 
						|
                            } | 
						|
                        if (iscontinue) | 
						|
                        { | 
						|
                            repair.Geometry = FeatureAPI.Difference(jcdltb.Geometry, Difference); | 
						|
                            #region 出现多部件的图形,需要进行节点修复逻辑 | 
						|
                            List<IGeometry> geometryList = FeatureAPI.DissolveGeometryByRing(repair.Geometry);//拆分多部件 | 
						|
                            if (geometryList.Count > 1) | 
						|
                            { | 
						|
 | 
						|
                            } | 
						|
                            else | 
						|
                            { | 
						|
                                //地类编码为空的 不更新年末数据库 | 
						|
                                if (!string.IsNullOrEmpty(repair.DLBM)) | 
						|
                                { | 
						|
                                    if (Difference.IsEmpty) | 
						|
                                    { | 
						|
                                        jcdltb.Geometry = null; | 
						|
                                    } | 
						|
                                    else | 
						|
                                    { | 
						|
                                        jcdltb.Geometry = Difference; | 
						|
                                    } | 
						|
                                    jcdltb.Modify = true; | 
						|
                                } | 
						|
 | 
						|
                                repair.ListReference.Add(new BoundaryRepairGeometryMessages() | 
						|
                                { | 
						|
                                    Objectid = -1, | 
						|
                                    BSM = $"NMK_{parameter.DKID.ToTrim().Replace("-", "")}", | 
						|
                                    CZCSXM = repair.CZCSXM, | 
						|
                                    DLBM = repair.DLBM, | 
						|
                                    Geometry = repair.Geometry, | 
						|
                                    Modify = true, | 
						|
                                    Describe = "图形修复:" | 
						|
                                }); | 
						|
                                return repair.ListReference; | 
						|
                            } | 
						|
                            #endregion | 
						|
 | 
						|
                        } | 
						|
                        #endregion | 
						|
 | 
						|
                        #endregion | 
						|
 | 
						|
                    } | 
						|
                    #region 没有参考基础库 | 
						|
                    if (repair.ListReference.Where(x => x.IsReference).ToList().Count == 0) return repair.ListReference; | 
						|
                    #endregion | 
						|
 | 
						|
                    var geometrys = ExecuteBoundaryRepair(repair, repair.ListReference, 0.618); | 
						|
                    foreach (var item in geometrys) | 
						|
                    { | 
						|
                        if (item == null || item.IsEmpty || item.GetEllipseArea() == 0) | 
						|
                            continue; | 
						|
                        if (geometrys.Count > 1 && item.GetEllipseArea() < 30) | 
						|
                            continue; | 
						|
                        foreach (BoundaryRepairGeometryMessages jcdltb in repair.ListReference) | 
						|
                        { | 
						|
                            if (!jcdltb.IsReference) continue; | 
						|
                            IGeometry diff = FeatureAPI.Difference(jcdltb.Geometry, item); | 
						|
                            if (diff == null || diff.IsEmpty || diff.GetEllipseArea() == 0) | 
						|
                            { | 
						|
                                if (!string.IsNullOrEmpty(repair.DLBM)) | 
						|
                                { | 
						|
                                    jcdltb.Geometry = null; | 
						|
                                    jcdltb.Modify = true; | 
						|
                                } | 
						|
                            } | 
						|
                            else | 
						|
                            { | 
						|
                                if (!string.IsNullOrEmpty(repair.DLBM)) | 
						|
                                { | 
						|
                                    jcdltb.Geometry = diff; | 
						|
                                    jcdltb.Modify = true; | 
						|
                                } | 
						|
                            } | 
						|
                        } | 
						|
                        BoundaryRepairGeometryMessages referenceEntity = new BoundaryRepairGeometryMessages(); | 
						|
                        referenceEntity.Objectid = -1; | 
						|
                        referenceEntity.BSM = $"NMK_{repair.DKID.ToTrim().Replace("-", "")}"; | 
						|
                        referenceEntity.CZCSXM = repair.CZCSXM; | 
						|
                        referenceEntity.DLBM = repair.DLBM; | 
						|
                        referenceEntity.Geometry = item; | 
						|
                        referenceEntity.Modify = true; | 
						|
                        referenceEntity.Describe = "图形修复:节点修复"; | 
						|
                        if (repair.ListReference.FirstOrDefault(x => x.BSM == referenceEntity.BSM) != null) | 
						|
                        { | 
						|
                            referenceEntity.BSM = $"NMK_{Guid.NewGuid().ToTrim().Replace("-", "")}"; | 
						|
                        } | 
						|
                        repair.ListReference.Add(referenceEntity); | 
						|
                    } | 
						|
                } | 
						|
                else | 
						|
                { | 
						|
                    return repair.ListReference; | 
						|
                } | 
						|
            } | 
						|
            catch (Exception ex) | 
						|
            { | 
						|
                throw; | 
						|
            } | 
						|
            return repair.ListReference; | 
						|
        } | 
						|
        #endregion | 
						|
 | 
						|
        #region 尖锐角修复---向外扩1米 | 
						|
        private static IGeometry Scale_Out(IGeometry ysgeometry, List<IPoint> points, List<BoundaryRepairGeometryMessages> referenceLayersGeometryMessages) | 
						|
        { | 
						|
            List<IPoint> pointList = null; | 
						|
            double angle = 0; | 
						|
            IGeometry geometry = null; | 
						|
            try | 
						|
            { | 
						|
                IPolyline polyline1 = new PolylineClass(); | 
						|
                IPolyline polyline1_vertical = null; | 
						|
                IPolyline polyline2_vertical = null; | 
						|
                IPolyline polyline2 = new PolylineClass(); | 
						|
                if (points.Count == 3) | 
						|
                { | 
						|
                    polyline1.SpatialReference = points[0].SpatialReference; | 
						|
                    polyline1.FromPoint = points[1]; | 
						|
                    polyline1.ToPoint = points[0]; | 
						|
                    polyline1_vertical = GetPerpendicularLine(polyline1, true); | 
						|
 | 
						|
                    polyline2.SpatialReference = points[0].SpatialReference; | 
						|
                    polyline2.FromPoint = points[1]; | 
						|
                    polyline2.ToPoint = points[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 | 
						|
                List<IPoint> points1 = new List<IPoint>() { length1Point, points[1], points[0] }; | 
						|
                IGeometry geometry1 = GenerateGeometryFromPoints(points1); | 
						|
                geometry1.SpatialReference = ysgeometry.SpatialReference; | 
						|
 | 
						|
                List<IPoint> points2 = new List<IPoint>() { length2Point, points[1], points[0] }; | 
						|
                IGeometry geometry2 = GenerateGeometryFromPoints(points2); | 
						|
                geometry2.SpatialReference = ysgeometry.SpatialReference; | 
						|
                var IsInterSectcount1 = 0; | 
						|
                var IsInterSectcount2 = 0; | 
						|
                foreach (BoundaryRepairGeometryMessages entity in referenceLayersGeometryMessages) | 
						|
                { | 
						|
                    if (FeatureAPI.IsInterSect(geometry1, entity.Geometry)) | 
						|
                    { | 
						|
                        IsInterSectcount1++; | 
						|
                    } | 
						|
                    if (FeatureAPI.IsInterSect(geometry2, entity.Geometry)) | 
						|
                    { | 
						|
                        IsInterSectcount2++; | 
						|
                    } | 
						|
                } | 
						|
                if (IsInterSectcount1 <= IsInterSectcount2) | 
						|
                { | 
						|
                    geometry = FeatureAPI.Union(ysgeometry, geometry1); | 
						|
                } | 
						|
                else | 
						|
                { | 
						|
                    geometry = FeatureAPI.Union(ysgeometry, geometry2); | 
						|
                } | 
						|
                if (AECommonHelper.SharpAngleDataCheck(geometry, ref pointList, ref angle)) | 
						|
                { | 
						|
                    if (angle > 10) | 
						|
                    { | 
						|
                        geometry = ResolveLongAndNarrow(geometry); | 
						|
                    } | 
						|
                    else | 
						|
                    { | 
						|
                        //geometry = Scale_Out(geometry, pointList, referenceLayersGeometryMessages); | 
						|
                    } | 
						|
                } | 
						|
                else | 
						|
                { | 
						|
                    return geometry; | 
						|
                } | 
						|
 | 
						|
            } | 
						|
            catch (Exception) | 
						|
            { | 
						|
                return ysgeometry; | 
						|
            } | 
						|
            return geometry; | 
						|
        } | 
						|
        #endregion | 
						|
 | 
						|
        #region 根据点集合生成图形 | 
						|
        /// <summary> | 
						|
        /// 根据点集合生成图形 | 
						|
        /// </summary> | 
						|
        /// <param name="Points"></param> | 
						|
        /// <returns></returns> | 
						|
        private static IGeometry GenerateGeometryFromPoints(List<IPoint> Points) | 
						|
        { | 
						|
            try | 
						|
            { | 
						|
                Ring ring = new RingClass(); | 
						|
                object missing = Type.Missing; | 
						|
                IPointCollection pointCollection2 = new MultipointClass(); | 
						|
                if (Points != null && Points.Count == 3) | 
						|
                { | 
						|
                    if (Points[0] != null && Points[1] != null && Points[2] != null)//Points中不为空 | 
						|
                    { | 
						|
                        pointCollection2.AddPoint(Points[0]); | 
						|
                        pointCollection2.AddPoint(Points[1]); | 
						|
                        pointCollection2.AddPoint(Points[2]); | 
						|
                    } | 
						|
                } | 
						|
                ring.AddPointCollection(pointCollection2); | 
						|
                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; | 
						|
            } | 
						|
            catch (Exception ex) | 
						|
            { | 
						|
                throw ex; | 
						|
            } | 
						|
        } | 
						|
        #endregion | 
						|
 | 
						|
        #region MyRegion | 
						|
        private static List<IGeometry> ExecuteBoundaryRepair(BoundaryRepairEntity repair, List<BoundaryRepairGeometryMessages> jcdltb_features, double distance) | 
						|
        { | 
						|
            List<IGeometry> ResultgeometryList = new List<IGeometry>(); | 
						|
            List<IGeometry> geometryList = null; | 
						|
            try | 
						|
            { | 
						|
                geometryList = FeatureAPI.DissolveGeometryByRing(repair.Geometry);//拆分多部件 | 
						|
                foreach (IGeometry Splitgeo in geometryList) | 
						|
                { | 
						|
                    //IGeometry geometry = Splitgeo; | 
						|
                    IClone clone = Splitgeo as IClone; | 
						|
                    IGeometry geometry = clone?.Clone() as IGeometry; | 
						|
                    if (geometry == null || geometry.IsEmpty || geometry.GetEllipseArea() == 0) continue; | 
						|
                    IGeometry repaird = NodeRepair(geometry, jcdltb_features, distance); | 
						|
                    if (repaird != null && !repaird.IsEmpty) | 
						|
                    { | 
						|
                        geometry = repaird; | 
						|
                        geometry.SpatialReference = repair.Geometry.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 < 10) | 
						|
                            { | 
						|
                                geometry = FeatureAPI.Difference(geometry, geo); | 
						|
                            } | 
						|
                        } | 
						|
                    } | 
						|
                    else if (multi == null) | 
						|
                        continue; | 
						|
                    #endregion | 
						|
 | 
						|
                    #region 检查图形是否存在尖锐角/狭长图形等问题 | 
						|
                    //List<IPoint> pointList = null; | 
						|
                    //double angle = 0; | 
						|
                    //if (AECommonHelper.SharpAngleDataCheck(geometry, ref pointList, ref angle)) | 
						|
                    //{ | 
						|
                    //    if (geometry.GetEllipseArea() > 10) | 
						|
                    //    { | 
						|
                    //        if (pointList != null && angle < 10) | 
						|
                    //        { | 
						|
                    //            if (jcdltb_features.Where(x => x.IsReference).ToList().Count == 1) | 
						|
                    //            { | 
						|
                    //                var Reference = jcdltb_features.Where(x => x.IsReference).ToList(); | 
						|
                    //                geometry = ResolveAcuteAngle(geometry, pointList, angle, Reference[0].RefGeometry, true); | 
						|
                    //            } | 
						|
                    //            else | 
						|
                    //            { | 
						|
                    //                //var completedgeo = SharpAngleMerge(geometry, pointList); | 
						|
                    //                geometry = ResolveAcuteAngle(geometry, pointList, angle); | 
						|
                    //            } | 
						|
                    //        } | 
						|
                    //    } | 
						|
                    //    else | 
						|
                    //    { | 
						|
                    //        //节点修复完成后,面积小于10 且为尖锐角的图形 | 
						|
                    //        continue; | 
						|
                    //    } | 
						|
                    //} | 
						|
                    #endregion | 
						|
 | 
						|
                    #region 判断当前图斑是否压盖多个图斑且存在碎图斑 | 
						|
                    foreach (BoundaryRepairGeometryMessages jcdltb in jcdltb_features) | 
						|
                    { | 
						|
                        #region 相交部分 | 
						|
                        var geo = FeatureAPI.InterSect(geometry, jcdltb.Geometry); | 
						|
                        List<IGeometry> 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(); | 
						|
                                List<IPoint> pointList2 = null; | 
						|
                                double angle2 = 0; | 
						|
                                if (mj < 1 && !item.IsEmpty) | 
						|
                                { | 
						|
                                    geometry = FeatureAPI.Difference(geometry, item); | 
						|
                                } | 
						|
                                else if (!item.IsEmpty && mj < 10 && AECommonHelper.SharpAngleDataCheck(item, ref pointList2, ref angle2)) | 
						|
                                { | 
						|
                                    geometry = FeatureAPI.Difference(geometry, item); | 
						|
                                } | 
						|
                            } | 
						|
                        } | 
						|
                        else | 
						|
                        { | 
						|
                            continue; | 
						|
                        } | 
						|
                        #endregion | 
						|
 | 
						|
                        #region 不相交部分 | 
						|
                        geo = FeatureAPI.Difference(jcdltb.Geometry, geometry); | 
						|
                        geometries = FeatureAPI.DissolveGeometryByRing(geo); | 
						|
                        if (geometries != null && geometries.Count > 0) | 
						|
                        { | 
						|
                            foreach (var item in geometries) | 
						|
                            { | 
						|
                                ITopologicalOperator topoOpr = item as ITopologicalOperator; | 
						|
                                topoOpr.Simplify(); | 
						|
                                List<IPoint> pointList = null; | 
						|
                                double angle = 0; | 
						|
                                var mj = item.GetEllipseArea(); | 
						|
                                if (item.IsEmpty) continue; | 
						|
                                //与基础库不相交的部分面积小于30平且相邻的情况下 合并 | 
						|
                                if (mj < 30 && FeatureAPI.IsAdjacent(geometry, item)) | 
						|
                                { | 
						|
                                    //线状地物不与碎图斑合并 | 
						|
                                    //if (!string.IsNullOrEmpty(repair.DLBM) && DL.Contains(repair.DLBM)) continue; | 
						|
 | 
						|
                                    #region 避免合并后是镂空的多环图形 | 
						|
                                    //bool isMultiRing = false; | 
						|
                                    //IGeometry multiRingGeo = FeatureAPI.Union(repair.Geometry, item); | 
						|
                                    //IPolygon4 poly4 = multiRingGeo as IPolygon4; | 
						|
                                    //GeometryBag geoBag = poly4.ExteriorRingBag as GeometryBag; | 
						|
                                    //if (geoBag != null) | 
						|
                                    //{ | 
						|
                                    //    IGeometryCollection geoCollection = geoBag as IGeometryCollection; | 
						|
                                    //    for (int j = 0; j < geoCollection.GeometryCount; j++) | 
						|
                                    //    { | 
						|
                                    //        IGeometry geoExterior = geoCollection.get_Geometry(j); | 
						|
                                    //        //内环图形 | 
						|
                                    //        IGeometryBag InteriorBag = (multiRingGeo as IPolygon4).get_InteriorRingBag(geoExterior as IRing); | 
						|
                                    //        if (InteriorBag != null) | 
						|
                                    //        { | 
						|
                                    //            if (!(InteriorBag is IGeometryCollection InteriorRingGeometryCollection)) continue; | 
						|
                                    //            if (InteriorRingGeometryCollection.GeometryCount > 0) | 
						|
                                    //            { | 
						|
                                    //                isMultiRing = true; | 
						|
                                    //                break; | 
						|
                                    //            } | 
						|
                                    //        } | 
						|
                                    //    } | 
						|
                                    //    if (isMultiRing) continue; | 
						|
                                    //} | 
						|
                                    #endregion | 
						|
 | 
						|
                                    geometry = FeatureAPI.Union(geometry, item); | 
						|
                                    continue; | 
						|
                                } | 
						|
                                else | 
						|
                                { | 
						|
                                    if (AECommonHelper.SharpAngleDataCheck(item, ref pointList, ref angle)) | 
						|
                                    { | 
						|
                                        if (angle > 10)//狭长图形 | 
						|
                                        { | 
						|
                                            continue; | 
						|
                                        } | 
						|
                                        else | 
						|
                                        { | 
						|
                                            #region 被动变更尖锐角处理 | 
						|
                                            geometry = Passive_Sharp_Repair(pointList, geometry, item); | 
						|
                                            //if (pointList1.Count != 3 || angle1 == -1) continue; | 
						|
                                            //var completedgeo = SharpAngleMerge(item, pointList1);//获取被动变更尖锐角的组成部分,与当前变更图斑合并 | 
						|
                                            //var InterSect = FeatureAPI.InterSect(item, completedgeo);//仅合并与被动变更相交的部分 | 
						|
                                            //completedgeo = InterSect; | 
						|
                                            //var passive = FeatureAPI.Difference(item, completedgeo); | 
						|
                                            //if (passive.GetEllipseArea() < 30) completedgeo = item;//与尖锐角合并后剩余被动变更图斑面积小于30, | 
						|
                                            //var completedgeoMJ = completedgeo.GetEllipseArea(); | 
						|
                                            //if (FeatureAPI.IsAdjacent(geometry, completedgeo) && completedgeoMJ < 30) | 
						|
                                            //{ | 
						|
                                            //    var uniongeo = FeatureAPI.Union(geometry, completedgeo); | 
						|
                                            //    if (AECommonHelper.SharpAngleDataCheck(uniongeo, ref pointList, ref angle)) | 
						|
                                            //    { | 
						|
                                            //        geometry = ResolveAcuteAngle(uniongeo, pointList, angle, item, true); | 
						|
                                            //    } | 
						|
                                            //    else | 
						|
                                            //    { | 
						|
                                            //        geometry = uniongeo; | 
						|
                                            //    } | 
						|
                                            //} | 
						|
                                            //else | 
						|
                                            //{ | 
						|
                                            //} | 
						|
                                            #endregion | 
						|
 | 
						|
                                        } | 
						|
                                    } | 
						|
                                } | 
						|
                            } | 
						|
                        } | 
						|
                        #endregion | 
						|
                    } | 
						|
                    #endregion | 
						|
 | 
						|
                    #region 检查图形是否存在尖锐角/狭长图形等问题 | 
						|
                    List<IPoint> pointList1 = null; | 
						|
                    double angle1 = 0; | 
						|
                    if (AECommonHelper.SharpAngleDataCheck(geometry, ref pointList1, ref angle1)) | 
						|
                    { | 
						|
                        #region 擦除尖锐角 | 
						|
                        if (pointList1 != null && pointList1.Count == 3) | 
						|
                        { | 
						|
                            try | 
						|
                            { | 
						|
                                //构成尖锐角的两条边 | 
						|
                                IPolyline polylinemax = new PolylineClass(); | 
						|
                                polylinemax.SpatialReference = geometry.SpatialReference; | 
						|
                                polylinemax.FromPoint = pointList1[0]; | 
						|
                                polylinemax.ToPoint = pointList1[1]; | 
						|
 | 
						|
                                IPolyline polylinemin = new PolylineClass(); | 
						|
                                polylinemin.SpatialReference = geometry.SpatialReference; | 
						|
                                polylinemin.FromPoint = pointList1[2]; | 
						|
                                polylinemin.ToPoint = pointList1[1]; | 
						|
 | 
						|
                                IPolyline polyline_vertical = null;//获取较短的边做垂线 | 
						|
                                if (polylinemax.Length < polylinemin.Length) | 
						|
                                { | 
						|
                                    IPolyline temppolylinemin = new PolylineClass(); | 
						|
                                    temppolylinemin = polylinemax; | 
						|
                                    polylinemax = polylinemin; | 
						|
                                    polylinemin = temppolylinemin; | 
						|
                                } | 
						|
                                polyline_vertical = GetPerpendicularLine(polylinemin, true, polylinemin.Length); | 
						|
                                IPointCollection pPointCol = polyline_vertical as IPointCollection; | 
						|
                                IPoint fPoint = new PointClass(); | 
						|
                                IPoint ePoint = new PointClass(); | 
						|
                                object missing2 = Type.Missing; | 
						|
                                polyline_vertical.QueryPoint(esriSegmentExtension.esriExtendAtFrom, -1 * polylinemin.Length, false, fPoint); | 
						|
                                pPointCol.InsertPoints(0, 1, ref fPoint); | 
						|
                                polyline_vertical.QueryPoint(esriSegmentExtension.esriExtendAtTo, polylinemin.Length + polylinemin.Length, false, ePoint); | 
						|
                                pPointCol.AddPoint(ePoint, ref missing2, ref missing2); | 
						|
                                IPolyline polyline = pPointCol as IPolyline; | 
						|
                                ITopologicalOperator topo = polyline_vertical as ITopologicalOperator; | 
						|
                                IGeometry extendgeo = topo.Intersect(polylinemax, esriGeometryDimension.esriGeometry0Dimension); | 
						|
                                IPoint point = null; | 
						|
                                if (extendgeo.GeometryType == esriGeometryType.esriGeometryPoint) | 
						|
                                { | 
						|
                                    point = extendgeo as IPoint; | 
						|
                                } | 
						|
                                else | 
						|
                                { | 
						|
                                    if (extendgeo.GeometryType == esriGeometryType.esriGeometryMultipoint) | 
						|
                                    { | 
						|
                                        IPointCollection pointCollection = extendgeo as IPointCollection; | 
						|
                                        if (pointCollection.PointCount > 0) | 
						|
                                        { | 
						|
                                            point = pointCollection.get_Point(0); | 
						|
                                        } | 
						|
                                    } | 
						|
                                } | 
						|
                                List<IPoint> points1 = new List<IPoint>() { point, pointList1[1], pointList1[0] }; | 
						|
                                IGeometry geometry1 = GenerateGeometryFromPoints(points1); | 
						|
                                geometry1.SpatialReference = geometry.SpatialReference; | 
						|
                                geometry = FeatureAPI.Difference(geometry, geometry1); | 
						|
                            } | 
						|
                            catch (Exception ex) | 
						|
                            { | 
						|
 | 
						|
                            } | 
						|
                        } | 
						|
                        #endregion | 
						|
                        //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; | 
						|
                return ResultgeometryList; | 
						|
            } | 
						|
            return ResultgeometryList; | 
						|
        } | 
						|
        #endregion | 
						|
 | 
						|
        #region MyRegion | 
						|
        private static IGeometry NodeRepair(IGeometry OriginalGeo, List<BoundaryRepairGeometryMessages> ReferenceLayer, double distance) | 
						|
        { | 
						|
            IGeometry geometry = OriginalGeo; | 
						|
            try | 
						|
            { | 
						|
                List<IPoint> repairpoints = GetMultipleRingPoints(geometry); | 
						|
                var count = 0; | 
						|
                List<string> listmoveToPoint = new List<string>(); | 
						|
                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<IGeometry> 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; | 
						|
        } | 
						|
        #endregion | 
						|
 | 
						|
        #region Passive_Sharp_Repair | 
						|
        /// <summary> | 
						|
        /// 构成尖锐角较短的边与较长的边做垂线,构成一个直角三角形,将直角三角形擦除 | 
						|
        /// </summary> | 
						|
        /// <param name="pointList"></param> | 
						|
        /// <param name="bg_geometry"></param> | 
						|
        /// <param name="diffgeo"></param> | 
						|
        /// <returns></returns> | 
						|
        private static IGeometry Passive_Sharp_Repair(List<IPoint> pointList, IGeometry bg_geometry, IGeometry diffgeo) | 
						|
        { | 
						|
            List<IPoint> pointList1 = null; | 
						|
            double angle1 = 0; | 
						|
            try | 
						|
            { | 
						|
                if (pointList != null && pointList.Count == 3) | 
						|
                { | 
						|
                    //构成尖锐角的两条边 | 
						|
                    IPoint pointmax = pointList[0]; | 
						|
                    IPolyline polylinemax = new PolylineClass(); | 
						|
                    polylinemax.SpatialReference = bg_geometry.SpatialReference; | 
						|
                    polylinemax.FromPoint = pointList[0]; | 
						|
                    polylinemax.ToPoint = pointList[1]; | 
						|
 | 
						|
                    IPoint pointmin = pointList[2]; | 
						|
                    IPolyline polylinemin = new PolylineClass(); | 
						|
                    polylinemin.SpatialReference = bg_geometry.SpatialReference; | 
						|
                    polylinemin.FromPoint = pointList[2]; | 
						|
                    polylinemin.ToPoint = pointList[1]; | 
						|
 | 
						|
                    IPolyline polyline_vertical = null;//获取较短的边做垂线 | 
						|
                    if (polylinemax.Length < polylinemin.Length) | 
						|
                    { | 
						|
                        IPolyline temppolylinemin = new PolylineClass(); | 
						|
                        temppolylinemin = polylinemax; | 
						|
                        polylinemax = polylinemin; | 
						|
                        polylinemin = temppolylinemin; | 
						|
                        IPoint temppoint = new PointClass(); | 
						|
                        temppoint = pointmax; | 
						|
                        pointmax = pointmin; | 
						|
                        pointmin = temppoint; | 
						|
                    } | 
						|
                    polyline_vertical = GetPerpendicularLine(polylinemin, true, polylinemin.Length); | 
						|
                    IPointCollection pPointCol = polyline_vertical as IPointCollection; | 
						|
                    IPoint fPoint = new PointClass(); | 
						|
                    IPoint ePoint = new PointClass(); | 
						|
                    object missing2 = Type.Missing; | 
						|
                    polyline_vertical.QueryPoint(esriSegmentExtension.esriExtendAtFrom, -1 * polylinemin.Length, false, fPoint); | 
						|
                    pPointCol.InsertPoints(0, 1, ref fPoint); | 
						|
                    polyline_vertical.QueryPoint(esriSegmentExtension.esriExtendAtTo, polylinemin.Length + polylinemin.Length, false, ePoint); | 
						|
                    pPointCol.AddPoint(ePoint, ref missing2, ref missing2); | 
						|
                    IPolyline polyline = pPointCol as IPolyline; | 
						|
                    ITopologicalOperator topo = polyline_vertical as ITopologicalOperator; | 
						|
                    IGeometry extendgeo = topo.Intersect(polylinemax, esriGeometryDimension.esriGeometry0Dimension); | 
						|
                    IPoint point = null; | 
						|
                    if (extendgeo.GeometryType == esriGeometryType.esriGeometryPoint) | 
						|
                    { | 
						|
                        point = extendgeo as IPoint; | 
						|
                    } | 
						|
                    else | 
						|
                    { | 
						|
                        if (extendgeo.GeometryType == esriGeometryType.esriGeometryMultipoint) | 
						|
                        { | 
						|
                            IPointCollection pointCollection = extendgeo as IPointCollection; | 
						|
                            if (pointCollection.PointCount > 0) | 
						|
                            { | 
						|
                                point = pointCollection.get_Point(0); | 
						|
                            } | 
						|
                            else | 
						|
                            { | 
						|
                                point = pointmax; | 
						|
                            } | 
						|
                        } | 
						|
                    } | 
						|
                    List<IPoint> points1 = new List<IPoint>() { point, pointList[1], pointmin }; | 
						|
                    IGeometry geometry1 = GenerateGeometryFromPoints(points1); | 
						|
                    geometry1.SpatialReference = bg_geometry.SpatialReference; | 
						|
                    diffgeo = FeatureAPI.Difference(diffgeo, geometry1); | 
						|
                    if (AECommonHelper.SharpAngleDataCheck(diffgeo, ref pointList1, ref angle1)) | 
						|
                    { | 
						|
                        bg_geometry = FeatureAPI.Union(bg_geometry, geometry1); | 
						|
                        //bg_geometry = Passive_Sharp_Repair(pointList1, bg_geometry, diffgeo); | 
						|
                    } | 
						|
                    else | 
						|
                    { | 
						|
                        bg_geometry = FeatureAPI.Union(bg_geometry, geometry1); | 
						|
                        if (diffgeo.GetEllipseArea() < 30) | 
						|
                        { | 
						|
                            bg_geometry = FeatureAPI.Union(bg_geometry, diffgeo); | 
						|
                        } | 
						|
                        return bg_geometry; | 
						|
                    } | 
						|
                } | 
						|
                return bg_geometry; | 
						|
            } | 
						|
            catch (Exception ex) | 
						|
            { | 
						|
                return bg_geometry; | 
						|
            } | 
						|
        } | 
						|
        #endregion | 
						|
 | 
						|
        #region MyRegion | 
						|
        /// <summary> | 
						|
        /// 获取图形中的所有节点 | 
						|
        /// </summary> | 
						|
        /// <param name="geometry"></param> | 
						|
        /// <returns></returns> | 
						|
        private static List<IPoint> GetMultipleRingPoints(IGeometry geometry) | 
						|
        { | 
						|
            List<IPoint> dicOPnts = new List<IPoint>(); | 
						|
            try | 
						|
            { | 
						|
                if (geometry == null) return dicOPnts; | 
						|
                IGeometryCollection geometryCollection = geometry as IGeometryCollection; | 
						|
                IRing ring = null; | 
						|
                if (geometryCollection == null) | 
						|
                { | 
						|
                    IPointCollection iPntCollection = geometry as IPointCollection; | 
						|
                    if (iPntCollection == null || iPntCollection.PointCount <= 0) return dicOPnts; | 
						|
                    for (int j = 0; j < iPntCollection.PointCount - 1; j++) | 
						|
                    { | 
						|
                        dicOPnts.Add(iPntCollection.Point[j]); | 
						|
                    } | 
						|
                } | 
						|
                else | 
						|
                { | 
						|
                    for (int i = 0; i < geometryCollection.GeometryCount; i++) | 
						|
                    { | 
						|
                        ring = geometryCollection.get_Geometry(i) as IRing; | 
						|
                        IPointCollection iPntCollection = ring as IPointCollection; | 
						|
                        if (iPntCollection == null || iPntCollection.PointCount <= 0) return dicOPnts; | 
						|
                        for (int j = 0; j < iPntCollection.PointCount - 1; j++) | 
						|
                        { | 
						|
                            dicOPnts.Add(iPntCollection.Point[j]); | 
						|
                        } | 
						|
                    } | 
						|
                } | 
						|
 | 
						|
            } | 
						|
            catch (System.Exception ex) | 
						|
            { | 
						|
 | 
						|
            } | 
						|
            return dicOPnts; | 
						|
        } | 
						|
        #endregion | 
						|
 | 
						|
        #region GetPerpendicularLine | 
						|
        /// <summary> | 
						|
        /// 获取尖锐角顶点位置外扩一段距离的垂线 | 
						|
        /// </summary> | 
						|
        /// <param name="baseLine"></param> | 
						|
        /// <param name="direction">clockwise顺时针 true为顺时针/false为逆时针</param> | 
						|
        /// <returns></returns> | 
						|
        private static IPolyline GetPerpendicularLine(IPolyline baseLine, bool clockwise, double length = 1) | 
						|
        { | 
						|
            // 获取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; | 
						|
                } | 
						|
                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; | 
						|
        } | 
						|
        #endregion | 
						|
 | 
						|
        #region MyRegion | 
						|
        private static List<ConcurrentClass> GetSnappingpoint2(IPoint point, List<BoundaryRepairGeometryMessages> m_featureLayer, List<string> listmoveToPoint = null, double distance = 1) | 
						|
        { | 
						|
            List<ConcurrentClass> pointList = new List<ConcurrentClass>(); | 
						|
            try | 
						|
            { | 
						|
                foreach (BoundaryRepairGeometryMessages jcdltb in m_featureLayer) | 
						|
                { | 
						|
                    if (!jcdltb.IsReference) continue; | 
						|
                    IPoint iHitPt = new Point(); | 
						|
                    IHitTest iHitTest = jcdltb.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 (BoundaryRepairGeometryMessages item in m_featureLayer) | 
						|
                            { | 
						|
                                if (!jcdltb.IsReference) continue; | 
						|
                                iHitTest = item.Geometry 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(jcdltb.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(jcdltb.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(jcdltb.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 = jcdltb.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) | 
						|
            { | 
						|
 | 
						|
            } | 
						|
            return pointList; | 
						|
        } | 
						|
        #endregion | 
						|
 | 
						|
        #region 解决狭长图形问题 | 
						|
        /// <summary> | 
						|
        /// 解决狭长图形问题 | 
						|
        /// </summary> | 
						|
        /// <param name="geometry"></param> | 
						|
        /// <returns></returns> | 
						|
        private static IGeometry ResolveLongAndNarrow(IGeometry geometry) | 
						|
        { | 
						|
            List<IPoint> pointList = null; | 
						|
            double angle = 0; | 
						|
            try | 
						|
            { | 
						|
                ///向内缓冲,如果还存在狭长的图形,暂不做处理 | 
						|
                ITopologicalOperator topo = geometry as ITopologicalOperator; | 
						|
                IGeometry tempgeometry = topo.Buffer(-0.06); | 
						|
                // 消除缓冲区后的狭长部分 | 
						|
                ITopologicalOperator bufferTopologicalOperator = tempgeometry as ITopologicalOperator; | 
						|
                IGeometry geo = bufferTopologicalOperator.Buffer(0.05); | 
						|
                geo.SpatialReference = geometry.SpatialReference; | 
						|
                topo = geo as ITopologicalOperator; | 
						|
                topo.Simplify(); | 
						|
                //删除相邻节点距离较近的点 | 
						|
                IPointCollection points = geo as IPointCollection; | 
						|
                for (int i = 0; i < points.PointCount - 1; i++) | 
						|
                { | 
						|
                    IPoint tPoint = points.Point[i]; | 
						|
                    IPoint point = points.Point[i + 1]; | 
						|
                    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)) continue; | 
						|
                    if (Math.Abs(refdistance) < 1) | 
						|
                    { | 
						|
                        points.RemovePoints(i + 1, 1); | 
						|
                        i = 0; | 
						|
                        points = geo as IPointCollection; | 
						|
                        continue; | 
						|
                    } | 
						|
                } | 
						|
                points.AddPoint(points.Point[points.PointCount - 1]); | 
						|
                topo = geo as ITopologicalOperator; | 
						|
                topo.Simplify(); | 
						|
                if (SharpAngleDataCheck(geo, ref pointList, ref angle)) | 
						|
                { | 
						|
                    //狭长图形未处理 | 
						|
                    return geometry; | 
						|
                } | 
						|
                else | 
						|
                { | 
						|
                    geometry = geo; | 
						|
                } | 
						|
            } | 
						|
            catch (Exception ex) | 
						|
            { | 
						|
                return geometry; | 
						|
            } | 
						|
            return geometry; | 
						|
        } | 
						|
 | 
						|
        public static IGeometry ResolveLongAndNarrow(IGeometry geometry, double distance) | 
						|
        { | 
						|
            try | 
						|
            { | 
						|
                ///向内缓冲,如果还存在狭长的图形,暂不做处理 | 
						|
                ITopologicalOperator topo = geometry as ITopologicalOperator; | 
						|
                IGeometry tempgeometry = topo.Buffer(distance); | 
						|
                // 消除缓冲区后的狭长部分 | 
						|
                ITopologicalOperator bufferTopologicalOperator = tempgeometry as ITopologicalOperator; | 
						|
                IGeometry geo = bufferTopologicalOperator.Buffer(Math.Abs(distance)); | 
						|
                geo.SpatialReference = geometry.SpatialReference; | 
						|
                topo = geo as ITopologicalOperator; | 
						|
                topo.Simplify(); | 
						|
                IGeometry geometryDis = FeatureAPI.Difference(geometry, geo); | 
						|
                if (geometryDis == null || geometryDis.IsEmpty) | 
						|
                { | 
						|
                    //狭长图形未处理 | 
						|
                    return geometry; | 
						|
                } | 
						|
                else if (geometryDis.GetEllipseArea() < 5) | 
						|
                { | 
						|
                    return geo; | 
						|
                } | 
						|
                return geometry; | 
						|
            } | 
						|
            catch (Exception) | 
						|
            { | 
						|
                return geometry; | 
						|
            } | 
						|
        } | 
						|
        #endregion | 
						|
 | 
						|
        #region 要素存在尖锐角和局部狭长图形(即不允许存在一个角度小于10度,或局部图形狭长的情况) | 
						|
        private static bool SharpAngleDataCheck(IGeometry geometry, ref List<IPoint> pointList, ref double angle) | 
						|
        { | 
						|
            bool isSharpAngle = false; | 
						|
            try | 
						|
            { | 
						|
                if (geometry == null) return isSharpAngle; | 
						|
                angle = GetMinAngle(geometry, ref pointList);//获取图形的最小角度 | 
						|
                ITopologicalOperator topo = geometry as ITopologicalOperator; | 
						|
                IPolyline line1 = topo.Boundary as IPolyline; | 
						|
                double length1 = line1.Length;//原始图形的周长 | 
						|
                int pointCount1 = (geometry as IPointCollection).PointCount; | 
						|
                IGeometry geo = null; | 
						|
                if (geometry.GetEllipseArea() < 30) | 
						|
                    geo = topo.Buffer(-0.05); | 
						|
                else | 
						|
                    geo = topo.Buffer(-0.5); | 
						|
                #region 向内缓冲后形成了多个图斑,则认定存在狭长 | 
						|
                var geometry_diff = FeatureAPI.DissolveGeometryByRing(geometry); | 
						|
                var Differences = FeatureAPI.DissolveGeometryByRing(geo); | 
						|
                if (Differences != null && geometry_diff != null) | 
						|
                { | 
						|
                    if (Differences.Count > geometry_diff.Count) | 
						|
                    { | 
						|
                        return true; | 
						|
                    } | 
						|
                } | 
						|
                #endregion | 
						|
                ITopologicalOperator topo2 = geo as ITopologicalOperator; | 
						|
                IPolyline line2 = topo2.Boundary as IPolyline; | 
						|
                double length2 = line2.Length;//向内缓冲后的图形的周长 | 
						|
                double delta_length = length1 - length2;//周长差 | 
						|
                double avg_halfangle = 180 * (pointCount1 - 1 - 2) / (pointCount1 - 1) / 2;//平均 | 
						|
                double conner_normal_length = 2 * 0.05 / Math.Tan(avg_halfangle * (Math.PI / 180)); | 
						|
                if ((delta_length > 8 * conner_normal_length * (pointCount1 - 1)) || angle < 10) | 
						|
                { | 
						|
                    if ((delta_length > 8 * conner_normal_length * (pointCount1 - 1)) && angle < 10) | 
						|
                        return true; | 
						|
                    else if (delta_length > 8 * conner_normal_length * (pointCount1 - 1)) | 
						|
                        return true; | 
						|
                    else if (angle < 10) | 
						|
                        return true; | 
						|
                } | 
						|
            } | 
						|
            catch (Exception) | 
						|
            { | 
						|
 | 
						|
            } | 
						|
            finally | 
						|
            { | 
						|
                //GC.Collect(); | 
						|
            } | 
						|
            return isSharpAngle; | 
						|
        } | 
						|
        /// <summary> | 
						|
        /// 获取最小角度 | 
						|
        /// </summary> | 
						|
        /// <param name="pGeo"></param> | 
						|
        /// <returns></returns> | 
						|
        private static double GetMinAngle(IGeometry pGeo, ref List<IPoint> pointlist) | 
						|
        { | 
						|
            double result = -1; | 
						|
            IPolygon4 poly4 = null; | 
						|
            ITopologicalOperator topo = null; | 
						|
            GeometryBag geoBag = null; | 
						|
            IGeometryCollection geoCollection = null; | 
						|
            pointlist = new List<IPoint>(); | 
						|
            try | 
						|
            { | 
						|
                if (pGeo == null || pGeo.IsEmpty) | 
						|
                    return result; | 
						|
                poly4 = pGeo as IPolygon4; | 
						|
                topo = poly4 as ITopologicalOperator; | 
						|
                topo?.Simplify(); | 
						|
                geoBag = poly4.ExteriorRingBag as GeometryBag; | 
						|
                if (geoBag == null) return result; | 
						|
                geoCollection = geoBag as IGeometryCollection; | 
						|
                List<IGeometry> rings = new List<IGeometry>(); | 
						|
                for (int j = 0; j < geoCollection.GeometryCount; j++) | 
						|
                { | 
						|
                    IGeometry geo = geoCollection.get_Geometry(j); | 
						|
                    rings.Add(geo); | 
						|
                    //内环图形 | 
						|
                    IGeometryBag InteriorBag = (pGeo as IPolygon4).get_InteriorRingBag(geo as IRing); | 
						|
                    if (InteriorBag != null) | 
						|
                    { | 
						|
                        IGeometryCollection InteriorRingGeometryCollection = InteriorBag as IGeometryCollection; | 
						|
                        for (int IR = 0; IR < InteriorRingGeometryCollection.GeometryCount; IR++) | 
						|
                        { | 
						|
                            rings.Add(InteriorRingGeometryCollection.get_Geometry(IR)); | 
						|
                        } | 
						|
                    } | 
						|
                } | 
						|
                foreach (IGeometry ring in rings) | 
						|
                { | 
						|
                    if (ring.IsEmpty) continue; | 
						|
                    IPointCollection points = ring as IPointCollection; | 
						|
                    int num = points.PointCount - 1; | 
						|
                    for (int i = 0; i < num; i++) | 
						|
                    { | 
						|
                        IPoint p1 = null; | 
						|
                        IPoint p2 = points.get_Point(i); | 
						|
                        IPoint p3 = null; | 
						|
                        if (i == 0) | 
						|
                        { | 
						|
                            p1 = points.get_Point(num - 1); | 
						|
                            p3 = points.get_Point(i + 1); | 
						|
                        } | 
						|
                        else if (i == num - 1) | 
						|
                        { | 
						|
                            p1 = points.get_Point(i - 1); | 
						|
                            p3 = points.get_Point(0); | 
						|
                        } | 
						|
                        else | 
						|
                        { | 
						|
                            p1 = points.get_Point(i - 1); | 
						|
                            p3 = points.get_Point(i + 1); | 
						|
                        } | 
						|
                        if ((p2.X == p1.X && p2.Y == p1.Y) || (p2.X == p3.X && p2.Y == p3.Y)) | 
						|
                            continue; | 
						|
 | 
						|
                        double angle = GetAngle(p2, p1, p3); | 
						|
                        if (result == -1) | 
						|
                        { | 
						|
                            result = angle; | 
						|
                            pointlist.Add(p1); | 
						|
                            pointlist.Add(p2); | 
						|
                            pointlist.Add(p3); | 
						|
                        } | 
						|
                        else | 
						|
                        { | 
						|
                            if (result > angle) | 
						|
                            { | 
						|
                                result = angle; | 
						|
                                if (pointlist.Count > 0) pointlist.Clear(); | 
						|
                                pointlist.Add(p1); | 
						|
                                pointlist.Add(p2); | 
						|
                                pointlist.Add(p3); | 
						|
                            } | 
						|
                        } | 
						|
                    } | 
						|
                } | 
						|
            } | 
						|
            catch (Exception ex) | 
						|
            { | 
						|
                throw ex; | 
						|
            } | 
						|
            finally | 
						|
            { | 
						|
            } | 
						|
            return result; | 
						|
        } | 
						|
        /// <summary> | 
						|
        /// 计算角度 | 
						|
        /// </summary> | 
						|
        /// <param name="cenPoint"></param> | 
						|
        /// <param name="firstPoint"></param> | 
						|
        /// <param name="secondPoint"></param> | 
						|
        /// <returns></returns> | 
						|
        private static double GetAngle(IPoint cenPoint, IPoint firstPoint, IPoint secondPoint) | 
						|
        { | 
						|
            double ma_x = firstPoint.X - cenPoint.X; | 
						|
            double ma_y = firstPoint.Y - cenPoint.Y; | 
						|
            double mb_x = secondPoint.X - cenPoint.X; | 
						|
            double mb_y = secondPoint.Y - cenPoint.Y; | 
						|
            double v1 = (ma_x * mb_x) + (ma_y * mb_y); | 
						|
            double ma_val = Math.Sqrt(ma_x * ma_x + ma_y * ma_y); | 
						|
            double mb_val = Math.Sqrt(mb_x * mb_x + mb_y * mb_y); | 
						|
            if (ma_val * mb_val == 0) | 
						|
            { | 
						|
                return -1; | 
						|
            } | 
						|
            double cosM = v1 / (ma_val * mb_val); | 
						|
            double angleAMB = Math.Acos(cosM) * 180 / Math.PI; | 
						|
            return angleAMB; | 
						|
        } | 
						|
        #endregion | 
						|
 | 
						|
        #region GetRelativeAngle | 
						|
        /// <summary> | 
						|
        /// 获取当前点与前后两个点之间的夹角的角度 | 
						|
        /// </summary> | 
						|
        /// <param name="geometry"></param> | 
						|
        /// <param name="point"></param> | 
						|
        /// <returns></returns> | 
						|
        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 BoundaryRepairGeometryMessages | 
						|
    { | 
						|
        public int Objectid { get; set; } | 
						|
        public string DLBM { get; set; } | 
						|
        public string CZCSXM { get; set; } | 
						|
        public string BSM { get; set; } | 
						|
        public IGeometry Geometry { get; set; } | 
						|
        public bool IsReference { get; set; } | 
						|
        public bool Modify { get; set; } | 
						|
        public string Describe { get; set; } | 
						|
    } | 
						|
 | 
						|
    public class BoundaryRepairEntity | 
						|
    { | 
						|
        public IGeometry Geometry { get; set; } | 
						|
        public string DLBM { get; set; } | 
						|
        public string CZCSXM { get; set; } | 
						|
        public int MJ { get; set; } | 
						|
        public List<BoundaryRepairGeometryMessages> ListReference { get; set; } | 
						|
        public string DKID { get; set; } | 
						|
    } | 
						|
 | 
						|
}
 | 
						|
 |