示例#1
0
        /// <summary>
        /// Update (or fully recalculate) the data for charting the path
        /// </summary>
        /// <param name="trainpath">The train path for which to store chart data</param>
        public void Update(Trainpath trainpath)
        {
            this.PathName = trainpath.PathName;
            var localPathChartPoints = new List <PathChartPoint>();

            DistanceAlongPath = new Dictionary <TrainpathNode, double>();
            ResetAllMinMax();

            TrainpathNode node         = trainpath.FirstNode;
            float         lastDistance = 0;

            while (node != null)
            {
                DistanceAlongPath[node] = lastDistance;
                IEnumerable <PathChartPoint> additionalPoints = DetermineChartPoints(node);

                foreach (PathChartPoint relativePoint in additionalPoints)
                {
                    PathChartPoint absolutePoint = new PathChartPoint(relativePoint, lastDistance);
                    lastDistance += relativePoint.DistanceAlongNextSection;
                    AddPoint(localPathChartPoints, absolutePoint);
                }

                node = node.NextMainNode;
            }

            //todo possibly we need to change the information on the last node, and copy e.g. the grade from the last-but-one node

            PathChartPoints = localPathChartPoints;
            StoreAllMinMax();
        }
示例#2
0
        /// <summary>
        /// Translate a curvature to a deviation in the chart. For now, basically we use sign
        /// </summary>
        /// <param name="pathPoint">The single point for which to determine the deviation from 0</param>
        private float CurvatureDeviation(PathChartPoint pathPoint)
        {
            float deviation = 10 * Math.Sign(pathPoint.Curvature);

            //deviation = pathPoint.Curvature;
            return(deviation);
        }
示例#3
0
 /// <summary>
 /// Constructor from another PathChartPoint, only shifted in distance along the path
 /// </summary>
 /// <param name="sourcePoint">The point to copy from</param>
 /// <param name="distanceShift">Extra distance along the path</param>
 public PathChartPoint(PathChartPoint sourcePoint, float distanceShift)
 {
     HeightM                  = sourcePoint.HeightM;
     DistanceAlongPath        = sourcePoint.DistanceAlongPath + distanceShift;
     Curvature                = sourcePoint.Curvature;
     DistanceAlongNextSection = sourcePoint.DistanceAlongNextSection;
     GradePercent             = sourcePoint.GradePercent;
     TrackItemText            = sourcePoint.TrackItemText;
     TrackItemType            = sourcePoint.TrackItemType;
 }
示例#4
0
        private PathChartPoint CreateBrokenChartPoint(TrainpathNode thisNode, TrainpathNode nextNode)
        {
            float          height      = thisNode.Location.Location.Y;
            float          distance    = (float)Math.Sqrt(WorldLocation.GetDistanceSquared(thisNode.Location, nextNode.Location));
            float          heightOther = nextNode.Location.Location.Y;
            float          grade       = (heightOther - height) / distance;
            float          curvature   = 0;
            PathChartPoint brokenPoint = new PathChartPoint(height, curvature, grade, distance);

            return(brokenPoint);
        }
示例#5
0
        /// <summary>
        /// Add a point to the list and update all Min/Max values
        /// </summary>
        private void AddPoint(List <PathChartPoint> localPathChartPoints, PathChartPoint newPoint)
        {
            this.MinDistanceAlongPath = Math.Min(this.MinDistanceAlongPath, newPoint.DistanceAlongPath);
            this.MaxDistanceAlongPath = Math.Max(this.MaxDistanceAlongPath, newPoint.DistanceAlongPath);
            this.MinHeightM           = Math.Min(this.MinHeightM, newPoint.HeightM);
            this.MaxHeightM           = Math.Max(this.MaxHeightM, newPoint.HeightM);
            this.MinGradePercent      = Math.Min(this.MinGradePercent, newPoint.GradePercent);
            this.MaxGradePercent      = Math.Max(this.MaxGradePercent, newPoint.GradePercent);
            this.MinCurvature         = Math.Min(this.MinCurvature, newPoint.Curvature);
            this.MaxCurvature         = Math.Max(this.MaxCurvature, newPoint.Curvature);

            localPathChartPoints.Add(newPoint);
        }
示例#6
0
        /// <summary>
        /// From section information create a point for charting the path, and add it to newPoints.
        /// In case there are track items in this particular section, add those also (starting with the last item as seen from the direction of the path)
        /// </summary>
        /// <param name="newPoints">The list to which to add the point</param>
        /// <param name="vectorNode">The vectorNode to use for curvature and grade</param>
        /// <param name="trackItems">A list of track items in this vector tracknode</param>
        /// <param name="isForward">Is the path in the same direction as the tracknode</param>
        /// <param name="height">Height to store in the point</param>
        /// <param name="tvsi">The section index in the track vector node</param>
        /// <param name="sectionOffsetStart">Offset of the start of this section (in forward direction of track, not of path)</param>
        /// <param name="sectionOffsetStart">Offset of the end of this section (in forward direction of track, not of path)</param>
        private void AddPointAndTrackItems(List <PathChartPoint> newPoints, TrVectorNode vectorNode, IEnumerable <ChartableTrackItem> trackItems,
                                           bool isForward, float height, int tvsi, float sectionOffsetStart, float sectionOffsetEnd)
        {
            //Note, we are adding points in in reverse direction

            var additionalPoints = new List <PathChartPoint>();

            // not a percentage. We can safely assume the pitch is small enough so we do not to take tan(pitch)
            float gradeFromPitch = -vectorNode.TrVectorSections[tvsi].AX * (isForward ? 1 : -1);
            float curvature      = GetCurvature(vectorNode, tvsi, isForward);

            List <ChartableTrackItem> items_local = trackItems.ToList();

            if (isForward)
            {
                items_local.Reverse();
            }

            PathChartPoint newPoint;

            foreach (ChartableTrackItem chartableItem in items_local)
            {
                if (chartableItem.TrackVectorSectionIndex == tvsi && sectionOffsetStart <= chartableItem.TrackVectorSectionOffset && chartableItem.TrackVectorSectionOffset < sectionOffsetEnd)
                {
                    if (isForward)
                    {
                        //For forward, we start at the last item in the track
                        newPoint         = new PathChartPoint(chartableItem.Height, curvature, gradeFromPitch, sectionOffsetEnd - chartableItem.TrackVectorSectionOffset, chartableItem.ItemText, chartableItem.ItemType);
                        sectionOffsetEnd = chartableItem.TrackVectorSectionOffset;
                    }
                    else
                    {
                        //For reverse, we have to swap forward and reverse speed limits
                        ChartableTrackItemType itemType =
                            chartableItem.ItemType == ChartableTrackItemType.SpeedLimitForward ? ChartableTrackItemType.SpeedLimitReverse :
                            chartableItem.ItemType == ChartableTrackItemType.SpeedLimitReverse ? ChartableTrackItemType.SpeedLimitForward :
                            chartableItem.ItemType;
                        //For reverse, we start at the first item in the track
                        newPoint           = new PathChartPoint(chartableItem.Height, curvature, gradeFromPitch, chartableItem.TrackVectorSectionOffset - sectionOffsetStart, chartableItem.ItemText, itemType);
                        sectionOffsetStart = chartableItem.TrackVectorSectionOffset;
                    }
                    additionalPoints.Add(newPoint);
                }
            }

            newPoint = new PathChartPoint(height, curvature, gradeFromPitch, sectionOffsetEnd - sectionOffsetStart);
            additionalPoints.Add(newPoint);

            newPoints.AddRange(additionalPoints);
        }
示例#7
0
        /// <summary>
        /// Determine the ChartPoints from the startNode (included) until but not including the endNode=startNode.NextMainNode
        /// Each tracksection-begin should be a new point
        /// </summary>
        /// <param name="thisNode">The node to start with</param>
        /// <remarks>The assumption is that the two trainpath nodes only have a single tracknode connecting them</remarks>
        /// <returns>At least one new chart point</returns>
        private IEnumerable <PathChartPoint> DetermineChartPoints(TrainpathNode thisNode)
        {
            // The track consists of a number of sections. These sections might be along the direction we are going in (isForward) or not
            // The first point (belonging to currentNode) is the first we return, and possibly the only one.
            // Any new  points we are going to add are all at the boundaries of sections
            // From the track database we get the (height) data only at start of a section.
            // If we are moving forward the height at the section boundary is coming from the section just after the boundary
            // If we are moving reverse the height at the section boundary is coming from the section just before the boundary;
            var           newPoints = new List <PathChartPoint>();
            TrainpathNode nextNode  = thisNode.NextMainNode;

            if (nextNode == null)
            {
                PathChartPoint singlePoint = new PathChartPoint(thisNode);
                newPoints.Add(singlePoint);
                return(newPoints);
            }

            if (thisNode.IsBroken || nextNode.IsBroken || thisNode.NextMainTvnIndex == -1)
            {
                PathChartPoint singlePoint = CreateBrokenChartPoint(thisNode, nextNode);
                newPoints.Add(singlePoint);
                return(newPoints);
            }

            TrackNode tn = trackDB.TrackNodes[thisNode.NextMainTvnIndex];

            TrVectorNode vectorNode            = tn.TrVectorNode;
            var          trackItemsInTracknode = trackItems.GetItemsInTracknode(tn);


            bool  isForward;
            bool  isReverse; // only dummy out argument
            int   tvsiStart;
            int   tvsiStop;
            float sectionOffsetStart;
            float sectionOffsetStop;

            DetermineSectionDetails(thisNode, nextNode, tn, out isForward, out tvsiStart, out sectionOffsetStart);
            DetermineSectionDetails(nextNode, thisNode, tn, out isReverse, out tvsiStop, out sectionOffsetStop);

            float height;

            if (isForward)
            {
                // We add points in reverse order, so starting at the last section and its index
                float sectionOffsetNext = sectionOffsetStop;
                for (int tvsi = tvsiStop; tvsi > tvsiStart; tvsi--)
                {
                    height = vectorNode.TrVectorSections[tvsi].Y;
                    AddPointAndTrackItems(newPoints, vectorNode, trackItemsInTracknode, isForward, height, tvsi, 0, sectionOffsetNext);

                    sectionOffsetNext = SectionLengthAlongTrack(tn, tvsi - 1);
                }

                //Also works in case this is the only point we are adding
                height = thisNode.Location.Location.Y;
                AddPointAndTrackItems(newPoints, vectorNode, trackItemsInTracknode, isForward, height, tvsiStart, sectionOffsetStart, sectionOffsetNext);
            }
            else
            {   //reverse
                // We add points in reverse order, so starting at the first section and its index
                float sectionOffsetNext = sectionOffsetStop;
                for (int tvsi = tvsiStop; tvsi < tvsiStart; tvsi++)
                {
                    // The height needs to come from the end of the section, so the where the next section starts. And we only know the height at the start.
                    height = vectorNode.TrVectorSections[tvsi + 1].Y;
                    AddPointAndTrackItems(newPoints, vectorNode, trackItemsInTracknode, isForward, height, tvsi, sectionOffsetNext, SectionLengthAlongTrack(tn, tvsi));

                    sectionOffsetNext = 0;
                }

                //Also works in case this is the only point we are adding
                height = thisNode.Location.Location.Y;
                AddPointAndTrackItems(newPoints, vectorNode, trackItemsInTracknode, isForward, height, tvsiStart, sectionOffsetNext, sectionOffsetStart);
            }
            newPoints.Reverse();
            return(newPoints);
        }
示例#8
0
 /// <summary>
 /// Return whether the source point is within the zoomrange
 /// </summary>
 /// <param name="sourcePoint">The point for which to determine whether it is in the zoomRange</param>
 /// <returns></returns>
 protected bool InZoomRange(PathChartPoint sourcePoint)
 {
     return(sourcePoint.DistanceAlongPath >= this.zoomedMinX && sourcePoint.DistanceAlongPath <= this.zoomedMaxX);
 }