using ESRI.ArcGIS.ADF; using ESRI.ArcGIS.Display; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Geometry; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace KGIS.PlatformPlugin.Commands.Tools.TraceTool { public class TraceFeedbackClass : IDisplayFeedback, ITraceFeedback { private IScreenDisplay m_pScreenDisplay; private ILineSymbol m_pLineSymbol; private List m_pListBeTracePolyline; private int m_nPolylineCount; private IPolyline m_pPolyline; private IPoint m_pPointStart; private IPoint m_pPointEnd; private IPoint m_pPointFrom; private IPolyline m_pPolylineBeTraced; private bool m_bAlongPolyline = true; private bool m_bIncludeAnchorFrom = true; public IScreenDisplay Display { set { this.m_pScreenDisplay = value; } } public ISymbol Symbol { get { return this.m_pLineSymbol as ISymbol; } set { } } public List ListBeTracePolyline { set { this.m_pListBeTracePolyline = value; this.m_nPolylineCount = this.m_pListBeTracePolyline.Count; } } public bool IncludeAnchorFrom { set { this.m_bIncludeAnchorFrom = value; } } public TraceFeedbackClass() { this.m_pLineSymbol = new SimpleLineSymbolClass(); this.m_pLineSymbol.Width = 2.0; (this.m_pLineSymbol as ISimpleLineSymbol).Style = esriSimpleLineStyle.esriSLSSolid; IColor color = new RgbColorClass { Red = 255, Blue = 0, Green = 0 }; this.m_pLineSymbol.Color = color; (this.m_pLineSymbol as ISymbol).ROP2 = esriRasterOpCode.esriROPNotXOrPen; } public void Start(IPoint pPoint, IPoint pPointFrom, IPoint pPointEnd) { if (pPoint != null && !pPoint.IsEmpty) { if (this.m_pPolyline != null) { ComReleaser.ReleaseCOMObject(this.m_pPolyline); } this.m_pPolyline = new PolylineClass(); this.m_pPolyline.SpatialReference = this.m_pScreenDisplay.DisplayTransformation.SpatialReference; double num = 10000000.0; for (int i = 0; i < this.m_nPolylineCount; i++) { IPolyline polyline = this.m_pListBeTracePolyline[i]; IProximityOperator proximityOperator = polyline as IProximityOperator; double num2 = proximityOperator.ReturnDistance(pPoint); if (num2 < num) { num = num2; this.m_pPointStart = proximityOperator.ReturnNearestPoint(pPoint, esriSegmentExtension.esriNoExtension); this.m_pPolylineBeTraced = polyline; } } this.m_pPointFrom = pPointFrom; this.m_pPointEnd = pPointEnd; if (this.m_pPointFrom == null) { this.m_pPointFrom = this.m_pPointStart; } return; } } public void MoveTo(IPoint pPoint) { if (this.m_pPolylineBeTraced == null) { return; } IProximityOperator proximityOperator = this.m_pPolylineBeTraced as IProximityOperator; IPoint point = proximityOperator.ReturnNearestPoint(pPoint, esriSegmentExtension.esriNoExtension); if (point != null && !(point as IRelationalOperator).Equals(this.m_pPointStart)) { if (this.m_pPolylineBeTraced != null && !this.m_pPolylineBeTraced.IsEmpty) { if (!this.m_pPolylineBeTraced.IsClosed) { IPolyline fromNotCloseTraced = this.GetFromNotCloseTraced(this.m_pPolylineBeTraced, this.m_pPointStart, point); if (this.m_pPolyline != null) { this.m_pPolyline.SetEmpty(); if (fromNotCloseTraced != null && !fromNotCloseTraced.IsEmpty) { (this.m_pPolyline as ISegmentCollection).AddSegmentCollection(fromNotCloseTraced as ISegmentCollection); } ComReleaser.ReleaseCOMObject(fromNotCloseTraced); } } else { IPolyline fromCloseTraced = this.GetFromCloseTraced(this.m_pPolylineBeTraced, this.m_pPointStart, point, this.m_pPolyline); if (this.m_pPolyline != null) { this.m_pPolyline.SetEmpty(); if (fromCloseTraced != null && !fromCloseTraced.IsEmpty) { (this.m_pPolyline as ISegmentCollection).AddSegmentCollection(fromCloseTraced as ISegmentCollection); } ComReleaser.ReleaseCOMObject(fromCloseTraced); } } } this.Refresh(0); } } public void Refresh(int hDC) { this.m_pScreenDisplay.StartDrawing(this.m_pScreenDisplay.hDC, -1); if (this.m_pPolyline != null && !this.m_pPolyline.IsEmpty && this.m_pLineSymbol != null) { IPolyline polyline = (this.m_pPolyline as IClone).Clone() as IPolyline; IPointCollection pointCollection = polyline as IPointCollection; if (this.m_pPointEnd != null && !this.m_pPointEnd.IsEmpty) { pointCollection.InsertPoints(0, 1, ref this.m_pPointEnd); } if (this.m_bIncludeAnchorFrom && this.m_pPointFrom != null && !this.m_pPointFrom.IsEmpty) { IPointCollection arg_B1_0 = pointCollection; IPoint arg_B1_1 = this.m_pPointFrom; object value = Missing.Value; object value2 = Missing.Value; arg_B1_0.AddPoint(arg_B1_1, ref value, ref value2); } polyline.SimplifyNetwork(); this.m_pScreenDisplay.SetSymbol(this.m_pLineSymbol as ISymbol); this.m_pScreenDisplay.DrawPolyline(polyline); ComReleaser.ReleaseCOMObject(polyline); } this.m_pScreenDisplay.FinishDrawing(); } public IPolyline Stop(IPoint pPoint) { if (pPoint != null && this.m_pPolyline != null && !this.m_pPolyline.IsEmpty) { IPolyline polyline = (this.m_pPolyline as IClone).Clone() as IPolyline; polyline.SimplifyNetwork(); ComReleaser.ReleaseCOMObject(this.m_pPolyline); this.m_pPolyline = null; return polyline; } ComReleaser.ReleaseCOMObject(this.m_pPolyline); this.m_pPolyline = null; return null; } private IPolyline GetFromNotCloseTraced(IPolyline pPolyline, IPoint pPointStart, IPoint pPointEnd) { IRelationalOperator relationalOperator = pPointStart as IRelationalOperator; IRelationalOperator relationalOperator2 = pPointEnd as IRelationalOperator; if (relationalOperator.Equals(pPointEnd)) { return null; } IPolyline polyline = (pPolyline as IClone).Clone() as IPolyline; bool flag = false; int num = -1; int num2 = -1; polyline.SplitAtPoint(pPointStart, true, false, out flag, out num, out num2); bool flag2 = false; int num3 = -1; int num4 = -1; polyline.SplitAtPoint(pPointEnd, true, false, out flag2, out num3, out num4); IPointCollection pointCollection = polyline as IPointCollection; int pointCount = pointCollection.PointCount; num2 = -1; num4 = -1; int num5 = 0; while (num5 < pointCount && (num2 < 0 || num4 < 0)) { IPoint other = pointCollection.get_Point(num5); if (!relationalOperator.Equals(other)) { if (relationalOperator2.Equals(other)) { num4 = num5; } } else { num2 = num5; } num5++; } IPolyline polyline2 = new PolylineClass(); polyline2.SpatialReference = this.m_pScreenDisplay.DisplayTransformation.SpatialReference; ISegmentCollection segmentCollection = polyline as ISegmentCollection; if (num2 <= num4) { if (num2 < num4) { for (int i = num2; i <= num4 - 1; i++) { ISegmentCollection arg_10E_0 = polyline2 as ISegmentCollection; ISegment arg_10E_1 = segmentCollection.get_Segment(i); object value = Missing.Value; object value2 = Missing.Value; arg_10E_0.AddSegment(arg_10E_1, ref value, ref value2); } } } else { for (int j = num2 - 1; j >= num4; j--) { ISegmentCollection arg_14D_0 = polyline2 as ISegmentCollection; ISegment arg_14D_1 = segmentCollection.get_Segment(j); object value3 = Missing.Value; object value4 = Missing.Value; arg_14D_0.AddSegment(arg_14D_1, ref value3, ref value4); } } ComReleaser.ReleaseCOMObject(polyline); polyline2.SimplifyNetwork(); return polyline2; } private IPolyline GetFromCloseTraced(IPolyline pPolyline, IPoint pPointStart, IPoint pPointEnd, IPolyline pPolylinePre) { if (pPolyline != null && !pPolyline.IsEmpty) { IRelationalOperator relationalOperator = pPointStart as IRelationalOperator; IRelationalOperator relationalOperator2 = pPointEnd as IRelationalOperator; IPolyline polyline = (pPolyline as IClone).Clone() as IPolyline; bool flag = false; int num = -1; int num2 = -1; polyline.SplitAtPoint(pPointStart, true, false, out flag, out num, out num2); bool flag2 = false; int num3 = -1; int num4 = -1; polyline.SplitAtPoint(pPointEnd, true, false, out flag2, out num3, out num4); IPointCollection pointCollection = polyline as IPointCollection; int num5 = -1; int num6 = -1; int pointCount = pointCollection.PointCount; int num7 = 0; while (num7 < pointCount && (num5 < 0 || num6 < 0)) { IPoint other = pointCollection.get_Point(num7); if (relationalOperator.Equals(other)) { num5 = num7; } else { if (relationalOperator2.Equals(other)) { num6 = num7; } } num7++; } double num8 = 0.0; if (pPolylinePre != null || !pPolylinePre.IsEmpty) { num8 = pPolylinePre.Length / pPolyline.Length; } IPolyline result; if (num8 >= 0.01) { result = PolylineEx.GetFromClosedPolyline(polyline, num5, num6, this.m_bAlongPolyline); } else { if (num5 != num6) { IPolyline fromClosedPolyline = PolylineEx.GetFromClosedPolyline(polyline, num5, num6, true); IPolyline fromClosedPolyline2 = PolylineEx.GetFromClosedPolyline(polyline, num5, num6, false); if (fromClosedPolyline2.Length >= fromClosedPolyline.Length) { ComReleaser.ReleaseCOMObject(fromClosedPolyline2); this.m_bAlongPolyline = true; result = fromClosedPolyline; } else { ComReleaser.ReleaseCOMObject(fromClosedPolyline); this.m_bAlongPolyline = false; result = fromClosedPolyline2; } } else { result = null; } } ComReleaser.ReleaseCOMObject(polyline); return result; } return null; } } }