Beispiel #1
0
        /// <summary>
        /// Interpolate the simultion data to a specified interval using a linear interpolation.
        /// </summary>
        /// <param name="simulatedTrain">The list of the simulated train details.</param>
        /// <param name="trackGeometry">The list of Track geometry data to align the train location.</param>
        /// <param name="startKm">Starting kilometreage for the interpolation.</param>
        /// <param name="endKm">End kilometerage for the interpolation.</param>
        /// <param name="interval">interpolation interval, specified in metres.</param>
        /// <returns>List of interpolated values for the simulation.</returns>
        public List <InterpolatedTrain> interpolateSimulationData(List <simulatedTrain> simulatedTrain, List <trackGeometry> trackGeometry)
        {
            /* Placeholders for the interpolated distance markers. */
            double previousKm = 0;
            double currentKm  = 0;
            /* Place holder to calaculte the time for each interpolated value. */
            DateTime simTime = new DateTime();
            double   time = 0;
            double   days, hours, minutes, seconds;
            /* Flag to indicate when to collect the next time value. */
            bool timeChange = true;

            /* Additional loop and TSR details. */
            int    geometryIdx = 0;
            bool   loop        = false;
            bool   TSR         = false;
            double TSRspeed    = 0;

            /* Index values for the interpolation parameters */
            int index0 = -1;
            int index1 = -1;

            /* Interplation parameters. */
            double interpolatedSpeed = 0;
            double X0, X1, Y0, Y1;

            List <InterpolatedTrain> simulatedInterpolation = new List <InterpolatedTrain>();

            if (simulatedTrain[1].singleLineKm - simulatedTrain[0].singleLineKm > 0)    // Increasing Km
            {
                /* Set the start of the interpolation. */
                currentKm = Settings.startKm;

                while (currentKm < Settings.endKm)
                {
                    /* Find the closest kilometerage markers either side of the current interpoaltion point. */
                    index0 = findClosestLowerKm(currentKm, simulatedTrain);
                    index1 = findClosestGreaterKm(currentKm, simulatedTrain);

                    /* If a valid index is found, extract the existing journey parameters and interpolate. */
                    if (index0 >= 0 && index1 >= 0)
                    {
                        X0 = simulatedTrain[index0].singleLineKm;
                        X1 = simulatedTrain[index1].singleLineKm;
                        Y0 = simulatedTrain[index0].velocity;
                        Y1 = simulatedTrain[index1].velocity;
                        if (timeChange)
                        {
                            time    = simulatedTrain[index0].time;
                            days    = (time / secPerDay);
                            hours   = (days - Math.Truncate(days)) * hoursPerDay;
                            minutes = (hours - Math.Truncate(hours)) * minutesPerHour;
                            seconds = (minutes - Math.Truncate(minutes)) * secPerMinute;

                            simTime    = new DateTime(2000, 1, (int)days + 1, (int)hours, (int)minutes, (int)seconds);
                            timeChange = false;
                        }

                        /* Perform linear interpolation. */
                        interpolatedSpeed = linear(currentKm, X0, X1, Y0, Y1);
                        /* Interpolate the time. */
                        simTime = simTime.AddHours(calculateTimeInterval(previousKm, currentKm, interpolatedSpeed));
                    }
                    else
                    {
                        /* Boundary conditions for interpolating the data prior to and beyond the existing journey points. */
                        time = 0;
                        interpolatedSpeed = 0;
                    }

                    /* Determine if we need to extract the time from the data or interpolate it. */
                    if (index1 >= 0)
                    {
                        if (currentKm >= simulatedTrain[index1].singleLineKm)
                        {
                            timeChange = true;
                        }
                    }

                    geometryIdx = trackGeometry[0].findClosestTrackGeometryPoint(trackGeometry, currentKm);

                    if (geometryIdx >= 0)
                    {
                        /* Check if there is a loop at this location. */
                        loop = trackGeometry[geometryIdx].isLoopHere;

                        /* Check if there is a TSR at this location. */
                        TSR      = trackGeometry[geometryIdx].isTSRHere;
                        TSRspeed = trackGeometry[geometryIdx].temporarySpeedRestriction;
                    }

                    /* Create the interpolated data object and add it to the list. */
                    InterpolatedTrain item = new InterpolatedTrain("Simulated Train", "Simulated Loco", simTime, currentKm, interpolatedSpeed, loop, TSR, TSRspeed);
                    simulatedInterpolation.Add(item);

                    /* Create a copy of the current km marker and increment. */
                    previousKm = currentKm;
                    currentKm  = currentKm + Settings.interval / 1000;
                }
            }
            else              // Decreasing km.
            {
                /* Set the start of the interpolation. */
                currentKm = Settings.endKm;

                while (currentKm > Settings.startKm)
                {
                    /* Find the closest kilometerage markers either side of the current interpoaltion point. */
                    index0 = findClosestLowerKm(currentKm, simulatedTrain);
                    index1 = findClosestGreaterKm(currentKm, simulatedTrain);

                    /* If a valid index is found, extract the existing journey parameters and interpolate. */
                    if (index0 >= 0 && index1 >= 0)
                    {
                        X0 = simulatedTrain[index0].singleLineKm;
                        X1 = simulatedTrain[index1].singleLineKm;
                        Y0 = simulatedTrain[index0].velocity;
                        Y1 = simulatedTrain[index1].velocity;
                        if (timeChange)
                        {
                            time    = simulatedTrain[index0].time;
                            days    = (time / secPerDay);
                            hours   = (days - Math.Truncate(days)) * hoursPerDay;
                            minutes = (hours - Math.Truncate(hours)) * minutesPerHour;
                            seconds = (minutes - Math.Truncate(minutes)) * secPerMinute;

                            simTime    = new DateTime(2000, 1, (int)days + 1, (int)hours, (int)minutes, (int)seconds);
                            timeChange = false;
                        }

                        /* Perform linear interpolation. */
                        interpolatedSpeed = linear(currentKm, X0, X1, Y0, Y1);
                        /* Interpolate the time. */
                        simTime = simTime.AddHours(calculateTimeInterval(previousKm, currentKm, interpolatedSpeed));
                    }
                    else
                    {
                        /* Boundary conditions for interpolating the data prior to and beyond the existing journey points. */
                        time = 0;
                        interpolatedSpeed = 0;
                    }

                    /* Determine if we need to extract the time from the data or interpolate it. */
                    if (index0 >= 0)
                    {
                        if (currentKm <= simulatedTrain[index0].singleLineKm)
                        {
                            timeChange = true;
                        }
                    }

                    geometryIdx = trackGeometry[0].findClosestTrackGeometryPoint(trackGeometry, currentKm);

                    if (geometryIdx >= 0)
                    {
                        /* Check if there is a loop at this location. */
                        loop = trackGeometry[geometryIdx].isLoopHere;

                        /* Check if there is a TSR at this location. */
                        TSR      = trackGeometry[geometryIdx].isTSRHere;
                        TSRspeed = trackGeometry[geometryIdx].temporarySpeedRestriction;
                    }

                    /* Create the interpolated data object and add it to the list. */
                    InterpolatedTrain item = new InterpolatedTrain("Simualted Train", "Simulated Loco", simTime, currentKm, interpolatedSpeed, loop, TSR, TSRspeed);
                    simulatedInterpolation.Add(item);

                    /* Create a copy of the current km marker and increment. */
                    previousKm = currentKm;
                    currentKm  = currentKm - Settings.interval / 1000;
                }
            }

            return(simulatedInterpolation);
        }
Beispiel #2
0
        /// <summary>
        ///  Interpolate the train speed to a specified interval using a linear interpolation.
        /// </summary>
        /// <param name="trains">List of train objects containing the parameters for each train journey.</param>
        /// <param name="trackGeometry">The list of Track geometry data to align the train location.</param>
        /// <param name="startKm">Starting kilometreage for the interpolation.</param>
        /// <param name="endKm">End kilometerage for the interpolation.</param>
        /// <param name="interval">interpolation interval, specified in metres.</param>
        /// <returns>List of train objects with interpolated values at the specified interval.</returns>
        public List <Train> interpolateTrainData(List <Train> trains, List <trackGeometry> trackGeometry)
        {
            /* Placeholders for the interpolated distance markers. */
            double previousKm = 0;
            double currentKm  = 0;
            /* Place holder to calaculte the time for each interpolated value. */
            DateTime time = new DateTime();
            /* Flag to indicate when to collect the next time value. */
            bool timeChange = true;

            /* Additional loop and TSR details. */
            int    geometryIdx = 0;
            bool   loop        = false;
            bool   TSR         = false;
            double TSRspeed    = 0;

            /* Index values for the interpolation parameters */
            int index0 = -1;
            int index1 = -1;

            /* Interplation parameters. */
            double interpolatedSpeed = 0;
            double X0, X1, Y0, Y1;


            /* Create a new list of trains for the journies interpolated values. */
            List <Train> newTrainList = new List <Train>();
            /* Create a journey list to store the existing journey details. */
            List <TrainDetails> journey = new List <TrainDetails>();

            /* Cycle through each train to interpolate between points. */
            for (int trainIdx = 0; trainIdx < trains.Count(); trainIdx++)
            {
                /* Create a new journey list of interpolated values. */
                List <InterpolatedTrain> interpolatedTrainList = new List <InterpolatedTrain>();

                journey = trains[trainIdx].TrainJourney;

                if (journey[0].trainDirection == direction.increasing)
                {
                    /* Set the start of the interpolation. */
                    currentKm = Settings.startKm;

                    while (currentKm < Settings.endKm)
                    {
                        /* Find the closest kilometerage markers either side of the current interpoaltion point. */
                        index0 = findClosestLowerKm(currentKm, journey);
                        index1 = findClosestGreaterKm(currentKm, journey);

                        /* If a valid index is found, extract the existing journey parameters and interpolate. */
                        if (index0 >= 0 && index1 >= 0)
                        {
                            X0 = journey[index0].geometryKm;
                            X1 = journey[index1].geometryKm;
                            Y0 = journey[index0].speed;
                            Y1 = journey[index1].speed;
                            if (timeChange)
                            {
                                time       = journey[index0].NotificationDateTime;
                                timeChange = false;
                            }

                            /* Perform linear interpolation. */
                            interpolatedSpeed = linear(currentKm, X0, X1, Y0, Y1);
                            /* Interpolate the time. */
                            time = time.AddHours(calculateTimeInterval(previousKm, currentKm, interpolatedSpeed));
                        }
                        else
                        {
                            /* Boundary conditions for interpolating the data prior to and beyond the existing journey points. */
                            time = new DateTime(2000, 1, 1);
                            interpolatedSpeed = 0;
                        }

                        /* Determine if we need to extract the time from the data or interpolate it. */
                        if (index1 >= 0)
                        {
                            if (currentKm >= journey[index1].geometryKm)
                            {
                                timeChange = true;
                            }
                        }

                        geometryIdx = trackGeometry[0].findClosestTrackGeometryPoint(trackGeometry, currentKm);

                        if (geometryIdx >= 0)
                        {
                            /* Check if there is a loop at this location. */
                            loop = trackGeometry[geometryIdx].isLoopHere;

                            /* Check if there is a TSR at this location. */
                            TSR      = trackGeometry[geometryIdx].isTSRHere;
                            TSRspeed = trackGeometry[geometryIdx].temporarySpeedRestriction;
                        }

                        /* Create the interpolated data object and add it to the list. */
                        InterpolatedTrain item = new InterpolatedTrain(trains[trainIdx].TrainJourney[0].TrainID, trains[trainIdx].TrainJourney[0].LocoID,
                                                                       time, currentKm, interpolatedSpeed, loop, TSR, TSRspeed);
                        interpolatedTrainList.Add(item);

                        /* Create a copy of the current km marker and increment. */
                        previousKm = currentKm;
                        currentKm  = currentKm + Settings.interval / 1000;
                    }
                }
                else if (journey[0].trainDirection == direction.decreasing)
                {
                    /* Set the start of the interpolation. */
                    currentKm = Settings.endKm;

                    while (currentKm > Settings.startKm)
                    {
                        /* Find the closest kilometerage markers either side of the current interpoaltion point. */
                        index0 = findClosestLowerKm(currentKm, journey);
                        index1 = findClosestGreaterKm(currentKm, journey);

                        /* If a valid index is found, extract the existing journey parameters and interpolate. */
                        if (index0 >= 0 && index1 >= 0)
                        {
                            X0 = journey[index0].geometryKm;
                            X1 = journey[index1].geometryKm;
                            Y0 = journey[index0].speed;
                            Y1 = journey[index1].speed;
                            if (timeChange)
                            {
                                time       = journey[index0].NotificationDateTime;
                                timeChange = false;
                            }

                            /* Perform linear interpolation. */
                            interpolatedSpeed = linear(currentKm, X0, X1, Y0, Y1);
                            /* Interpolate the time. */
                            time = time.AddHours(calculateTimeInterval(previousKm, currentKm, interpolatedSpeed));
                        }
                        else
                        {
                            /* Boundary conditions for interpolating the data prior to and beyond the existing journey points. */
                            time = new DateTime(2000, 1, 1);
                            interpolatedSpeed = 0;
                        }

                        /* Determine if we need to extract the time from the data or interpolate it. */
                        if (index0 >= 0)
                        {
                            if (currentKm <= journey[index0].geometryKm)
                            {
                                timeChange = true;
                            }
                        }

                        geometryIdx = trackGeometry[0].findClosestTrackGeometryPoint(trackGeometry, currentKm);

                        if (geometryIdx >= 0)
                        {
                            /* Check if there is a loop at this location. */
                            loop = trackGeometry[geometryIdx].isLoopHere;

                            /* Check if there is a TSR at this location. */
                            TSR      = trackGeometry[geometryIdx].isTSRHere;
                            TSRspeed = trackGeometry[geometryIdx].temporarySpeedRestriction;
                        }

                        /* Create the interpolated data object and add it to the list. */
                        InterpolatedTrain item = new InterpolatedTrain(trains[trainIdx].TrainJourney[0].TrainID, trains[trainIdx].TrainJourney[0].LocoID,
                                                                       time, currentKm, interpolatedSpeed, loop, TSR, TSRspeed);
                        interpolatedTrainList.Add(item);

                        /* Create a copy of the current km marker and increment. */
                        previousKm = currentKm;
                        currentKm  = currentKm - Settings.interval / 1000;
                    }
                }
                else
                {
                    /* The train direction is not defined. */
                }

                /* Add the interpolated list to the list of new train objects. */
                Train trainItem = new Train(interpolatedTrainList, journey[0].trainDirection);
                newTrainList.Add(trainItem);
            }

            /* Return the completed interpolated train data. */
            return(newTrainList);
        }