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 { /// /// 边界修复 /// public static class BoundaryRepairHelperNew { private static List XZDW_List = new List() { "1001", "1002", "1003", "1004", "1006", "1009", "1107", "1107A", "1101", "1203" }; #region 执行边界修复 public static List ExecuteRepair(BoundaryRepairEntity parameter, ISpatialReference SpatialReference) { BoundaryRepairEntity repair = null; try { repair = parameter; IGeometry geometry = parameter.Geometry; if (geometry == null || geometry.IsEmpty) { return null; } #region 原始图形存在尖锐角/狭长 List 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 geometries = new List(); // 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 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 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 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 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 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 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 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 points, List referenceLayersGeometryMessages) { List 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 points1 = new List() { length1Point, points[1], points[0] }; IGeometry geometry1 = GenerateGeometryFromPoints(points1); geometry1.SpatialReference = ysgeometry.SpatialReference; List points2 = new List() { 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 根据点集合生成图形 /// /// 根据点集合生成图形 /// /// /// private static IGeometry GenerateGeometryFromPoints(List 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 ExecuteBoundaryRepair(BoundaryRepairEntity repair, List jcdltb_features, double distance) { List ResultgeometryList = new List(); List 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 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 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 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 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 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 points1 = new List() { 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 ReferenceLayer, double distance) { IGeometry geometry = OriginalGeo; try { List repairpoints = GetMultipleRingPoints(geometry); var count = 0; List listmoveToPoint = new List(); foreach (var point in repairpoints) { count++; var xx = point.X; var yy = point.Y; IPoint PrevPoint = null; IPoint NextPoint = null; var pointangle = GetRelativeAngle(geometry, point, ref PrevPoint, ref NextPoint); var UpdatePoint = GetSnappingpoint2(point, ReferenceLayer, listmoveToPoint, distance); if (UpdatePoint.Count == 0) continue; var Listpoint = UpdatePoint.OrderByDescending(x => x.ConcurrentCount).ToList(); IPoint moveToPoint = null; if (Listpoint.Count > 0) { bool isContains = true; foreach (var item in Listpoint) { if (!listmoveToPoint.Contains($"{item.Point.X},{item.Point.Y}")) { bool isbreak = false; foreach (var iPoint in listmoveToPoint) { var x = iPoint.Split(',')[0].ToDouble(); var y = iPoint.Split(',')[1].ToDouble(); //两个距离相近的点修复到同一个位置时,删除当前图形中的一个点 var refdistance = Math.Sqrt((item.Point.X - x) * (item.Point.X - x) + (item.Point.Y - y) * (item.Point.Y - y)); if (refdistance == 0 || Math.Abs(refdistance) < (1e-3)) { isbreak = true; break; } } if (isbreak) break; isContains = false; break; } } if (isContains) { IPointCollection points = geometry as IPointCollection; var index = -1; for (int i = 0; i < points.PointCount - 1; i++) { IPoint tPoint = points.Point[i]; var refdistance = Math.Sqrt((point.X - tPoint.X) * (point.X - tPoint.X) + (point.Y - tPoint.Y) * (point.Y - tPoint.Y)); if (refdistance == 0 || Math.Abs(refdistance) < (1e-5)) { index = i; break; } } if (index > -1) { points.RemovePoints(index, 1); continue; } } if (Listpoint.Count > 1) { if (Listpoint.FirstOrDefault(x => x.FootPoint == false) != null) { for (int i = 0; i < Listpoint.Count; i++) { if (Listpoint[i].FootPoint == true) { Listpoint.RemoveAt(i); i = 0; continue; } } } //多个相近的参考点在不同的参考图形上,根据距离最近的取参考点 if (ReferenceLayer.Count > 1) { double mindistance = -1; var index = -1; for (int i = 0; i < Listpoint.Count; i++) { double refdistance = Math.Sqrt((point.X - Listpoint[i].Point.X) * (point.X - Listpoint[i].Point.X) + (point.Y - Listpoint[i].Point.Y) * (point.Y - Listpoint[i].Point.Y)); if (mindistance == -1) { mindistance = refdistance; index = i; } else if (refdistance < mindistance) { mindistance = refdistance; index = i; } } if (index != -1) { moveToPoint = Listpoint[index].Point; Listpoint.RemoveAt(index); } } else { #region 出现多个相近的点 var nearUpdatePoint = Listpoint.OrderBy(n => Math.Abs(n.angle - pointangle)).FirstOrDefault(); moveToPoint = nearUpdatePoint.Point; #endregion } } else if (Listpoint.Count == 1) { //if (Listpoint[0].FootPoint) //{ // IPolyline polyline = new PolylineClass(); // try // { // double refdistance = Math.Sqrt((point.X - Listpoint[0].Point.X) * (point.X - Listpoint[0].Point.X) + (point.Y - Listpoint[0].Point.Y) * (point.Y - Listpoint[0].Point.Y)); // if (Math.Abs(refdistance) < (1e-5)) // { // continue; // } // polyline.SpatialReference = geometry.SpatialReference; // polyline.FromPoint = point; // polyline.ToPoint = Listpoint[0].Point; // polyline = getExtendLine(polyline, 2, 1); // if (FeatureAPI.IsInterSect(geometry, polyline)) // { // //List Cutgeometries = FeatureAPI.CutGeometry(geometry, polyline); // //if (Cutgeometries != null && Cutgeometries.Count > 1) // //{ // // bool isbreak = false; // // foreach (var item in Cutgeometries) // // { // // if (item.IsEmpty || item.GetEllipseArea() == 0) // // { // // isbreak = true; break; // // } // // } // // if (!isbreak) // // continue; // //} // } // } // catch (Exception ex) { } // finally // { // if (polyline != null) // Marshal.ReleaseComObject(polyline); // } //} moveToPoint = Listpoint[0].Point; Listpoint.RemoveAt(0); } } if (moveToPoint != null) { IPointCollection points = geometry as IPointCollection; var index = -1; for (int i = 0; i < points.PointCount - 1; i++) { IPoint tPoint = points.Point[i]; var refdistance = Math.Sqrt((point.X - tPoint.X) * (point.X - tPoint.X) + (point.Y - tPoint.Y) * (point.Y - tPoint.Y)); if (refdistance == 0 || Math.Abs(refdistance) < (1e-5)) { index = i; break; } } if (index > -1) { var refdistance = Math.Sqrt((point.X - moveToPoint.X) * (point.X - moveToPoint.X) + (point.Y - moveToPoint.Y) * (point.Y - moveToPoint.Y)); if (refdistance == 0) continue; points.UpdatePoint(index, moveToPoint); listmoveToPoint.Add($"{moveToPoint.X},{moveToPoint.Y}"); } } } } catch (Exception ex) { return null; } return geometry; } #endregion #region Passive_Sharp_Repair /// /// 构成尖锐角较短的边与较长的边做垂线,构成一个直角三角形,将直角三角形擦除 /// /// /// /// /// private static IGeometry Passive_Sharp_Repair(List pointList, IGeometry bg_geometry, IGeometry diffgeo) { List 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 points1 = new List() { 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 /// /// 获取图形中的所有节点 /// /// /// private static List GetMultipleRingPoints(IGeometry geometry) { List dicOPnts = new List(); 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 /// /// 获取尖锐角顶点位置外扩一段距离的垂线 /// /// /// clockwise顺时针 true为顺时针/false为逆时针 /// 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 GetSnappingpoint2(IPoint point, List m_featureLayer, List listmoveToPoint = null, double distance = 1) { List pointList = new List(); 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 解决狭长图形问题 /// /// 解决狭长图形问题 /// /// /// private static IGeometry ResolveLongAndNarrow(IGeometry geometry) { List 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 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; } /// /// 获取最小角度 /// /// /// private static double GetMinAngle(IGeometry pGeo, ref List pointlist) { double result = -1; IPolygon4 poly4 = null; ITopologicalOperator topo = null; GeometryBag geoBag = null; IGeometryCollection geoCollection = null; pointlist = new List(); 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 rings = new List(); 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; } /// /// 计算角度 /// /// /// /// /// 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 /// /// 获取当前点与前后两个点之间的夹角的角度 /// /// /// /// 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 ListReference { get; set; } public string DKID { get; set; } } }