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.
1957 lines
97 KiB
1957 lines
97 KiB
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 |
|
{ |
|
/// <summary> |
|
/// 边界修复 |
|
/// </summary> |
|
public static class BoundaryRepairHelper |
|
{ |
|
/// <summary> |
|
/// 执行边界套合修复逻辑 |
|
/// </summary> |
|
/// <param name="geometry">待修复的图斑</param> |
|
/// <param name="RepairLayer">修复图层</param> |
|
/// <param name="ReferenceLayer">参考图层</param> |
|
/// <returns></returns> |
|
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<IPoint> 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<MovePointStruct> 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<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(); |
|
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; |
|
} |
|
|
|
/// <summary> |
|
/// 执行边界套合修复逻辑 |
|
/// </summary> |
|
/// <param name="geometry">待修复的图斑</param> |
|
/// <param name="RepairLayer">修复图层</param> |
|
/// <param name="ReferenceLayer">参考图层</param> |
|
/// <returns></returns> |
|
public static IGeometry ExecuteBoundaryRepair1(IGeometry geometry, IFeatureLayer RepairLayer, IFeatureLayer ReferenceLayer, double distance) |
|
{ |
|
try |
|
{ |
|
List<IFeature> 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<IPoint> RepairdPoint = new List<IPoint>();//已修复的点 |
|
for (int p = 0; p < geometryCollection.GeometryCount; p++) |
|
{ |
|
insidegeo = geometryCollection.get_Geometry(p); |
|
List<IPoint> 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<MovePointStruct> 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<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(); |
|
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; |
|
} |
|
/// <summary> |
|
/// 执行边界套合修复逻辑 |
|
/// </summary> |
|
/// <param name="geometry">待修复的图斑</param> |
|
/// <param name="RepairLayer">修复图层</param> |
|
/// <param name="ReferenceLayer">参考图层</param> |
|
/// <returns></returns> |
|
public static IGeometry ExecuteBoundaryRepair2(IGeometry geometry, List<IGeometry> RepairLayer, List<IGeometry> ReferenceLayer, double distance) |
|
{ |
|
try |
|
{ |
|
IGeometryCollection geometryCollection = geometry as IGeometryCollection; |
|
IGeometry insidegeo = null; |
|
ISegmentCollection final = new PolygonClass(); |
|
List<IPoint> RepairdPoint = new List<IPoint>();//已修复的点 |
|
for (int p = 0; p < geometryCollection.GeometryCount; p++) |
|
{ |
|
insidegeo = geometryCollection.get_Geometry(p); |
|
List<IPoint> 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<MovePointStruct> 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<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(); |
|
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<IGeometry> ExecuteBoundaryRepair3(IGeometry OriginalGeo, List<IGeometry> ReferenceLayer, List<IGeometry> jcdltb_features, double distance) |
|
{ |
|
List<IGeometry> ResultgeometryList = new List<IGeometry>(); |
|
List<IGeometry> 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<IPoint> 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<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(); |
|
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<IPoint> 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<IGeometry> ReferenceLayer, double distance) |
|
{ |
|
IGeometry geometry = OriginalGeo; |
|
try |
|
{ |
|
List<IPoint> repairpoints = LayerHelper.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; |
|
} |
|
|
|
/// <summary> |
|
/// 延长线段 |
|
/// </summary> |
|
/// <param name="passLine">传入去的线</param> |
|
/// <param name="mode">模式,1为从FromPoint处延长,2为从ToPint处延长,3为两端延长</param> |
|
/// <param name="dis">延长的距离</param> |
|
/// <returns></returns> |
|
/// 创建人:懒羊羊 |
|
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; |
|
} |
|
|
|
/// <summary> |
|
/// 捕捉 |
|
/// </summary> |
|
/// <param name="x"></param> |
|
/// <param name="y"></param> |
|
/// <param name="iFeatureLyr"></param> |
|
/// <param name="axMapControl1"></param> |
|
/// <returns></returns> |
|
private static List<MovePointStruct> 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<MovePointStruct> pointList = new List<MovePointStruct>(); |
|
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<MovePointStruct> Snapping2(IPoint point, List<IGeometry> 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<MovePointStruct> pointList = new List<MovePointStruct>(); |
|
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<IPoint, int> GetSnappingpoint(IPoint point, IFeatureLayer m_featureLayer, double distance = 1) |
|
{ |
|
Dictionary<IPoint, int> pointList = new Dictionary<IPoint, int>(); |
|
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<ConcurrentClass> GetSnappingpoint1(IPoint point, IFeatureLayer m_featureLayer, double distance = 1) |
|
{ |
|
List<ConcurrentClass> pointList = new List<ConcurrentClass>(); |
|
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<int> listoid = new List<int>(); |
|
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<ConcurrentClass> GetSnappingpoint2(IPoint point, List<IGeometry> m_featureLayer, List<string> listmoveToPoint = null, double distance = 1) |
|
{ |
|
List<ConcurrentClass> pointList = new List<ConcurrentClass>(); |
|
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; |
|
} |
|
/// <summary> |
|
/// 线转面 |
|
/// </summary> |
|
/// <param name="pPolyline">线对象</param> |
|
/// <returns>IGeometry 面对象</returns> |
|
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 尖锐角处理 |
|
/// <summary> |
|
/// 尖锐角处理 |
|
/// </summary> |
|
/// <param name="geometry"></param> |
|
/// <param name="pointList"></param> |
|
/// <param name="angle"></param> |
|
/// <returns></returns> |
|
public static IGeometry ResolveAcuteAngle(IGeometry geometry, List<IPoint> 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; |
|
} |
|
|
|
/// <summary> |
|
/// 解决狭长图形问题 |
|
/// </summary> |
|
/// <param name="geometry"></param> |
|
/// <returns></returns> |
|
public static IGeometry ResolveLongAndNarrow(IGeometry geometry) |
|
{ |
|
List<IPoint> 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<IPoint> points, IGeometry uniongeo = null) |
|
{ |
|
List<IPoint> 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; |
|
} |
|
/// <summary> |
|
/// 擦除图形本身存在的尖锐角 |
|
/// </summary> |
|
/// <param name="geometry"></param> |
|
/// <param name="points"></param> |
|
/// <param name="uniongeo"></param> |
|
/// <returns></returns> |
|
public static IGeometry SharpAngleErase(IGeometry geometry, List<IPoint> points, IGeometry Erasegeo = null) |
|
{ |
|
List<IPoint> 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; |
|
} |
|
|
|
/// <summary> |
|
/// |
|
/// </summary> |
|
/// <param name="baseLine"></param> |
|
/// <param name="direction">clockwise顺时针 true为顺时针/false为逆时针</param> |
|
/// <returns></returns> |
|
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; |
|
} |
|
|
|
|
|
/// <summary> |
|
/// 根据点集合生成图形 |
|
/// </summary> |
|
/// <param name="Points"></param> |
|
/// <returns></returns> |
|
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 |
|
/// <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 MovePointStruct |
|
{ |
|
public IFeature Feature { get; set; } |
|
public IGeometry Geometry { get; set; } |
|
public int PartIndex { get; set; } |
|
public int VertexIndex { get; set; } |
|
} |
|
public class ConcurrentClass |
|
{ |
|
/// <summary> |
|
/// 共点 |
|
/// </summary> |
|
public IPoint Point { get; set; } |
|
/// <summary> |
|
/// 共点个数 |
|
/// </summary> |
|
public int ConcurrentCount { get; set; } |
|
/// <summary> |
|
/// 所在图形 |
|
/// </summary> |
|
public List<int> ListObjectID { get; set; } |
|
|
|
public bool FootPoint { get; set; } |
|
public double angle { get; set; } |
|
} |
|
}
|
|
|