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

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; }
}
}