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