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.
		
		
		
		
		
			
		
			
				
					
					
						
							333 lines
						
					
					
						
							14 KiB
						
					
					
				
			
		
		
	
	
							333 lines
						
					
					
						
							14 KiB
						
					
					
				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<IPolyline> 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<IPolyline> 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; | 
						|
        } | 
						|
    } | 
						|
}
 | 
						|
 |