森林草原湿地荒漠调查
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.
 
 
 

1193 lines
64 KiB

using ESRI.ArcGIS.Geometry;
using KGIS.Framework.AE;
using KGIS.Framework.AE.GPHelper;
using KGIS.Framework.Utils;
using KGIS.Framework.Utils.ExtensionMethod;
using Kingo.Plugin.EngineEditor.Model;
using Kingo.PluginServiceInterface;
using Kingo.PluginServiceInterface.Helper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Kingo.Plugin.EngineEditor.helper
{
public static class BoundaryRepairHelper
{
public static IProjectedCoordinateSystem _SpatialReference { get; set; }
public static void Execute(List<RepairEntity> repairs, List<int> UnionList)
{
List<ReferenceEntity> ListDLTB = new List<ReferenceEntity>();//年末数据库
List<RepairEntity> RepairLayerZDK = new List<RepairEntity>();//边界修复多部件图斑新增的子地块
try
{
#region 生成年末库
for (int i = repairs.Count - 1; i >= 0; i--)
{
if (repairs[i].Geometry == null) repairs[i].Geometry = ConvertWKTAndSetSpatialRef(repairs[i].WKT, _SpatialReference);
foreach (var item in repairs[i].ListReference)
{
ReferenceEntity dLTB_NMK = ListDLTB.FirstOrDefault(x => x.BSM == item.BSM);
if (dLTB_NMK == null)
{
ReferenceEntity dLTB = DeepCopyByReflect(item);
dLTB.RefGeometry = ConvertWKTAndSetSpatialRef(dLTB.RefWKT ?? GeometryConvertHelper.ConvertIGeoemtryToWKT(item.RefGeometry), _SpatialReference);
ListDLTB.Add(dLTB);
}
}
}
#endregion
#region 面积小于30平的,直接和相邻共边最长的图形合并,合并一整个子地块,再进行边界修复
for (int i = repairs.Count - 1; i >= 0; i--)
{
string dlbm = repairs[i].DLBM;
if (repairs[i].Geometry == null) repairs[i].Geometry = ConvertWKTAndSetSpatialRef(repairs[i].WKT, _SpatialReference);
if (repairs[i].Geometry == null || repairs[i].Geometry.IsEmpty) continue;
if ((repairs[i].Geometry as IArea).Area < 30)
{
RepairEntity UnionZDK = null;
double Unionlength = 0.00;
foreach (RepairEntity currentZDK in repairs)
{
if (currentZDK.JCBH == repairs[i].JCBH) continue;
if (currentZDK.Geometry == null) currentZDK.Geometry = ConvertWKTAndSetSpatialRef(currentZDK.WKT, _SpatialReference);
if (currentZDK.Geometry == null || currentZDK.Geometry.IsEmpty) continue;
ITopologicalOperator topologicalOperator1 = currentZDK.Geometry as ITopologicalOperator;
if (topologicalOperator1 == null) continue;
IGeometry geometryIntersect = topologicalOperator1.Intersect(repairs[i].Geometry, esriGeometryDimension.esriGeometry1Dimension);
if (geometryIntersect == null || geometryIntersect.IsEmpty) continue;
IPolyline polyline = geometryIntersect as IPolyline;
if (polyline == null || polyline.IsEmpty) continue;
double length = FeatureAPI.LengthOfSide(currentZDK.Geometry, repairs[i].Geometry);
if (length < 0.01) continue;
if (length > Unionlength)
{
Unionlength = length;
UnionZDK = currentZDK;
}
}
if (UnionZDK != null)
{
UnionZDK.Geometry = FeatureAPI.Union(UnionZDK.Geometry, repairs[i].Geometry);
UnionZDK.WKT = GeometryConvertHelper.ConvertIGeoemtryToWKT(UnionZDK.Geometry);
UnionList.Add(repairs[i].OID);
repairs.RemoveAt(i);
}
}
}
#endregion
foreach (RepairEntity repair in repairs)
{
// 预存DLTB的Envelope(仅SHAPE非空的图斑)
var dltbEnvelopes = ListDLTB.Where(jc => !string.IsNullOrEmpty(jc.RefWKT))
.Select(jc => new
{
DLTB = jc,
Envelope = (jc.RefGeometry?.Envelope ?? ConvertWKTAndSetSpatialRef(jc.RefWKT, _SpatialReference).Envelope)
}).ToList();
var candidateDLTBs = dltbEnvelopes.Where(item => AreEnvelopesIntersecting(repair.Geometry.Envelope, item.Envelope)).Select(item => item.DLTB).ToList();
foreach (ReferenceEntity jcfeature in candidateDLTBs)
{
if (string.IsNullOrEmpty(jcfeature.RefWKT)) continue;//图形为空的不参与后续图形的修复
IGeometry jcgeometry = jcfeature.RefGeometry == null ? ConvertWKTAndSetSpatialRef(jcfeature.RefWKT, _SpatialReference) : jcfeature.RefGeometry;
if (FeatureAPI.IsInterSect(jcgeometry, repair.Geometry))
repair.ListReference.Add(new ReferenceEntity()
{
BSM = jcfeature.BSM,
DLBM = jcfeature.DLBM,
CZCSXM = jcfeature.CZCSXM,
RefWKT = jcfeature.RefWKT,
RefGeometry = jcgeometry
});
}
List<ReferenceEntity> entities = ExecuteRepair(repair);
if (entities == null || entities.Count <= 0)
{
continue;
}
AddResultToAnalysisLayer(entities, ListDLTB, repairs, repair, RepairLayerZDK);
}
if (RepairLayerZDK != null && RepairLayerZDK.Count > 0)
{
foreach (RepairEntity item in RepairLayerZDK)
{
repairs.Add(item);
}
}
}
catch (Exception ex)
{
throw;
}
}
public static List<ReferenceEntity> ExecuteRepair(RepairEntity repair)
{
List<ReferenceEntity> needAddReference = new List<ReferenceEntity>();
List<ReferenceEntity> jrjReference = new List<ReferenceEntity>();
try
{
if (repair == null) return null;
#region 删除图形中的重复点(首位点除外)
IGeometryCollection geomColl = repair.Geometry as IGeometryCollection;
// 遍历所有子环(外环和内环)
for (int i = 0; i < geomColl.GeometryCount; i++)
{
IGeometry subGeom = geomColl.get_Geometry(i);
IRing ring = subGeom as IRing; // 环是闭合的线(IRing 继承自 IPolyline)
if (ring == null) continue;
// 处理当前环的重复点
RemoveDuplicatePointsInRing(ring);
}
#endregion
#region 节点套合
#region 获取待修复图形的外接矩形并向外缓冲
IEnvelope geometryEnvelope = repair.Geometry.Envelope;
double xMin = geometryEnvelope.XMin;
double yMin = geometryEnvelope.YMin;
double xMax = geometryEnvelope.XMax;
double yMax = geometryEnvelope.YMax;
IPoint lowerLeft = new PointClass();
lowerLeft.PutCoords(xMin, yMin);
IPoint lowerRight = new PointClass();
lowerRight.PutCoords(xMax, yMin);
IPoint upperRight = new PointClass();
upperRight.PutCoords(xMin, yMax);
IPoint upperLeft = new PointClass();
upperLeft.PutCoords(xMax, yMax);
IPolygon triangle = new PolygonClass();
IPointCollection trianglePoints = triangle as IPointCollection;
trianglePoints.AddPoint(lowerLeft);
trianglePoints.AddPoint(lowerRight);
trianglePoints.AddPoint(upperLeft);
trianglePoints.AddPoint(upperRight);
ITopologicalOperator topo = triangle as ITopologicalOperator;
topo.Simplify();
IGeometry geometry = topo.Buffer(2);
#endregion
List<IGeometry> geometries = new List<IGeometry>();
foreach (var item in repair.ListReference)
{
#region 获取变更图斑的外接矩形,向外缓冲 然后与基础库相交
IGeometry geo = FeatureAPI.InterSect(geometry, item.RefGeometry);
if (geo != null && !geo.IsEmpty)
{
double area = (geo as IArea).Area;
if (area > 0.1)
{
geometries.Add(geo);
}
}
#endregion
}
repair.Geometry = PolygonBoundaryAligner.AlignPolygonBoundary(repair.Geometry, geometries, 0.1);
#endregion
#region 尖锐角检查与修复
List<IPoint> yspointList = null;
double ysangle = 0;
IGeometry restSharpGeo = null;
if (!repair.Geometry.IsEmpty && SharpAngle.JudgmentSharpAngle(repair.Geometry, ref yspointList, ref ysangle))
{
IGeometry repairGeo = SharpAngle.ProcessSharpAngles(repair.Geometry, 5);
repairGeo.SpatialReference = _SpatialReference;
restSharpGeo = FeatureAPI.Difference(repair.Geometry, repairGeo);
repair.Geometry = repairGeo;
if (restSharpGeo != null && !restSharpGeo.IsEmpty)
{
var area = (restSharpGeo as IArea);
if (area != null && area.Area > 1)
{
List<IGeometry> geometryList = FeatureAPI.DissolveGeometryByRing(restSharpGeo);//拆分多部件
foreach (IGeometry SharpGeo in geometryList)
{
if (SharpGeo == null || SharpGeo.IsEmpty) continue;
ReferenceEntity referenceEntity = new ReferenceEntity();
referenceEntity.BSM = $"NMK_{repair.JCBH}_{Guid.NewGuid().ToTrim().Replace("-", "")}_SharpAngle";
referenceEntity.CZCSXM = repair.CZCSXM;
referenceEntity.DLBM = repair.DLBM;
referenceEntity.RefWKT = PluginServiceInterface.GeometryConvertHelper.ConvertIGeoemtryToWKT(SharpGeo);
referenceEntity.RefGeometry = SharpGeo;
referenceEntity.Modify = true;
jrjReference.Add(referenceEntity);
}
}
}
}
#endregion
#region 狭长/局部狭长检查与修复
if (!repair.Geometry.IsEmpty)
{
var NarrowAreas = PolygonNarrowAreaChecker.CheckLocalNarrowAreas(repair.Geometry as IPolygon);
if (NarrowAreas != null && NarrowAreas.Count > 0)
{
foreach (var item in NarrowAreas)
{
if (!FeatureAPI.IsInterSect(item, repair.Geometry))
{
repair.Geometry = FeatureAPI.Union(repair.Geometry, item);
}
else
{
repair.Geometry = FeatureAPI.Difference(repair.Geometry, item);
}
}
}
}
#endregion
//尖锐角/狭长图形修复完以后,图形为空直接返回,删除当前子地块
if (repair.Geometry.IsEmpty) return repair.ListReference;
#region 压盖带一个参考图形
if (repair.ListReference != null && repair.ListReference.Count == 1)
{
ReferenceEntity jcdltb = repair.ListReference[0];
#region 面积相差小于1的 直接使用基础库图形
var refmj = (jcdltb.RefGeometry as IArea).Area;
var geomj = (repair.Geometry as IArea).Area;
if (refmj == geomj || Math.Abs(refmj - geomj) < 1)
{
repair.ListReference.Add(
new ReferenceEntity()
{
BSM = $"NMK_{repair.JCBH}",
CZCSXM = repair.CZCSXM,
DLBM = repair.DLBM,
RefWKT = jcdltb.RefWKT,
Modify = true
});
jcdltb.Modify = true;
jcdltb.RefWKT = "";
jcdltb.RefGeometry = null;
return repair.ListReference;
}
#endregion
#region 图形在基础数据内部 且被动变更图斑不存在尖锐角/狭长图形
IGeometry diffGeo = FeatureAPI.Difference(jcdltb.RefGeometry, repair.Geometry);
List<IGeometry> geos = FeatureAPI.DissolveGeometryByRing(diffGeo);
if (geos != null && geos.Count > 0)
{
bool iscontinue = true;
foreach (IGeometry diff in geos)
{
if (diff == null || diff.IsEmpty) continue;
double area = (diff as IArea).Area;
if (area < 1)
{
iscontinue = false; break;
}
if (SharpAngle.JudgmentSharpAngle(diff, ref yspointList, ref ysangle))
{
iscontinue = false; break;
}
List<IPolygon> NarrowAreas = PolygonNarrowAreaChecker.CheckLocalNarrowAreas(diff as IPolygon);
if (NarrowAreas != null && NarrowAreas.Count > 0)
{
iscontinue = false; break;
}
}
if (iscontinue)
{
if (geos.Count == 1)
{
jcdltb.RefWKT = GeometryConvertHelper.ConvertIGeoemtryToWKT(geos[0]);
jcdltb.RefGeometry = geos[0];
jcdltb.Modify = true;
}
else
{
IGeometry difference = FeatureAPI.Difference(jcdltb.RefGeometry, repair.Geometry);
if (difference != null && !difference.IsEmpty)
{
jcdltb.RefWKT = GeometryConvertHelper.ConvertIGeoemtryToWKT(difference);
jcdltb.RefGeometry = difference;
jcdltb.Modify = true;
}
}
repair.ListReference.Add(
new ReferenceEntity()
{
BSM = $"NMK_{repair.JCBH}",
CZCSXM = repair.CZCSXM,
DLBM = repair.DLBM,
RefWKT = GeometryConvertHelper.ConvertIGeoemtryToWKT(repair.Geometry),
Modify = true
});
if (jrjReference.Count > 0)
{
foreach (ReferenceEntity item in repair.ListReference.FindAll(x => x.Modify && !x.BSM.Contains("NMK_")))
{
if (item.RefGeometry == null || item.RefGeometry.IsEmpty) continue;
item.RefGeometry = FeatureAPI.Difference(item.RefGeometry, restSharpGeo);
if (item.RefGeometry == null || item.RefGeometry.IsEmpty) continue;
item.RefWKT = GeometryConvertHelper.ConvertIGeoemtryToWKT(item.RefGeometry);
}
repair.ListReference.AddRange(jrjReference);
}
return repair.ListReference;
}
}
#endregion
if (repair.ListReference != null && repair.ListReference.Count >= 1)
{
foreach (ReferenceEntity jcfc in repair.ListReference)
{
#region 与基础库相交
if (repair.Geometry.IsEmpty) break;
IGeometry InterArearesult = FeatureAPI.InterSect(jcfc.RefGeometry, repair.Geometry);
if (InterArearesult != null)
{
if (InterArearesult == null || InterArearesult.IsEmpty) continue;//未相交到或相交为空图形的直接跳过
double area = (InterArearesult as IArea).Area;
if (area < 1)//相交面积小于1的图形擦除
{
//if (!string.IsNullOrEmpty(repair.DLBM) && XZDW_List.Contains(repair.DLBM))
//{
// jcfc.IsReference = true; continue;
//}
IGeometry result = FeatureAPI.Difference(repair.Geometry, InterArearesult);
if (result != null && !result.IsEmpty)
{
repair.Geometry = result; continue;
}
}
else if (area > 1 && area < 10)
{
//if (!string.IsNullOrEmpty(repair.DLBM) && XZDW_List.Contains(repair.DLBM))
//{
// jcfc.IsReference = true; continue;
//}
//相交面积小于10且相交图形为尖锐角或者狭长图形的擦除
if (SharpAngle.JudgmentSharpAngle(InterArearesult, ref yspointList, ref ysangle))
{
IGeometry result = FeatureAPI.Difference(repair.Geometry, InterArearesult);
if (result != null && !result.IsEmpty)
repair.Geometry = result; continue;
}
else
{
jcfc.IsReference = true; continue;
}
}
else
{
//参与图形修复的基础库
jcfc.IsReference = true;
continue;
}
}
#endregion
}
}
else
{
return repair.ListReference;
}
}
#endregion
if (repair.ListReference != null && repair.ListReference.Count >= 1)
{
foreach (ReferenceEntity jcfc in repair.ListReference)
{
#region 与基础库相交
if (repair.Geometry.IsEmpty) break;
IGeometry InterArearesult = FeatureAPI.InterSect(jcfc.RefGeometry, repair.Geometry);
if (InterArearesult != null)
{
if (InterArearesult == null || InterArearesult.IsEmpty) continue;//未相交到或相交为空图形的直接跳过
double area = (InterArearesult as IArea).Area;
if (area < 1)//相交面积小于1的图形擦除
{
//if (!string.IsNullOrEmpty(repair.DLBM) && XZDW_List.Contains(repair.DLBM))
//{
// jcfc.IsReference = true; continue;
//}
IGeometry result = FeatureAPI.Difference(repair.Geometry, InterArearesult);
if (result != null && !result.IsEmpty)
{
repair.Geometry = result; continue;
}
}
else if (area > 1 && area < 10)
{
//if (!string.IsNullOrEmpty(repair.DLBM) && XZDW_List.Contains(repair.DLBM))
//{
// jcfc.IsReference = true; continue;
//}
//相交面积小于10且相交图形为尖锐角或者狭长图形的擦除
if (SharpAngle.JudgmentSharpAngle(InterArearesult, ref yspointList, ref ysangle))
{
IGeometry result = FeatureAPI.Difference(repair.Geometry, InterArearesult);
if (result != null && !result.IsEmpty)
repair.Geometry = result; continue;
}
else
{
jcfc.IsReference = true; continue;
}
}
else
{
//参与图形修复的基础库
jcfc.IsReference = true;
continue;
}
}
#endregion
if (!jcfc.IsReference) continue;
#region 与基础库不相交的面积
IGeometry diffresult = FeatureAPI.Difference(jcfc.RefGeometry, repair.Geometry);
if (diffresult != null && !diffresult.IsEmpty)
{
List<IPoint> pointList1 = null;
double angle = 0;
double area = (diffresult as IArea).Area;
if (area < 1)//未相交面积小于1的图形合并
{
if (FeatureAPI.IsAdjacent(repair.Geometry, diffresult))
{
//if (!string.IsNullOrEmpty(repair.DLBM) && XZDW_List.Contains(repair.DLBM)) continue;//线状地物不与碎图斑合并
IGeometry unionresult = FeatureAPI.Union(repair.Geometry, diffresult);
if (unionresult != null && !unionresult.IsEmpty)
{
repair.Geometry = unionresult;
}
}
}
else if (area < 10 && AECommonHelper.SharpAngleDataCheck(diffresult, ref pointList1, ref angle))
{
//if (!string.IsNullOrEmpty(repair.DLBM) && XZDW_List.Contains(repair.DLBM)) continue;//线状地物不与碎图斑合并
if (FeatureAPI.IsAdjacent(repair.Geometry, diffresult))
{
IGeometry unionresult = FeatureAPI.Union(repair.Geometry, diffresult);
if (unionresult != null && unionresult != null)
{
repair.Geometry = unionresult;
}
}
}
else
{
#region 被动变更小于30平且相邻的图斑与当前图斑合并
//小于30平的合并问题还需要验证
if (area < 30)
{
//if (!string.IsNullOrEmpty(repair.DLBM) && XZDW_List.Contains(repair.DLBM)) continue;//线状地物不与碎图斑合并
if (FeatureAPI.IsAdjacent(repair.Geometry, diffresult))
{
IGeometry unionresult = FeatureAPI.Union(repair.Geometry, diffresult);
if (unionresult != null && unionresult != null)
{
repair.Geometry = unionresult;
}
}
}
#endregion
}
}
#endregion
}
if (repair.Geometry.IsEmpty) return repair.ListReference;
if (repair.ListReference.Where(x => x.IsReference).ToList().Count == 1)
{
ReferenceEntity jcdltb = repair.ListReference.Where(x => x.IsReference).ToList().FirstOrDefault();
#region 压盖带一个参考图形
#region 面积相差小于1的 直接使用基础库图形
jcdltb.EllipseArea = (jcdltb.RefGeometry as IArea).Area;
var geomj = (repair.Geometry as IArea).Area;
if (jcdltb.EllipseArea == geomj || Math.Abs(jcdltb.EllipseArea - geomj) < 1)
{
//基础数据库存在多部件,且面积较小的图形,删掉对应的碎图斑
string RefWKT = jcdltb.RefWKT;
jcdltb.RefWKT = "";
jcdltb.Modify = true;
jcdltb.RefGeometry = null;
repair.ListReference.Add(new ReferenceEntity()
{
BSM = $"NMK_{repair.JCBH}",
CZCSXM = repair.CZCSXM,
DLBM = repair.DLBM,
RefWKT = RefWKT,
Modify = true
//IsNeedAddNewZDK = false
});
return repair.ListReference;
}
#endregion
#region 图形在基础数据内部 且被动变更图斑不存在尖锐角/狭长图形
bool iscontinue = true;
IGeometry diffresult = FeatureAPI.Difference(jcdltb.RefGeometry, repair.Geometry);
if (diffresult != null && !diffresult.IsEmpty)
{
List<IPoint> pointList = null;
double angle = 0;
if (SharpAngle.JudgmentSharpAngle(diffresult, ref pointList, ref angle) || PolygonNarrowAreaChecker.CheckLocalNarrowAreas(diffresult as IPolygon).Count > 0)
{
iscontinue = false;
}
foreach (var item in repair.ListReference)
{
if (item.BSM == jcdltb.BSM) continue;
if (FeatureAPI.IsInterSect(item.RefGeometry, diffresult))
{
iscontinue = false; break;
}
}
if (iscontinue)
{
//Difference 擦除的结果与修复后的repair.Geometry 存在误差范围内的差别
//repair.Geometry = FeatureAPI.Difference(jcdltb.RefGeometry, Difference);
#region 出现多部件的图形,需要进行节点修复逻辑
List<IGeometry> geometryList = FeatureAPI.DissolveGeometryByRing(repair.Geometry);//拆分多部件
if (geometryList.Count > 1)
{
LogAPI.Debug($"jcbh:{repair.JCBH},的图斑,BoundaryRepairHelper.ExecuteRepair方法中的 出现多部件的图形,需要进行节点修复逻辑,geometryList.Count > 1的相关逻辑暂未处理 ! ");
}
else
{
if (diffresult.IsEmpty)
{
jcdltb.RefWKT = "";
jcdltb.RefGeometry = null;
}
else
{
jcdltb.RefWKT = GeometryConvertHelper.ConvertIGeoemtryToWKT(diffresult);
jcdltb.RefGeometry = diffresult;
}
jcdltb.Modify = true;
repair.ListReference.Add(new ReferenceEntity()
{
BSM = $"NMK_{repair.JCBH}",
CZCSXM = repair.CZCSXM,
DLBM = repair.DLBM,
RefWKT = GeometryConvertHelper.ConvertIGeoemtryToWKT(repair.Geometry),
Modify = true,
//Describe = "图形修复:"
});
if (jrjReference.Count > 0)
{
foreach (var item in repair.ListReference.FindAll(x => x.Modify && !x.BSM.Contains("NMK_")))
{
if (item.RefGeometry == null || item.RefGeometry.IsEmpty) continue;
item.RefGeometry = FeatureAPI.Difference(item.RefGeometry, restSharpGeo);
if (item.RefGeometry == null || item.RefGeometry.IsEmpty) continue;
item.RefWKT = GeometryConvertHelper.ConvertIGeoemtryToWKT(item.RefGeometry);
}
repair.ListReference.AddRange(jrjReference);
}
return repair.ListReference;
}
#endregion
}
}
#endregion
#endregion
}
#region 没有参考基础库
if (repair.ListReference.Where(x => x.IsReference).ToList().Count == 0) return repair.ListReference;
#endregion
geometries.Clear();
foreach (var item in repair.ListReference)
{
if (!item.IsReference) continue;
geometries.Add(item.RefGeometry);
}
List<IGeometry> geometrys = ExecuteBoundaryRepair(repair, geometries);
if (geometrys != null)
{
foreach (var item in geometrys)
{
if (item.IsEmpty || item as IArea == null || (item as IArea).Area == 0) continue;
foreach (ReferenceEntity jcdltb in repair.ListReference)
{
if (!jcdltb.IsReference) continue;
IGeometry diff = FeatureAPI.Difference(jcdltb.RefGeometry, item);
if (diff == null || diff.IsEmpty || (diff as IArea).Area == 0)
{
jcdltb.RefWKT = "";
jcdltb.RefGeometry = null;
jcdltb.Modify = true;
}
else
{
jcdltb.RefWKT = GeometryConvertHelper.ConvertIGeoemtryToWKT(diff);
jcdltb.RefGeometry = diff;
jcdltb.Modify = true;
}
}
ReferenceEntity referenceEntity = new ReferenceEntity
{
BSM = $"NMK_{repair.JCBH}",
CZCSXM = repair.CZCSXM,
DLBM = repair.DLBM,
RefWKT = GeometryConvertHelper.ConvertIGeoemtryToWKT(item),
RefGeometry = item,
Modify = true
};
if (repair.ListReference.FirstOrDefault(x => x.BSM == referenceEntity.BSM) != null)
{
referenceEntity.BSM = $"NMK_{repair.JCBH}_{Guid.NewGuid().ToTrim().Replace("-", "")}";
}
repair.ListReference.Add(referenceEntity);
}
}
}
else
{
return repair.ListReference;
}
if (jrjReference.Count > 0)
{
foreach (ReferenceEntity item in repair.ListReference.FindAll(x => x.Modify && !x.BSM.Contains("NMK_")))
{
if (item.RefGeometry == null || item.RefGeometry.IsEmpty) continue;
item.RefGeometry = FeatureAPI.Difference(item.RefGeometry, restSharpGeo);
if (item.RefGeometry == null || item.RefGeometry.IsEmpty) continue;
item.RefWKT = GeometryConvertHelper.ConvertIGeoemtryToWKT(item.RefGeometry);
}
repair.ListReference.AddRange(jrjReference);
}
}
catch (Exception ex)
{
LogAPI.Debug("执行边界修复失败:\r\n");
LogAPI.Debug(ex);
throw ex;
}
return repair.ListReference;
}
#region 节点去重
private static void RemoveDuplicatePointsInRing(IRing ring)
{
IPointCollection pointColl = ring as IPointCollection;
if (pointColl == null) return;
// 从第 1 个点开始(索引 1),向前比较(避免越界)
for (int i = 1; i < pointColl.PointCount;)
{
IPoint currentPoint = pointColl.get_Point(i);
IPoint prevPoint = pointColl.get_Point(i - 1);
// 检查坐标是否完全一致(X、Y、Z、M 均相等)
if (currentPoint.X == prevPoint.X && currentPoint.Y == prevPoint.Y)
{
// 删除当前重复点(删除后后续点索引前移,i 不递增)
pointColl.RemovePoints(i, 1);
}
else
{
i++; // 无重复,继续下一个点
}
}
// 重新闭合环(确保最后一个点与第一个点一致,避免几何无效)
ring.Close();
}
#endregion
private static List<IGeometry> ExecuteBoundaryRepair(RepairEntity repair, List<IGeometry> jcdltb_features)
{
List<IGeometry> ResultgeometryList = new List<IGeometry>();
List<IGeometry> geometryList = null;
List<IPoint> pointList = null;
double angle = 0;
try
{
if (IsMultipartGeometry(repair.Geometry))
{
#region 拆分多部件
List<IGeometry> Dissolves = FeatureAPI.DissolveGeometryByRing(repair.Geometry);
if (Dissolves != null && Dissolves.Count > 0)
{
for (int i = 0; i < Dissolves.Count; i++)
{
IGeometry single = Dissolves[i];
if (single == null || (single as IArea).Area == 0) continue;
#region 拆分多部件过后检查图形是否存在尖锐角/狭长
#region 尖锐角检查与修复
if (!single.IsEmpty && SharpAngle.JudgmentSharpAngle(single, ref pointList, ref angle))
{
single = SharpAngle.ProcessSharpAngles(single, 3);
single.SpatialReference = _SpatialReference;
}
#endregion
#region 狭长/局部狭长检查与修复
if (!single.IsEmpty)
{
var NarrowAreas = PolygonNarrowAreaChecker.CheckLocalNarrowAreas(single as IPolygon);
if (NarrowAreas != null && NarrowAreas.Count > 0)
{
LogAPI.Debug($"jcbh:{repair.JCBH}的图斑,BoundaryRepairHelper.ExecuteBoundaryRepair方法中的 狭长/局部狭长检查与修复,检查出来暂未处理 ! ");
}
}
#endregion
if (single.IsEmpty) continue;
#endregion
#region 判断当前图斑是否压盖多个图斑且存在碎图斑
foreach (IGeometry jcdltb in jcdltb_features)
{
#region 相交部分
IGeometry InterSect = FeatureAPI.InterSect(single, jcdltb);
List<IGeometry> InterSects = FeatureAPI.DissolveGeometryByRing(InterSect);
if (InterSects != null && InterSects.Count > 0)
{
foreach (IGeometry intersect in InterSects)
{
if (intersect == null || intersect.IsEmpty || (intersect as IArea).Area == 0) continue;
if ((intersect as IArea).Area < 1 || (SharpAngle.JudgmentSharpAngle(intersect, ref pointList, ref angle) && (intersect as IArea).Area < 10))
{
//if (!string.IsNullOrEmpty(repair.DLBM) && XZDW_List.Contains(repair.DLBM)) continue;//线状地物不与碎图斑合并
IGeometry Difference1 = FeatureAPI.Difference(single, intersect);
if (Difference1 != null && !Difference1.IsEmpty)
single = Difference1;
}
}
}
else
{
continue;
}
#endregion
#region 不相交部分
IGeometry Difference = FeatureAPI.Difference(jcdltb, single);
List<IGeometry> Differences = FeatureAPI.DissolveGeometryByRing(Difference);
if (Differences != null && Differences.Count > 0)
{
for (int j = 0; j < Differences.Count; j++)
{
IGeometry difference = Differences[j];
if (difference == null || difference.IsEmpty || (difference as IArea).Area == 0) continue;
//与基础库不相交的部分面积小于30平且相邻的情况下 合并
if (FeatureAPI.IsAdjacent(single, difference))
{
double area = (difference as IArea).Area;
if ((difference as IArea).Area < 10)
{
//if (!string.IsNullOrEmpty(repair.DLBM) && XZDW_List.Contains(repair.DLBM)) continue;//线状地物不与碎图斑合并
IGeometry unionresult = FeatureAPI.Union(single, difference);
if (unionresult != null && !unionresult.IsEmpty)
{
single = unionresult;
}
continue;
}
else if (area > 10 && area < 30)
{
ResultgeometryList.Add(single);
}
}
else
{
if (AECommonHelper.SharpAngleDataCheck(difference, ref pointList, ref angle))
{
if (angle > 10)//狭长图形
{
continue;
}
else
{
LogAPI.Debug($"jcbh:{repair.JCBH}的图斑,BoundaryRepairHelper.ExecuteBoundaryRepair方法中的 被动变更尖锐角处理 暂未处理 ! ");
#region 被动变更尖锐角处理
//geometry = Passive_Sharp_Repair(pointList, geometry, item);
#endregion
}
}
}
}
}
#endregion
}
#endregion
List<IGeometry> Dissolve = FeatureAPI.DissolveGeometryByRing(single);//拆分多部件
if (Dissolve != null && Dissolve.Count > 1)
{
foreach (IGeometry item in Dissolve)
{
ResultgeometryList.Add(item);
}
}
else
{
ResultgeometryList.Add(single);
}
}
}
#endregion
}
else
{
#region 拆分多部件过后检查图形是否存在尖锐角/狭长
#region 尖锐角检查与修复
if (!repair.Geometry.IsEmpty && SharpAngle.JudgmentSharpAngle(repair.Geometry, ref pointList, ref angle))
{
repair.Geometry = SharpAngle.ProcessSharpAngles(repair.Geometry, 3);
repair.Geometry.SpatialReference = _SpatialReference;
}
#endregion
#region 狭长/局部狭长检查与修复
if (!repair.Geometry.IsEmpty)
{
var NarrowAreas = PolygonNarrowAreaChecker.CheckLocalNarrowAreas(repair.Geometry as IPolygon);
if (NarrowAreas != null && NarrowAreas.Count > 0)
{
LogAPI.Debug($"jcbh:{repair.JCBH}的图斑,BoundaryRepairHelper.ExecuteBoundaryRepair方法中的 拆分多部件过后检查图形是否存在狭长,检查出来暂未处理 ! ");
}
}
#endregion
#endregion
#region 判断当前图斑是否压盖多个图斑且存在碎图斑
foreach (IGeometry jcdltb in jcdltb_features)
{
#region 相交部分
IGeometry InterSect = FeatureAPI.InterSect(repair.Geometry, jcdltb);
List<IGeometry> InterSects = FeatureAPI.DissolveGeometryByRing(InterSect);
if (InterSects != null && InterSects.Count > 0)
{
foreach (IGeometry intersect in InterSects)
{
//if (!string.IsNullOrEmpty(repair.DLBM) && XZDW_List.Contains(repair.DLBM)) continue;
if ((!intersect.IsEmpty && (intersect as IArea).Area < 1)/* || (SharpAngle.JudgmentSharpAngle(intersect.Geometry, ref pointList, ref angle) && intersect.mj < 10)*/)
{
IGeometry differenceresult1 = FeatureAPI.Difference(repair.Geometry, intersect);
if (differenceresult1 != null && !differenceresult1.IsEmpty)
repair.Geometry = differenceresult1;
}
}
}
#endregion
#region 不相交部分
IGeometry differenceresult = FeatureAPI.Difference(jcdltb, repair.Geometry);
List<IGeometry> differenceresults = FeatureAPI.DissolveGeometryByRing(differenceresult);
if (differenceresults != null && differenceresults.Count > 0)
{
foreach (IGeometry differenc in differenceresults)
{
if (differenc == null || differenc.IsEmpty)
{
continue;
}
double area = (differenc as IArea).Area;
if (area == 0) continue;
//与基础库不相交的部分面积小于30平且相邻的情况下 合并
if (FeatureAPI.IsAdjacent(repair.Geometry, differenc))
{
//线状地物不与碎图斑合并
//if (!string.IsNullOrEmpty(repair.DLBM) && XZDW_List.Contains(repair.DLBM)) continue;
if (area < 10)
{
IGeometry unionresult = FeatureAPI.Union(repair.Geometry, differenc);
if (unionresult != null && !unionresult.IsEmpty)
{
//假设合并之后为尖锐角或者狭长,就不合并
if (SharpAngle.JudgmentSharpAngle(unionresult, ref pointList, ref angle) || PolygonNarrowAreaChecker.CheckLocalNarrowAreas(unionresult as IPolygon).Count > 0)
{
continue;
}
repair.Geometry = unionresult;
continue;
}
}
else if (area > 10 && area < 30)
{
ResultgeometryList.Add(differenc);
}
//不相交部分,判定是否有尖锐角或者狭长图形,不相交部分的尖锐角或者狭长图形剩余部分合并给相邻的子地块
else if (SharpAngle.JudgmentSharpAngle(differenc, ref pointList, ref angle))
{
IGeometry repairGeo = SharpAngle.ProcessSharpAngles(differenc, 5);
repairGeo.SpatialReference = _SpatialReference;
IGeometry diffresult = FeatureAPI.Difference(differenc, repairGeo);
if (diffresult != null && !diffresult.IsEmpty)
{
double diffArea = (diffresult as IArea).Area;
if (diffArea > 0)
{
List<IGeometry> tempGeometryList = FeatureAPI.DissolveGeometryByRing(diffresult);//拆分多部件
foreach (IGeometry SharpGeo in tempGeometryList)
{
if (FeatureAPI.IsAdjacent(SharpGeo, repair.Geometry))
{
IGeometry unionresult = FeatureAPI.Union(repair.Geometry, SharpGeo);
if (unionresult != null && unionresult != null)
{
if (!SharpAngle.JudgmentSharpAngle(unionresult, ref pointList, ref angle) && PolygonNarrowAreaChecker.CheckLocalNarrowAreas(unionresult as IPolygon).Count <= 0)
{
repair.Geometry = unionresult;
}
}
}
}
}
}
}
else if (PolygonNarrowAreaChecker.CheckLocalNarrowAreas(differenc as IPolygon).Count > 0)
{
var NarrowAreas = PolygonNarrowAreaChecker.CheckLocalNarrowAreas(differenc as IPolygon);
if (NarrowAreas != null && NarrowAreas.Count > 0)
{
foreach (var item in NarrowAreas)
{
if (FeatureAPI.IsAdjacent(item, repair.Geometry))
{
IGeometry unionresult = FeatureAPI.Union(repair.Geometry, item);
if (!SharpAngle.JudgmentSharpAngle(unionresult, ref pointList, ref angle) && PolygonNarrowAreaChecker.CheckLocalNarrowAreas(unionresult as IPolygon).Count <= 0)
{
repair.Geometry = unionresult;
}
}
}
}
}
}
else
{
if (AECommonHelper.SharpAngleDataCheck(differenc, ref pointList, ref angle))
{
if (angle > 10)//狭长图形
{
continue;
}
else
{
LogAPI.Debug($"jcbh:{repair.JCBH}的图斑,BoundaryRepairHelper.ExecuteBoundaryRepair方法中的 不相交部分的被动变更尖锐角处理,检查出来暂未处理 ! ");
#region 被动变更尖锐角处理
//geometry = Passive_Sharp_Repair(pointList, geometry, item);
#endregion
}
}
}
}
}
#endregion
}
#endregion
List<IGeometry> Dissolve = FeatureAPI.DissolveGeometryByRing(repair.Geometry);
if (Dissolve != null && Dissolve.Count > 1)
{
foreach (var item in Dissolve)
{
if (item == null || item.IsEmpty || (item as IArea).Area < 0.01) continue;
ResultgeometryList.Add(item);
}
}
else
{
ResultgeometryList.Add(repair.Geometry);
}
}
}
catch (Exception ex)
{
ResultgeometryList = geometryList;
return ResultgeometryList;
}
return ResultgeometryList;
}
/// <summary>
/// 判断图形是否为多部件
/// </summary>
/// <param name="geometry"></param>
/// <returns></returns>
private static bool IsMultipartGeometry(IGeometry geometry)
{
// 检查是否为支持多部件的几何类型
if (geometry.GeometryType != esriGeometryType.esriGeometryPolygon &&
geometry.GeometryType != esriGeometryType.esriGeometryPolyline)
{
return false;
}
// 转换为IGeometryCollection接口
IGeometryCollection geometryCollection = geometry as IGeometryCollection;
if (geometryCollection == null)
{
return false;
}
// 判断部件数量
return geometryCollection.GeometryCount > 1;
}
/// <summary>
/// 处理边界修复后新增或修改的子地块
/// </summary>
/// <param name="entities">边界修复结果</param>
/// <param name="ListDLTB">年末数据库</param>
/// <param name="repairs">所有参与边界修复子地块</param>
/// <param name="repair">当前修复子地块</param>
/// <param name="RepairLayerZDK">边界修复多部件图斑新增的子地块</param>
private static void AddResultToAnalysisLayer(List<ReferenceEntity> entities, List<ReferenceEntity> ListDLTB, List<RepairEntity> repairs, RepairEntity repair, List<RepairEntity> RepairLayerZDK)
{
try
{
//所有他图形都没有被修改,删除当前子地块
if (entities.FirstOrDefault(x => x.Modify == true) == null)
{
//repair.JCBH = "-1";
repair.JCBH = $"{repair.JCBH}_DELETE";
return;
}
entities = entities.OrderBy(x => x.BSM.Contains("_New")).ToList();
bool isadd = false;//判断是否需要新增子地块
foreach (var item in entities)
{
if (!item.Modify) continue;
var dltb = ListDLTB.FirstOrDefault(x => x.BSM == item.BSM);
if (dltb != null)
{
if (dltb.BSM.StartsWith("NMK"))
{
string dkid = dltb.BSM.Split('_')[2];
var updatezdk = repairs.FirstOrDefault(x => x.JCBH.ToTrim().Replace("-", "") == dkid);
if (updatezdk != null) updatezdk.WKT = item.RefWKT;
}
dltb.RefWKT = item.RefWKT;
dltb.RefGeometry = item.RefGeometry;
}
else
{
var exist = ListDLTB.FirstOrDefault(x => x.RefWKT == item.RefWKT);
if (exist != null && !item.BSM.StartsWith("NMK_")) continue;
ListDLTB.Add(new ReferenceEntity()
{
#region 属性值
BSM = item.BSM,
CZCSXM = item.CZCSXM,
RefWKT = item.RefWKT,
RefGeometry = item.RefGeometry,
DLBM = item.DLBM,
IsReference = true,
oid = item.oid
#endregion
});
if (!isadd)
{
repair.WKT = item.RefWKT;
repair.Geometry = item.RefGeometry;
isadd = true;
//只修改后续有相交子地块,先擦除掉因此子地块修改后造成的相交部分,便于点修复时的修改
for (int i = repairs.Count - 1; i >= 0; i--)
{
if (repairs[i].JCBH == repair.JCBH) break;
IGeometry otherZDKGeo = repairs[i].Geometry == null ? ConvertWKTAndSetSpatialRef(repairs[i].WKT, _SpatialReference) : repairs[i].Geometry;
if (FeatureAPI.IsInterSect(repair.Geometry, otherZDKGeo))
{
IGeometry geo = FeatureAPI.InterSect(repair.Geometry, otherZDKGeo);
if (geo != null)
{
IGeometry diffGeo = FeatureAPI.Difference(otherZDKGeo, geo);
if (diffGeo != null && !diffGeo.IsEmpty)
{
repairs[i].Geometry = diffGeo;
repairs[i].WKT = GeometryConvertHelper.ConvertIGeoemtryToWKT(diffGeo);
}
}
}
}
}
else
{
RepairEntity zDK = new RepairEntity();
zDK.WKT = item.RefWKT;
zDK.CZCSXM = repair.CZCSXM;
zDK.DLBM = repair.DLBM;
if (item.BSM.Contains("_SharpAngle") || item.BSM.Contains("_New"))
{
zDK.JCBH = item.BSM;
}
else
{
zDK.JCBH = Guid.NewGuid().ToTrim().Replace("-", "");
}
RepairLayerZDK.Add(zDK);
}
}
}
}
catch (Exception ex)
{
throw;
}
}
private static IGeometry ConvertWKTAndSetSpatialRef(string wkt, ISpatialReference spatialRef)
{
var geometry = GeometryConvertHelper.ConvertWKTToIGeometry(wkt);
geometry.SpatialReference = spatialRef;
return geometry;
}
/// <summary>
/// 判断两个包围盒是否相交
/// </summary>
/// <param name="envA">包围盒A</param>
/// <param name="envB">包围盒B</param>
/// <returns>true-相交;false-不相交</returns>
private static bool AreEnvelopesIntersecting(IEnvelope envA, IEnvelope envB)
{
// 任一包围盒为空时,视为不相交
if (envA == null || envB == null || envA.IsEmpty || envB.IsEmpty)
return false;
// X轴投影不重叠
if (envA.XMin >= envB.XMax || envA.XMax <= envB.XMin)
return false;
// Y轴投影不重叠
if (envA.YMin >= envB.YMax || envA.YMax <= envB.YMin)
return false;
// X和Y轴均重叠,包围盒相交
return true;
}
private static T DeepCopyByReflect<T>(T obj)
{
//如果是字符串或值类型则直接返回
if (obj == null || (obj is string) || obj.GetType().IsValueType) return obj;
object retval = System.Activator.CreateInstance(obj.GetType());
System.Reflection.FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
foreach (System.Reflection.FieldInfo field in fields)
{
try { field.SetValue(retval, DeepCopyByReflect(field.GetValue(obj))); }
catch { }
}
return (T)retval;
}
}
}