Example #1
0
        internal static TrainInformation TestMisdirectedTrain(ESTW estw)
        {
            var Train = estw.Area.Trains[4711];

            var Result = new TrainInformation(Train);

            Result.Direction = eBlockDirection.Right;
            Result.Delay     = 0;
            Result.Block     = estw.Blocks["32G11"].First();

            var ProbeSchedule = new LiveSchedule(Result, Train.Schedules.FirstOrDefault(s => s.Station.ShortSymbol == "TPRB"));

            ProbeSchedule.LiveArrival       = new LeibitTime(eDaysOfService.Thursday, 14, 4);
            ProbeSchedule.LiveDeparture     = new LeibitTime(eDaysOfService.Thursday, 14, 5);
            ProbeSchedule.LiveTrack         = ProbeSchedule.Schedule.Track;
            ProbeSchedule.ExpectedArrival   = ProbeSchedule.LiveArrival;
            ProbeSchedule.ExpectedDeparture = ProbeSchedule.LiveDeparture;
            Result.AddSchedule(ProbeSchedule);

            var TestdorfSchedule = new LiveSchedule(Result, new Schedule(Train, estw.Stations.FirstOrDefault(s => s.ShortSymbol == "TTST")));

            TestdorfSchedule.Schedule.Arrival   = new LeibitTime(14, 11);
            TestdorfSchedule.LiveArrival        = new LeibitTime(eDaysOfService.Thursday, 14, 11);
            TestdorfSchedule.Schedule.Departure = new LeibitTime(14, 12);
            TestdorfSchedule.LiveDeparture      = new LeibitTime(eDaysOfService.Thursday, 14, 12);
            TestdorfSchedule.LiveTrack          = TestdorfSchedule.Schedule.Station.Tracks.FirstOrDefault(t => t.Name == "1A");
            TestdorfSchedule.ExpectedArrival    = TestdorfSchedule.LiveArrival;
            TestdorfSchedule.ExpectedDeparture  = TestdorfSchedule.LiveDeparture;
            Result.AddSchedule(TestdorfSchedule);

            Train.AddSchedule(TestdorfSchedule.Schedule);
            return(Result);
        }
Example #2
0
        internal static TrainInformation TestLoadSharedDelay_NonExisting(ESTW estw)
        {
            var Train = estw.Area.Trains[2007];

            var Result = new TrainInformation(Train);

            Result.Direction = eBlockDirection.Right;
            Result.Delay     = 6;
            Result.Block     = estw.Blocks["32G12"].First();

            var ProbeSchedule = new LiveSchedule(Result, Train.Schedules.FirstOrDefault(s => s.Station.ShortSymbol == "TPRB"));

            ProbeSchedule.LiveArrival       = new LeibitTime(eDaysOfService.Thursday, 13, 7);
            ProbeSchedule.LiveDeparture     = new LeibitTime(eDaysOfService.Thursday, 13, 8);
            ProbeSchedule.LiveTrack         = ProbeSchedule.Schedule.Track;
            ProbeSchedule.ExpectedArrival   = ProbeSchedule.LiveArrival;
            ProbeSchedule.ExpectedDeparture = ProbeSchedule.LiveDeparture;
            Result.AddSchedule(ProbeSchedule);

            var TestdorfSchedule = new LiveSchedule(Result, Train.Schedules.FirstOrDefault(s => s.Station.ShortSymbol == "TTST"));

            TestdorfSchedule.LiveArrival       = new LeibitTime(eDaysOfService.Thursday, 13, 12);
            TestdorfSchedule.LiveDeparture     = new LeibitTime(eDaysOfService.Thursday, 13, 14);
            TestdorfSchedule.LiveTrack         = TestdorfSchedule.Schedule.Track;
            TestdorfSchedule.ExpectedArrival   = TestdorfSchedule.LiveArrival;
            TestdorfSchedule.ExpectedDeparture = TestdorfSchedule.LiveDeparture;
            Result.AddSchedule(TestdorfSchedule);

            var Delay = TestdorfSchedule.AddDelay(4, eDelayType.Departure);

            Delay.Reason   = "Keine Ahnung";
            Delay.CausedBy = 4711;

            return(Result);
        }
Example #3
0
        private void __RefreshLiveSchedules(TrainInformation Train, ESTW estw)
        {
            lock (Train.LockSchedules)
            {
                var OldSchedules = Train.Schedules.ToList();
                Train.TruncateSchedules();

                var SchedulesResult = CalculationBLL.GetSchedulesByTime(Train.Train.Schedules, estw.Time);
                ValidateResult(SchedulesResult);

                foreach (var Schedule in SchedulesResult.Result)
                {
                    var LiveSchedule = OldSchedules.FirstOrDefault(s => s.Schedule.Station.ESTW.Id == Schedule.Station.ESTW.Id &&
                                                                   s.Schedule.Station.ShortSymbol == Schedule.Station.ShortSymbol &&
                                                                   s.Schedule.Time == Schedule.Time);

                    if (LiveSchedule == null)
                    {
                        LiveSchedule = new LiveSchedule(Train, Schedule);
                    }
                    else
                    {
                        OldSchedules.Remove(LiveSchedule);
                    }

                    Train.AddSchedule(LiveSchedule);
                }

                foreach (var OldSchedule in OldSchedules)
                {
                    Train.AddSchedule(OldSchedule);
                }
            }
        }
Example #4
0
        internal static TrainInformation TestTrainDelayDeparture(ESTW estw)
        {
            var Train = estw.Area.Trains[2007];

            var Result = new TrainInformation(Train);

            Result.Direction = eBlockDirection.Right;
            Result.Delay     = 4;
            Result.Block     = estw.Blocks["32G12"].First();

            var ProbeSchedule = new LiveSchedule(Result, Train.Schedules.FirstOrDefault(s => s.Station.ShortSymbol == "TPRB"));

            ProbeSchedule.LiveArrival       = new LeibitTime(eDaysOfService.Thursday, 13, 0);
            ProbeSchedule.LiveDeparture     = new LeibitTime(eDaysOfService.Thursday, 13, 2);
            ProbeSchedule.LiveTrack         = ProbeSchedule.Schedule.Track;
            ProbeSchedule.ExpectedArrival   = ProbeSchedule.LiveArrival;
            ProbeSchedule.ExpectedDeparture = ProbeSchedule.LiveDeparture;
            Result.AddSchedule(ProbeSchedule);

            var TestdorfSchedule = new LiveSchedule(Result, Train.Schedules.FirstOrDefault(s => s.Station.ShortSymbol == "TTST"));

            TestdorfSchedule.LiveArrival       = new LeibitTime(eDaysOfService.Thursday, 13, 07);
            TestdorfSchedule.LiveDeparture     = new LeibitTime(eDaysOfService.Thursday, 13, 12);
            TestdorfSchedule.LiveTrack         = TestdorfSchedule.Schedule.Track;
            TestdorfSchedule.ExpectedArrival   = TestdorfSchedule.LiveArrival;
            TestdorfSchedule.ExpectedDeparture = TestdorfSchedule.LiveDeparture;
            TestdorfSchedule.AddDelay(3, eDelayType.Departure);
            Result.AddSchedule(TestdorfSchedule);

            return(Result);
        }
Example #5
0
        private LiveSchedule __GetCurrentSchedule(TrainInformation train, Block block)
        {
            var Schedules = train.Schedules.Where(s => s.Schedule.Station.ShortSymbol == block.Track.Station.ShortSymbol);

            // If there is only one schedule, it's easy. This will accommodate most cases.
            if (Schedules.Count() == 1)
            {
                return(Schedules.Single());
            }

            // Find the schedule that fits to the train's direction (only if this is unique).
            // LeftToLeft and RightToRight can't be handled here as the train changes its direction.
            var scheduleDirection = eScheduleDirection.Unknown;

            if (train.Direction == eBlockDirection.Left)
            {
                scheduleDirection = eScheduleDirection.RightToLeft;
            }
            else if (train.Direction == eBlockDirection.Right)
            {
                scheduleDirection = eScheduleDirection.LeftToRight;
            }

            var candidates = Schedules.Where(s => s.Schedule.Direction == scheduleDirection);

            if (candidates.Count() == 1)
            {
                return(candidates.Single());
            }

            // Next, check the schedules with the correct directions and take the first one that is not departed.
            if (candidates.Any(s => !s.IsDeparted))
            {
                return(candidates.First(s => !s.IsDeparted));
            }

            // Okay, we were unlucky with the direction, so try again with all schedules.
            if (Schedules.Any(s => !s.IsDeparted))
            {
                return(Schedules.First(s => !s.IsDeparted));
            }

            // As a last resort, assume the last schedule as the current schedule, even if it's already departed.
            if (Schedules.Any())
            {
                return(Schedules.Last());
            }

            // The train has no schedule for the current station (e.g. special or misdirected trains).
            if (block.Track.Station.HasScheduleFile && block.Track.CalculateDelay)
            {
                var schedule = new LiveSchedule(train, block.Track.Station);
                train.AddSchedule(schedule);
                train.Train.AddSchedule(schedule.Schedule);
                return(schedule);
            }

            return(null);
        }
        private static ChannelItemInfo CreateChannelItemInfo(LiveSchedule liveSchedule)
        {
            var id       = LiveVideoProvider.CreateId(liveSchedule.Id);
            var name     = ChannelInfoHelper.FormatMatchName(liveSchedule.HomeTeam, liveSchedule.AwayTeam);
            var overview = string.Format("Starts at {0}<br>Event: {1}<br>Feed type: {2}", liveSchedule.StartTime, liveSchedule.Event, liveSchedule.FeedType);

            return(ChannelInfoHelper.CreateChannelItemInfo(id, name, overview, DateTime.Today));
        }
Example #7
0
        public OperationResult <bool> SetExpectedDelay(LiveSchedule schedule, int?expectedDelayArrival, int?expectedDelayDeparture)
        {
            try
            {
                // Validation
                var validationMessages = new List <string>();

                if (expectedDelayArrival.HasValue && schedule.IsArrived)
                {
                    validationMessages.Add($"Die Ankunftsverspätung kann nicht gesetzt werden, da der Zug {schedule.Train.Train.Number} die Betriebsstelle {schedule.Schedule.Station.ShortSymbol} bereits erreicht hat.");
                }
                if (schedule.IsDeparted)
                {
                    validationMessages.Add($"Der Zug {schedule.Train.Train.Number} hat die Betriebsstelle {schedule.Schedule.Station.ShortSymbol} bereits verlassen.");
                }

                if (validationMessages.Any())
                {
                    validationMessages.Insert(0, "Verspätung kann nicht eingetragen werden");
                    var message = string.Join(Environment.NewLine, validationMessages);
                    throw new InvalidOperationException(message);
                }

                // Let's do it
                if (expectedDelayArrival.HasValue)
                {
                    schedule.ExpectedDelayArrival = expectedDelayArrival;
                }

                if (expectedDelayDeparture.HasValue)
                {
                    schedule.ExpectedDelayDeparture = expectedDelayDeparture;
                }

                schedule.IsManuallyModified = true;

                var calculationResult = CalculationBLL.CalculateExpectedTimes(schedule.Train, schedule.Schedule.Station.ESTW);
                ValidateResult(calculationResult);

                __SynchronizeTwinSchedules(schedule.Train, schedule.Schedule.Station.ESTW);

                var result = new OperationResult <bool>();
                result.Result    = true;
                result.Succeeded = true;
                return(result);
            }
            catch (Exception ex)
            {
                return(new OperationResult <bool> {
                    Message = ex.Message
                });
            }
        }
Example #8
0
        public OperationResult <bool> SetExpectedDelay(LiveSchedule schedule, int expectedDelay)
        {
            try
            {
                // Validation
                var validationMessages = new List <string>();

                if (schedule.IsDeparted)
                {
                    validationMessages.Add($"Der Zug {schedule.Train.Train.Number} hat die Betriebsstelle {schedule.Schedule.Station.ShortSymbol} bereits verlassen.");
                }
                if (schedule.Schedule.Handling == eHandling.Destination)
                {
                    validationMessages.Add($"Der Zug {schedule.Train.Train.Number} endet in {schedule.Schedule.Station.ShortSymbol}.");
                }

                if (validationMessages.Any())
                {
                    validationMessages.Insert(0, "Verspätung kann nicht eingetragen werden");
                    var message = string.Join(Environment.NewLine, validationMessages);
                    throw new InvalidOperationException(message);
                }

                // Let's do it
                schedule.ExpectedDelay = expectedDelay;

                var calculationResult = CalculationBLL.CalculateExpectedTimes(schedule.Train, schedule.Schedule.Station.ESTW);
                ValidateResult(calculationResult);

                var result = new OperationResult <bool>();
                result.Result    = true;
                result.Succeeded = true;
                return(result);
            }
            catch (Exception ex)
            {
                return(new OperationResult <bool> {
                    Message = ex.Message
                });
            }
        }
Example #9
0
        internal static TrainInformation TestSpecialTrainDelay(ESTW estw)
        {
            var Train = new Train(98765);

            var Result = new TrainInformation(Train);

            Result.Direction = eBlockDirection.Left;
            Result.Delay     = 11;
            Result.Block     = estw.Blocks["31G1"].First();

            var TestdorfSchedule = new LiveSchedule(Result, new Schedule(Train, estw.Stations.FirstOrDefault(s => s.ShortSymbol == "TTST")));

            TestdorfSchedule.Schedule.Arrival   = new LeibitTime(18, 26);
            TestdorfSchedule.LiveArrival        = new LeibitTime(eDaysOfService.Thursday, 18, 29);
            TestdorfSchedule.Schedule.Departure = new LeibitTime(18, 28);
            TestdorfSchedule.LiveDeparture      = new LeibitTime(eDaysOfService.Thursday, 18, 35);
            TestdorfSchedule.LiveTrack          = TestdorfSchedule.Schedule.Station.Tracks.FirstOrDefault(t => t.Name == "3");
            TestdorfSchedule.ExpectedArrival    = TestdorfSchedule.LiveArrival;
            TestdorfSchedule.ExpectedDeparture  = TestdorfSchedule.LiveDeparture;
            TestdorfSchedule.AddDelay(4, eDelayType.Departure);
            Result.AddSchedule(TestdorfSchedule);

            var ProbeSchedule = new LiveSchedule(Result, new Schedule(Train, estw.Stations.FirstOrDefault(s => s.ShortSymbol == "TPRB")));

            ProbeSchedule.Schedule.Arrival   = new LeibitTime(18, 33);
            ProbeSchedule.LiveArrival        = new LeibitTime(eDaysOfService.Thursday, 18, 43);
            ProbeSchedule.Schedule.Departure = new LeibitTime(18, 33);
            ProbeSchedule.LiveDeparture      = new LeibitTime(eDaysOfService.Thursday, 18, 44);
            ProbeSchedule.LiveTrack          = ProbeSchedule.Schedule.Station.Tracks.FirstOrDefault(t => t.Name == "1");
            ProbeSchedule.ExpectedArrival    = ProbeSchedule.LiveArrival;
            ProbeSchedule.ExpectedDeparture  = ProbeSchedule.LiveDeparture;
            ProbeSchedule.AddDelay(3, eDelayType.Arrival);
            Result.AddSchedule(ProbeSchedule);

            Train.AddSchedule(TestdorfSchedule.Schedule);
            Train.AddSchedule(ProbeSchedule.Schedule);
            return(Result);
        }
Example #10
0
        internal static TrainInformation TestExpectedTimesPremature(ESTW estw)
        {
            var Train = estw.Area.Trains[12345];

            var Result = new TrainInformation(Train);

            Result.Direction = eBlockDirection.Left;
            Result.Delay     = -5;
            Result.Block     = estw.Blocks["33BP"].First();

            var TestdorfSchedule = new LiveSchedule(Result, Train.Schedules.FirstOrDefault(s => s.Station.ShortSymbol == "TTST"));

            TestdorfSchedule.ExpectedArrival   = new LeibitTime(13, 01);
            TestdorfSchedule.ExpectedDeparture = new LeibitTime(13, 10);
            Result.AddSchedule(TestdorfSchedule);

            var ProbeSchedule = new LiveSchedule(Result, Train.Schedules.FirstOrDefault(s => s.Station.ShortSymbol == "TPRB"));

            ProbeSchedule.ExpectedArrival = new LeibitTime(13, 15);
            Result.AddSchedule(ProbeSchedule);

            return(Result);
        }
Example #11
0
        private TrainInformation __CreateLiveTrainInformation(int trainNumber, ESTW estw)
        {
            if (estw.Area.Trains.ContainsKey(trainNumber))
            {
                var Train  = estw.Area.Trains[trainNumber];
                var Result = new TrainInformation(Train);

                var SchedulesResult = CalculationBLL.GetSchedulesByTime(Train.Schedules, estw.Time);
                ValidateResult(SchedulesResult);

                foreach (var Schedule in SchedulesResult.Result)
                {
                    var LiveSchedule = new LiveSchedule(Result, Schedule);
                    Result.AddSchedule(LiveSchedule);
                }

                // Don't validate result here. When this fails, it's not so dramatic...
                var prevResult = CalculationBLL.GetPreviousService(Train, estw);
                if (prevResult.Succeeded)
                {
                    Result.PreviousService = prevResult.Result;
                }

                var followUpResult = CalculationBLL.GetFollowUpService(Train, estw);
                if (followUpResult.Succeeded)
                {
                    Result.FollowUpService = followUpResult.Result;
                }

                return(Result);
            }
            else
            {
                var Train = estw.Area.Trains.GetOrAdd(trainNumber, new Train(trainNumber));
                return(new TrainInformation(Train));
            }
        }
Example #12
0
        private TrainInformation __CreateLiveTrainInformation(int trainNumber, ESTW estw)
        {
            if (estw.Area.Trains.ContainsKey(trainNumber))
            {
                var Train  = estw.Area.Trains[trainNumber];
                var Result = new TrainInformation(Train);

                var SchedulesResult = CalculationBLL.GetSchedulesByTime(Train.Schedules, estw.Time);
                ValidateResult(SchedulesResult);

                foreach (var Schedule in SchedulesResult.Result)
                {
                    var LiveSchedule = new LiveSchedule(Result, Schedule);
                    Result.AddSchedule(LiveSchedule);
                }

                return(Result);
            }
            else
            {
                var Train = new Train(trainNumber);
                return(new TrainInformation(Train));
            }
        }
Example #13
0
        public OperationResult <SerializationContainer> Open(string Filename)
        {
            try
            {
                var SettingsResult = SettingsBll.GetSettings();
                ValidateResult(SettingsResult);
                var Settings = SettingsResult.Result;

                var Container = new SerializationContainer();

                var File = new FileInfo(Filename);

                if (!File.Exists)
                {
                    throw new OperationFailedException(String.Format("File '{0}' does not exist.", Filename));
                }

                SerializedRoot Root;

                using (var Stream = File.OpenRead())
                {
                    Root = m_Formatter.Deserialize(Stream) as SerializedRoot;
                }

                if (Root == null)
                {
                    throw new OperationFailedException("Invalid file.");
                }

                var AreaResult = InitializationBll.GetAreaInformation();
                ValidateResult(AreaResult);

                var Area = AreaResult.Result.FirstOrDefault(a => a.Id == Root.AreaId);

                if (Area == null)
                {
                    throw new OperationFailedException("Invalid area.");
                }

                foreach (var SerializedEstw in Root.LoadedESTWs)
                {
                    if (!Settings.LoadInactiveEstws && !SerializedEstw.IsActive)
                    {
                        continue;
                    }

                    var Estw = Area.ESTWs.FirstOrDefault(e => e.Id == SerializedEstw.ESTWId);

                    if (Estw == null)
                    {
                        throw new OperationFailedException("Invalid ESTW.");
                    }

                    var LoadResult = InitializationBll.LoadESTW(Estw);
                    ValidateResult(LoadResult);
                    Estw.Time = SerializedEstw.Time;
                }

                foreach (var SerializedTrain in Root.LiveTrains)
                {
                    var Estw = Area.ESTWs.SingleOrDefault(e => e.Id == SerializedTrain.CurrentEstwId);

                    if (Estw == null || !Estw.IsLoaded || !Area.Trains.ContainsKey(SerializedTrain.TrainNumber))
                    {
                        continue;
                    }

                    var Train     = Area.Trains[SerializedTrain.TrainNumber];
                    var LiveTrain = new TrainInformation(Train);
                    LiveTrain.Delay        = SerializedTrain.Delay;
                    LiveTrain.LastModified = SerializedTrain.LastModified;
                    LiveTrain.Direction    = SerializedTrain.TrainDirection;

                    if (Estw.Blocks.ContainsKey(SerializedTrain.Block))
                    {
                        LiveTrain.Block = Estw.Blocks[SerializedTrain.Block].FirstOrDefault(b => b.Direction == SerializedTrain.BlockDirection);
                    }

                    var SchedulesResult = CalculationBll.GetSchedulesByTime(Train.Schedules, Estw.Time);
                    ValidateResult(SchedulesResult);

                    foreach (var SerializedSchedule in SerializedTrain.Schedules)
                    {
                        var Schedule = SchedulesResult.Result.FirstOrDefault(s => s.Station.ShortSymbol == SerializedSchedule.StationShortSymbol &&
                                                                             s.Time == SerializedSchedule.StationTime &&
                                                                             (s.Station.ESTW.Id == SerializedSchedule.EstwId || SerializedSchedule.EstwId == null));

                        if (Schedule == null)
                        {
                            continue;
                        }

                        var LiveSchedule = new LiveSchedule(LiveTrain, Schedule);
                        LiveSchedule.LiveArrival       = SerializedSchedule.LiveArrival;
                        LiveSchedule.LiveDeparture     = SerializedSchedule.LiveDeparture;
                        LiveSchedule.IsArrived         = SerializedSchedule.IsArrived;
                        LiveSchedule.IsDeparted        = SerializedSchedule.IsDeparted;
                        LiveSchedule.ExpectedArrival   = SerializedSchedule.ExpectedArrival;
                        LiveSchedule.ExpectedDeparture = SerializedSchedule.ExpectedDeparture;
                        LiveSchedule.ExpectedDelay     = SerializedSchedule.ExpectedDelay;

                        if (SerializedSchedule.LiveTrack.IsNotNullOrEmpty())
                        {
                            LiveSchedule.LiveTrack = Schedule.Station.Tracks.SingleOrDefault(t => t.Name == SerializedSchedule.LiveTrack);
                        }

                        foreach (var SerializedDelay in SerializedSchedule.Delays)
                        {
                            var Delay = LiveSchedule.AddDelay(SerializedDelay.Minutes, SerializedDelay.Type);
                            Delay.Reason   = SerializedDelay.Reason;
                            Delay.CausedBy = SerializedDelay.CausedBy;
                        }

                        LiveTrain.AddSchedule(LiveSchedule);
                    }

                    if (LiveTrain.Schedules.Any())
                    {
                        Area.LiveTrains.TryAdd(Train.Number, LiveTrain);
                    }
                }

                Container.Area            = Area;
                Container.VisibleStations = Root.VisibleStations;
                Container.Windows         = Root.Windows;

                var Result = new OperationResult <SerializationContainer>();
                Result.Result    = Container;
                Result.Succeeded = true;
                return(Result);
            }
            catch (Exception ex)
            {
                return(new OperationResult <SerializationContainer> {
                    Message = ex.Message
                });
            }
        }
Example #14
0
        protected List <ScheduleItem> GetScheduleCandidates(Area area, int leadMinutes, bool matchTrack)
        {
            var currentTime     = SelectedStation.ESTW.Time;
            var schedulesResult = m_CalculationBll.GetSchedulesByTime(SelectedStation.Schedules, currentTime);

            if (!schedulesResult.Succeeded)
            {
                Dispatcher.Invoke(() => MessageBox.Show(schedulesResult.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error));
                return(new List <ScheduleItem>());
            }

            var schedules  = schedulesResult.Result.Where(s => s.Handling == eHandling.Start || s.Handling == eHandling.StopPassengerTrain || s.Handling == eHandling.StopFreightTrain || s.Handling == eHandling.Destination);
            var candidates = new List <ScheduleItem>();

            foreach (var schedule in schedules)
            {
                var          train        = schedule.Train;
                LiveSchedule liveSchedule = null;

                if (train == null || !schedule.TrainType.IsPassengerTrain())
                {
                    continue;
                }

                if (area.LiveTrains.ContainsKey(train.Number))
                {
                    var liveTrain = area.LiveTrains[train.Number];
                    liveSchedule = liveTrain.Schedules.FirstOrDefault(s => s.Schedule == schedule);
                }

                if (liveSchedule == null)
                {
                    if (matchTrack && schedule.Track != SelectedTrack && schedule.Track != SelectedTrack.Parent)
                    {
                        continue;
                    }
                    if (schedule.Time < currentTime)
                    {
                        continue;
                    }
                    if (schedule.Time > currentTime.AddMinutes(leadMinutes))
                    {
                        continue;
                    }

                    candidates.Add(new ScheduleItem(schedule.Time, schedule));
                }
                else
                {
                    if (liveSchedule.IsDeparted)
                    {
                        continue;
                    }

                    if (schedule.Handling == eHandling.Destination && schedule.Station.ESTW.Time > liveSchedule.Train.LastModified)
                    {
                        continue;
                    }

                    if (matchTrack && schedule.Track != SelectedTrack && schedule.Track != SelectedTrack.Parent && liveSchedule.LiveTrack != SelectedTrack && liveSchedule.LiveTrack != SelectedTrack.Parent)
                    {
                        continue;
                    }

                    var liveScheduleIndex = liveSchedule.Train.Schedules.IndexOf(liveSchedule);
                    var nextSchedules     = liveSchedule.Train.Schedules.Skip(liveScheduleIndex + 1);

                    // No live data is available for the current station, but the train has already arrived at one of the next stations.
                    // This is the case at the beginning of the simulation or for diverted trains.
                    if (nextSchedules.Any(s => s.IsArrived))
                    {
                        continue;
                    }

                    var referenceTime = schedule.Arrival ?? schedule.Departure;

                    if (liveSchedule.Schedule.Handling == eHandling.Start && liveSchedule.ExpectedDeparture != null)
                    {
                        referenceTime = liveSchedule.ExpectedDeparture;
                    }
                    else if (liveSchedule.Schedule.Handling != eHandling.Start && liveSchedule.ExpectedArrival != null)
                    {
                        referenceTime = liveSchedule.ExpectedArrival;
                    }

                    if (referenceTime > currentTime.AddMinutes(leadMinutes))
                    {
                        continue;
                    }

                    if (referenceTime < currentTime && liveSchedule.Train.LastModified < currentTime)
                    {
                        continue;
                    }

                    candidates.Add(new ScheduleItem(referenceTime, schedule, liveSchedule));
                }
            }

            return(candidates);
        }
Example #15
0
 internal DelayInfo(LiveSchedule schedule, int minutes, eDelayType type)
 {
     Schedule = schedule;
     Minutes  = minutes;
     Type     = type;
 }
Example #16
0
        private void __RefreshTrainInformation(TrainInformation Train, Block Block, ESTW Estw)
        {
            LiveSchedule CurrentSchedule = null;

            // Train is in station and drives in the correct direction
            if (Block != null)
            {
                // Dummy track for stations without platforms (e.g. Üst)
                if (!Estw.SchedulesLoaded || Block.Track.Name.IsNullOrEmpty())
                {
                    Train.Block = Block;
                }
                else
                {
                    CurrentSchedule = __GetCurrentSchedule(Train, Block);

                    if (CurrentSchedule == null)
                    {
                        Train.Block = Block;
                    }
                    else
                    {
                        Track LiveTrack = null;

                        // Too difficult to explain -> LTA...
                        if (CurrentSchedule.Schedule.Track == null ||
                            !CurrentSchedule.Schedule.Track.IsPlatform ||
                            CurrentSchedule.Schedule.Track.Name.Equals(Block.Track.Name, StringComparison.InvariantCultureIgnoreCase) ||
                            (CurrentSchedule.Schedule.Track.Alternatives.Count == 0 && CurrentSchedule.Schedule.Track.Parent.Alternatives.Count == 0) ||
                            CurrentSchedule.Schedule.Track.Alternatives.Any(a => a.Name.Equals(Block.Track.Name, StringComparison.InvariantCultureIgnoreCase)))
                        {
                            LiveTrack = Block.Track;
                        }
                        else if (CurrentSchedule.Schedule.Track.Name.Equals(Block.Track.Parent.Name, StringComparison.InvariantCultureIgnoreCase) ||
                                 CurrentSchedule.Schedule.Track.Alternatives.Any(a => a.Name.Equals(Block.Track.Parent.Name, StringComparison.InvariantCultureIgnoreCase)))
                        {
                            LiveTrack = Block.Track.Parent;
                        }
                        else if (CurrentSchedule.Schedule.Track.Parent.Name.Equals(Block.Track.Parent.Name, StringComparison.InvariantCultureIgnoreCase) ||
                                 CurrentSchedule.Schedule.Track.Parent.Alternatives.Any(a => a.Name.Equals(Block.Track.Parent.Name, StringComparison.InvariantCultureIgnoreCase)))
                        {
                            LiveTrack = Block.Track;
                        }

                        if (LiveTrack != null)
                        {
                            Train.Block = Block;
                        }

                        if (LiveTrack == null)
                        {
                            CurrentSchedule = null;
                        }
                        else
                        {
                            CurrentSchedule.IsArrived   = true;
                            CurrentSchedule.IsCancelled = false;

                            if ((CurrentSchedule.Schedule.Track == null || CurrentSchedule.Schedule.Track.CalculateDelay) && CurrentSchedule.LiveArrival == null)
                            {
                                CurrentSchedule.LiveArrival = Estw.Time;
                            }

                            if (CurrentSchedule.Schedule.Track == null || CurrentSchedule.Schedule.Track.IsPlatform)
                            {
                                CurrentSchedule.LiveTrack = LiveTrack;

                                if (LiveTrack.IsPlatform)
                                {
                                    // When train is in station, it cannot be departed.
                                    // This fixes issues that can occur in mirror fields when the train has arrived at the station in one ESTW, but not yet in the other.
                                    CurrentSchedule.IsDeparted    = false;
                                    CurrentSchedule.LiveDeparture = null;
                                }
                            }
                        }
                    }
                }
            }

            foreach (var Schedule in Train.Schedules)
            {
                if (Schedule != CurrentSchedule || Schedule.LiveTrack == null || !Schedule.LiveTrack.IsPlatform)
                {
                    if (Schedule.IsArrived)
                    {
                        Schedule.IsDeparted = true;
                    }

                    if (Schedule.LiveArrival != null && Schedule.LiveDeparture == null)
                    {
                        Schedule.LiveDeparture = Estw.Time;
                    }
                }
            }

            // For stations that are located in mirror fields, two schedules might exist.
            // The times etc. must be identical to both schedules to ensure that delay and expected times are calculated correctly.
            // Example: HBON is located in the district of AROG, but also in the mirror fields of HB. For the local trains, two schedules exist (one from ESTW HB and one from AROG).

            foreach (var ScheduleGroup in Train.Schedules.GroupBy(s => new { s.Schedule.Station.ShortSymbol, s.Schedule.Time }))
            {
                var ReferenceSchedule = ScheduleGroup.FirstOrDefault(s => s.IsArrived);

                if (ReferenceSchedule != null)
                {
                    foreach (var Schedule in ScheduleGroup)
                    {
                        Schedule.IsArrived     = ReferenceSchedule.IsArrived;
                        Schedule.IsDeparted    = ReferenceSchedule.IsDeparted;
                        Schedule.LiveArrival   = ReferenceSchedule.LiveArrival;
                        Schedule.LiveDeparture = ReferenceSchedule.LiveDeparture;
                        Schedule.LiveTrack     = ReferenceSchedule.LiveTrack;
                    }
                }
            }

            if (Estw.SchedulesLoaded)
            {
                var DelayResult = CalculationBLL.CalculateDelay(Train, Estw);
                ValidateResult(DelayResult);

                if (DelayResult.Result.HasValue)
                {
                    Train.Delay = DelayResult.Result.Value;
                }
            }

            var ExpectedResult = CalculationBLL.CalculateExpectedTimes(Train, Estw);

            ValidateResult(ExpectedResult);

            Train.LastModified = Estw.Time;
            Train.RealBlock    = Block;

            __SynchronizeTwinSchedules(Train, Estw);

            if (Train.PreviousService.HasValue && Estw.Area.LiveTrains.ContainsKey(Train.PreviousService.Value) && CurrentSchedule != null && CurrentSchedule.Schedule.Handling == eHandling.Start)
            {
                var previousTrain = Estw.Area.LiveTrains[Train.PreviousService.Value];

                if (previousTrain.Schedules.FirstOrDefault(s => s.Schedule.Handling == eHandling.Destination)?.IsArrived == false)
                {
                    __RefreshTrainInformation(previousTrain, Block, Estw);
                }
            }
        }
Example #17
0
        public OperationResult <bool> SetTrainState(LiveSchedule schedule, eTrainState state)
        {
            try
            {
                // Check if we are lucky
                if ((state == eTrainState.None && !schedule.IsComposed && !schedule.IsPrepared) ||
                    (state == eTrainState.Composed && schedule.IsComposed) ||
                    (state == eTrainState.Prepared && schedule.IsPrepared))
                {
                    return(new OperationResult <bool> {
                        Result = false, Succeeded = true
                    });
                }

                // Validation
                var validationMessages = new List <string>();

                if (!schedule.IsArrived)
                {
                    validationMessages.Add($"Der Zug {schedule.Train.Train.Number} hat die Betriebsstelle {schedule.Schedule.Station.ShortSymbol} noch nicht erreicht.");
                }

                if (schedule.IsDeparted)
                {
                    validationMessages.Add($"Der Zug {schedule.Train.Train.Number} hat die Betriebsstelle {schedule.Schedule.Station.ShortSymbol} bereits verlassen.");
                }

                if (validationMessages.Any())
                {
                    validationMessages.Insert(0, "Eingabe des Zugstatus nicht möglich");
                    var message = string.Join(Environment.NewLine, validationMessages);
                    throw new InvalidOperationException(message);
                }

                // Here we go
                switch (state)
                {
                case eTrainState.None:
                    schedule.IsComposed = false;
                    schedule.IsPrepared = false;
                    break;

                case eTrainState.Composed:
                    schedule.IsComposed = true;
                    break;

                case eTrainState.Prepared:
                    schedule.IsComposed = true;     // Set both flags is this case
                    schedule.IsPrepared = true;
                    break;
                }

                __SynchronizeTwinSchedules(schedule.Train, schedule.Schedule.Station.ESTW);

                var result = new OperationResult <bool>();
                result.Result    = true;
                result.Succeeded = true;
                return(result);
            }
            catch (Exception ex)
            {
                return(new OperationResult <bool> {
                    Message = ex.Message
                });
            }
        }
Example #18
0
        public void CalculationBLLTest_CalculateDelay_Unscheduled()
        {
            var bll  = new CalculationBLL();
            var estw = new ESTW("meep", "bla", string.Empty, null);

            var train     = new Train(4711);
            var liveTrain = new TrainInformation(train);

            var station1 = new Station("Bahnhof A", "A", 1, string.Empty, string.Empty, estw);
            var station2 = new Station("Bahnhof B", "B", 2, string.Empty, string.Empty, estw);
            var station3 = new Station("Bahnhof C", "C", 3, string.Empty, string.Empty, estw);
            var track1   = new Track("dummy", true, true, station1, null);
            var track2   = new Track("dummy", true, true, station2, null);
            var track3   = new Track("dummy", true, true, station3, null);

            var schedule1 = new Schedule(train, null, new LeibitTime(8, 20), track1, new List <eDaysOfService> {
                eDaysOfService.Tuesday
            }, eScheduleDirection.LeftToRight, eHandling.Transit, string.Empty, null);
            var schedule2 = new Schedule(train, null, new LeibitTime(8, 30), track2, new List <eDaysOfService> {
                eDaysOfService.Tuesday
            }, eScheduleDirection.LeftToRight, eHandling.Transit, string.Empty, null);

            train.AddSchedule(schedule1);
            train.AddSchedule(schedule2);

            var liveSchedule1 = new LiveSchedule(liveTrain, schedule1);
            var liveSchedule2 = new LiveSchedule(liveTrain, schedule2);

            liveTrain.AddSchedule(liveSchedule1);
            liveTrain.AddSchedule(liveSchedule2);

            liveSchedule1.LiveArrival   = new LeibitTime(8, 21);
            liveSchedule1.LiveDeparture = new LeibitTime(8, 22);

            estw.Time = new LeibitTime(eDaysOfService.Tuesday, 8, 25);
            var result = bll.CalculateDelay(liveTrain, estw);

            Assert.IsTrue(result.Succeeded);
            Assert.AreEqual(2, result.Result);

            liveTrain.Delay = result.Result.Value;
            estw.Time       = new LeibitTime(eDaysOfService.Tuesday, 8, 39);

            var liveSchedule3 = new LiveSchedule(liveTrain, station3);

            liveTrain.AddSchedule(liveSchedule3);
            train.AddSchedule(liveSchedule3.Schedule);

            liveSchedule3.LiveArrival   = estw.Time;
            liveSchedule3.LiveDeparture = estw.Time;

            Assert.AreEqual(new LeibitTime(eDaysOfService.Tuesday, 8, 37), liveSchedule3.Schedule.Arrival);
            Assert.AreEqual(new LeibitTime(eDaysOfService.Tuesday, 8, 37), liveSchedule3.Schedule.Departure);

            result = bll.CalculateDelay(liveTrain, estw);
            Assert.IsTrue(result.Succeeded);
            Assert.AreEqual(2, result.Result);

            estw.Time = new LeibitTime(eDaysOfService.Tuesday, 8, 45);
            liveSchedule2.LiveArrival   = estw.Time;
            liveSchedule2.LiveDeparture = estw.Time;

            result = bll.CalculateDelay(liveTrain, estw);
            Assert.IsTrue(result.Succeeded);
            Assert.AreEqual(15, result.Result);
        }
Example #19
0
        public void CalculationBLLTest_SortSchedules_NormalCase()
        {
            var estw = new ESTW("meep", "bla", string.Empty, null);

            var station1 = new Station("Bahnhof A", "A", 1, string.Empty, string.Empty, estw);
            var station2 = new Station("Bahnhof B", "B", 2, string.Empty, string.Empty, estw);
            var station3 = new Station("Bahnhof C", "C", 3, string.Empty, string.Empty, estw);

            var track1 = new Track("dummy", true, true, station1, null);
            var track2 = new Track("dummy", true, true, station2, null);
            var track3 = new Track("dummy", true, true, station3, null);

            var train = new Train(4711);

            var schedule1 = new Schedule(train: train,
                                         arrival: null,
                                         departure: new LeibitTime(eDaysOfService.Monday, 16, 1),
                                         track: track1,
                                         days: new List <eDaysOfService> {
                eDaysOfService.Monday
            },
                                         direction: eScheduleDirection.LeftToRight,
                                         handling: eHandling.Transit,
                                         remark: string.Empty);

            var schedule2 = new Schedule(train: train,
                                         arrival: null,
                                         departure: new LeibitTime(eDaysOfService.Monday, 16, 5),
                                         track: track2,
                                         days: new List <eDaysOfService> {
                eDaysOfService.Monday
            },
                                         direction: eScheduleDirection.LeftToRight,
                                         handling: eHandling.Transit,
                                         remark: string.Empty);

            var schedule3 = new Schedule(train: train,
                                         arrival: null,
                                         departure: new LeibitTime(eDaysOfService.Monday, 16, 9),
                                         track: track3,
                                         days: new List <eDaysOfService> {
                eDaysOfService.Monday
            },
                                         direction: eScheduleDirection.LeftToRight,
                                         handling: eHandling.Transit,
                                         remark: string.Empty);

            var liveTrain = new TrainInformation(train);

            var liveSchedule1 = new LiveSchedule(liveTrain, schedule1);
            var liveSchedule2 = new LiveSchedule(liveTrain, schedule2);
            var liveSchedule3 = new LiveSchedule(liveTrain, schedule3);

            liveTrain.AddSchedule(liveSchedule1);
            liveTrain.AddSchedule(liveSchedule2);
            liveTrain.AddSchedule(liveSchedule3);

            liveSchedule1.LiveArrival   = new LeibitTime(eDaysOfService.Monday, 16, 2);
            liveSchedule1.LiveDeparture = new LeibitTime(eDaysOfService.Monday, 16, 3);

            Assert.AreEqual(0, liveTrain.Schedules.IndexOf(liveSchedule1));
            Assert.AreEqual(1, liveTrain.Schedules.IndexOf(liveSchedule2));
            Assert.AreEqual(2, liveTrain.Schedules.IndexOf(liveSchedule3));
        }
        internal static SerializationContainer Serialize_Deserialize()
        {
            var Area = ExpectedValuesOfInitializationBLLTest.LoadTestdorfESTW();
            var Estw = Area.ESTWs.Single(e => e.Id == "TTST");

            Estw.Time          = new LeibitTime(eDaysOfService.Thursday, 13, 40);
            Estw.LastUpdatedOn = DateTime.Now.AddSeconds(-10);

            var Train = Area.Trains[2007];

            var LiveTrain = new TrainInformation(Train);

            LiveTrain.Block = Estw.Blocks["32G12"].First();

            var ProbeSchedule = new LiveSchedule(LiveTrain, Train.Schedules.FirstOrDefault(s => s.Station.ShortSymbol == "TPRB"));

            ProbeSchedule.LiveArrival   = new LeibitTime(eDaysOfService.Thursday, 13, 7);
            ProbeSchedule.LiveDeparture = new LeibitTime(eDaysOfService.Thursday, 13, 8);
            ProbeSchedule.LiveTrack     = ProbeSchedule.Schedule.Track;
            LiveTrain.AddSchedule(ProbeSchedule);

            var TestdorfSchedule = new LiveSchedule(LiveTrain, Train.Schedules.FirstOrDefault(s => s.Station.ShortSymbol == "TTST"));

            TestdorfSchedule.LiveArrival   = new LeibitTime(eDaysOfService.Thursday, 13, 12);
            TestdorfSchedule.LiveDeparture = new LeibitTime(eDaysOfService.Thursday, 13, 14);
            TestdorfSchedule.LiveTrack     = TestdorfSchedule.Schedule.Track;
            LiveTrain.AddSchedule(TestdorfSchedule);

            Area.LiveTrains.TryAdd(Train.Number, LiveTrain);


            Train = Area.Trains[12345];

            LiveTrain       = new TrainInformation(Train);
            LiveTrain.Block = Estw.Blocks["31G3"].First();

            ProbeSchedule             = new LiveSchedule(LiveTrain, Train.Schedules.FirstOrDefault(s => s.Station.ShortSymbol == "TPRB"));
            ProbeSchedule.LiveArrival = new LeibitTime(eDaysOfService.Thursday, 13, 14);
            ProbeSchedule.LiveTrack   = ProbeSchedule.Schedule.Track;
            LiveTrain.AddSchedule(ProbeSchedule);

            TestdorfSchedule               = new LiveSchedule(LiveTrain, Train.Schedules.FirstOrDefault(s => s.Station.ShortSymbol == "TTST"));
            TestdorfSchedule.LiveArrival   = new LeibitTime(eDaysOfService.Thursday, 13, 7);
            TestdorfSchedule.LiveDeparture = new LeibitTime(eDaysOfService.Thursday, 13, 10);
            TestdorfSchedule.LiveTrack     = TestdorfSchedule.Schedule.Track;
            LiveTrain.AddSchedule(TestdorfSchedule);

            Area.LiveTrains.TryAdd(Train.Number, LiveTrain);


            Train = Area.Trains[12346];

            LiveTrain       = new TrainInformation(Train);
            LiveTrain.Block = Estw.Blocks["32G22"].First();

            ProbeSchedule               = new LiveSchedule(LiveTrain, Train.Schedules.FirstOrDefault(s => s.Station.ShortSymbol == "TPRB"));
            ProbeSchedule.LiveArrival   = new LeibitTime(eDaysOfService.Thursday, 13, 15);
            ProbeSchedule.LiveDeparture = new LeibitTime(eDaysOfService.Thursday, 13, 25);
            ProbeSchedule.LiveTrack     = ProbeSchedule.Schedule.Track;

            var ProbeDelay = ProbeSchedule.AddDelay(5, eDelayType.Departure);

            ProbeDelay.Reason = "Meep";

            LiveTrain.AddSchedule(ProbeSchedule);

            TestdorfSchedule               = new LiveSchedule(LiveTrain, Train.Schedules.FirstOrDefault(s => s.Station.ShortSymbol == "TTST"));
            TestdorfSchedule.LiveArrival   = new LeibitTime(eDaysOfService.Thursday, 13, 29);
            TestdorfSchedule.LiveDeparture = new LeibitTime(eDaysOfService.Thursday, 13, 30);
            TestdorfSchedule.LiveTrack     = TestdorfSchedule.Schedule.Station.Tracks.Single(t => t.Name == "2");
            LiveTrain.AddSchedule(TestdorfSchedule);

            Area.LiveTrains.TryAdd(Train.Number, LiveTrain);

            var Result = new SerializationContainer();

            Result.Area = Area;
            return(Result);
        }
Example #21
0
 internal ScheduleItem(LeibitTime referenceTime, Schedule schedule, LiveSchedule liveSchedule = null)
 {
     ReferenceTime = referenceTime;
     Schedule      = schedule;
     LiveSchedule  = liveSchedule;
 }
Example #22
0
        public OperationResult <bool> ChangeTrack(LiveSchedule schedule, Track track)
        {
            try
            {
                // Validation
                var validationMessages = new List <string>();

                if (schedule.IsArrived)
                {
                    validationMessages.Add($"Der Zug {schedule.Train.Train.Number} hat die Betriebsstelle {schedule.Schedule.Station.ShortSymbol} bereits erreicht.");
                }

                if (schedule.Schedule.Track != null && !schedule.Schedule.Track.IsPlatform)
                {
                    validationMessages.Add($"Für die Betriebsstelle {schedule.Schedule.Station.ShortSymbol} kann kein Gleiswechsel vorgenommen werden.");
                }

                if (schedule.Schedule.Track != null && (schedule.Schedule.Track.Alternatives.Any() || schedule.Schedule.Track.Parent.Alternatives.Any()))
                {
                    if (!schedule.Schedule.Track.Name.Equals(track.Name, StringComparison.InvariantCultureIgnoreCase) && // 1 -> 1
                        !schedule.Schedule.Track.Name.Equals(track.Parent.Name, StringComparison.InvariantCultureIgnoreCase) && // 1 -> 1A
                        !schedule.Schedule.Track.Parent.Name.Equals(track.Name, StringComparison.InvariantCultureIgnoreCase) && // 1A -> 1
                        !schedule.Schedule.Track.Parent.Name.Equals(track.Parent.Name, StringComparison.InvariantCultureIgnoreCase) && // 1A -> 1B
                        !schedule.Schedule.Track.Alternatives.Any(a => a.Name.Equals(track.Name, StringComparison.InvariantCultureIgnoreCase)) && // 1 -> 2
                        !schedule.Schedule.Track.Alternatives.Any(a => a.Name.Equals(track.Parent.Name, StringComparison.InvariantCultureIgnoreCase)) && // 1 -> 2A
                        !schedule.Schedule.Track.Parent.Alternatives.Any(a => a.Name.Equals(track.Name, StringComparison.InvariantCultureIgnoreCase)) && // 1A -> 2
                        !schedule.Schedule.Track.Parent.Alternatives.Any(a => a.Name.Equals(track.Parent.Name, StringComparison.InvariantCultureIgnoreCase)))    // 1A -> 2A
                    {
                        validationMessages.Add($"Das Gleis {track.Name} liegt in einem anderen Bahnhofsteil als das planmäßige Gleis {schedule.Schedule.Track.Name}.");
                    }
                }

                if (validationMessages.Any())
                {
                    validationMessages.Insert(0, "Gleiswechsel nicht möglich");
                    var message = string.Join(Environment.NewLine, validationMessages);
                    throw new InvalidOperationException(message);
                }

                // Let's go
                if (schedule.Schedule.Track != null && schedule.Schedule.Track.Name.Equals(track.Name, StringComparison.InvariantCultureIgnoreCase))
                {
                    schedule.LiveTrack = null;
                }
                else
                {
                    schedule.LiveTrack = track;
                }

                var result = new OperationResult <bool>();
                result.Result    = true;
                result.Succeeded = true;
                return(result);
            }
            catch (Exception ex)
            {
                return(new OperationResult <bool> {
                    Message = ex.Message
                });
            }
        }
Example #23
0
        private void __RefreshTrainInformation(TrainInformation Train, Block Block, ESTW Estw)
        {
            LiveSchedule CurrentSchedule = null;

            // Train is in station and drives in the correct direction
            if (Block != null)
            {
                // Dummy track for stations without platforms (e.g. Üst)
                if (Block.Track.Name.IsNullOrEmpty())
                {
                    Train.Block = Block;
                }
                else
                {
                    var Schedules = Train.Schedules.Where(s => s.Schedule.Station.ShortSymbol == Block.Track.Station.ShortSymbol);

                    // Find schedule that fits to the current direction of travel
                    foreach (var Schedule in Schedules)
                    {
                        if ((Schedule.Schedule.Direction == eScheduleDirection.LeftToRight && Train.Direction == eBlockDirection.Right) ||
                            (Schedule.Schedule.Direction == eScheduleDirection.RightToLeft && Train.Direction == eBlockDirection.Left))
                        {
                            CurrentSchedule = Schedule;
                            break;
                        }
                    }

                    // When no schedule has been found according to the direction, take the first one.
                    if (CurrentSchedule == null)
                    {
                        CurrentSchedule = Schedules.FirstOrDefault();
                    }

                    // The train has no schedule for the current station (e.g. special or misdirected trains).
                    if (CurrentSchedule == null && Block.Track.Station.ScheduleFile.IsNotNullOrWhiteSpace() && Block.Track.CalculateDelay)
                    {
                        CurrentSchedule = new LiveSchedule(Train, Block.Track.Station);
                        Train.AddSchedule(CurrentSchedule);
                        Train.Train.AddSchedule(CurrentSchedule.Schedule);
                    }

                    if (CurrentSchedule == null)
                    {
                        Train.Block = Block;
                    }
                    else
                    {
                        Track LiveTrack = null;

                        // Too difficult to explain -> LTA...
                        if (CurrentSchedule.Schedule.Track == null ||
                            !CurrentSchedule.Schedule.Track.IsPlatform ||
                            CurrentSchedule.Schedule.Track.Name.Equals(Block.Track.Name, StringComparison.InvariantCultureIgnoreCase) ||
                            (CurrentSchedule.Schedule.Track.Alternatives.Count == 0 && CurrentSchedule.Schedule.Track.Parent.Alternatives.Count == 0) ||
                            CurrentSchedule.Schedule.Track.Alternatives.Any(a => a.Name.Equals(Block.Track.Name, StringComparison.InvariantCultureIgnoreCase)))
                        {
                            LiveTrack = Block.Track;
                        }
                        else if (CurrentSchedule.Schedule.Track.Name.Equals(Block.Track.Parent.Name, StringComparison.InvariantCultureIgnoreCase) ||
                                 CurrentSchedule.Schedule.Track.Alternatives.Any(a => a.Name.Equals(Block.Track.Parent.Name, StringComparison.InvariantCultureIgnoreCase)))
                        {
                            LiveTrack = Block.Track.Parent;
                        }
                        else if (CurrentSchedule.Schedule.Track.Parent.Name.Equals(Block.Track.Parent.Name, StringComparison.InvariantCultureIgnoreCase) ||
                                 CurrentSchedule.Schedule.Track.Parent.Alternatives.Any(a => a.Name.Equals(Block.Track.Parent.Name, StringComparison.InvariantCultureIgnoreCase)))
                        {
                            LiveTrack = Block.Track;
                        }

                        if (LiveTrack != null || Train.Block == null)
                        {
                            Train.Block = Block;
                        }

                        if (LiveTrack == null)
                        {
                            CurrentSchedule = null;
                        }
                        else
                        {
                            CurrentSchedule.IsArrived = true;

                            if ((CurrentSchedule.Schedule.Track == null || CurrentSchedule.Schedule.Track.CalculateDelay) && CurrentSchedule.LiveArrival == null)
                            {
                                CurrentSchedule.LiveArrival = Estw.Time;
                            }

                            if (CurrentSchedule.Schedule.Track == null || CurrentSchedule.Schedule.Track.IsPlatform)
                            {
                                CurrentSchedule.LiveTrack = LiveTrack;

                                if (LiveTrack.IsPlatform)
                                {
                                    // When train is in station, it cannot be departed.
                                    // This fixes issues that can occur in mirror fields when the train has arrived at the station in one ESTW, but not yet in the other.
                                    CurrentSchedule.IsDeparted    = false;
                                    CurrentSchedule.LiveDeparture = null;
                                }
                            }
                        }
                    }
                }
            }

            foreach (var Schedule in Train.Schedules)
            {
                if (Schedule != CurrentSchedule || Schedule.LiveTrack == null || !Schedule.LiveTrack.IsPlatform)
                {
                    if (Schedule.IsArrived)
                    {
                        Schedule.IsDeparted = true;
                    }

                    if (Schedule.LiveArrival != null && Schedule.LiveDeparture == null)
                    {
                        Schedule.LiveDeparture = Estw.Time;
                    }
                }
            }

            // For stations that are located in mirror fields, two schedules might exist.
            // The times etc. must be identical to both schedules to ensure that delay and expected times are calculated correctly.
            // Example: HBON is located in the district of AROG, but also in the mirror fields of HB. For the local trains, two schedules exist (one from ESTW HB and one from AROG).

            foreach (var ScheduleGroup in Train.Schedules.GroupBy(s => new { s.Schedule.Station.ShortSymbol, s.Schedule.Time }))
            {
                var ReferenceSchedule = ScheduleGroup.FirstOrDefault(s => s.IsArrived);

                if (ReferenceSchedule != null)
                {
                    foreach (var Schedule in ScheduleGroup)
                    {
                        Schedule.IsArrived     = ReferenceSchedule.IsArrived;
                        Schedule.IsDeparted    = ReferenceSchedule.IsDeparted;
                        Schedule.LiveArrival   = ReferenceSchedule.LiveArrival;
                        Schedule.LiveDeparture = ReferenceSchedule.LiveDeparture;
                        Schedule.LiveTrack     = ReferenceSchedule.LiveTrack;
                    }
                }
            }

            var DelayResult = CalculationBLL.CalculateDelay(Train, Estw);

            ValidateResult(DelayResult);

            if (DelayResult.Result.HasValue)
            {
                Train.Delay = DelayResult.Result.Value;
            }

            var ExpectedResult = CalculationBLL.CalculateExpectedTimes(Train, Estw);

            ValidateResult(ExpectedResult);

            Train.LastModified = Estw.Time;
        }
Example #24
0
        public OperationResult <SerializationContainer> Open(string Filename)
        {
            try
            {
                var SettingsResult = SettingsBll.GetSettings();
                ValidateResult(SettingsResult);
                var Settings = SettingsResult.Result;

                var Container = new SerializationContainer();

                var File = new FileInfo(Filename);

                if (!File.Exists)
                {
                    throw new OperationFailedException(String.Format("File '{0}' does not exist.", Filename));
                }

                SerializedRoot Root;

                using (var Stream = File.OpenRead())
                {
                    Root = m_Formatter.Deserialize(Stream) as SerializedRoot;
                }

                if (Root == null)
                {
                    throw new OperationFailedException("Invalid file.");
                }

                var AreaResult = InitializationBll.GetAreaInformation();
                ValidateResult(AreaResult);

                var Area = AreaResult.Result.FirstOrDefault(a => a.Id == Root.AreaId);

                if (Area == null)
                {
                    throw new OperationFailedException("Invalid area.");
                }

                foreach (var SerializedEstw in Root.LoadedESTWs)
                {
                    if (!Settings.LoadInactiveEstws && !SerializedEstw.IsActive)
                    {
                        continue;
                    }

                    var Estw = Area.ESTWs.FirstOrDefault(e => e.Id == SerializedEstw.ESTWId);

                    if (Estw == null)
                    {
                        throw new OperationFailedException("Invalid ESTW.");
                    }

                    var LoadResult = InitializationBll.LoadESTW(Estw);
                    ValidateResult(LoadResult);
                    Estw.Time      = SerializedEstw.Time;
                    Estw.StartTime = SerializedEstw.StartTime;
                }

                foreach (var SerializedTrain in Root.LiveTrains)
                {
                    var Estw = Area.ESTWs.SingleOrDefault(e => e.Id == SerializedTrain.CurrentEstwId);

                    if (Estw?.IsLoaded == false || !Area.Trains.ContainsKey(SerializedTrain.TrainNumber))
                    {
                        continue;
                    }

                    var Train     = Area.Trains[SerializedTrain.TrainNumber];
                    var LiveTrain = new TrainInformation(Train);
                    LiveTrain.Delay        = SerializedTrain.Delay;
                    LiveTrain.LastModified = SerializedTrain.LastModified;
                    LiveTrain.CreatedOn    = SerializedTrain.CreatedOn;
                    LiveTrain.Direction    = SerializedTrain.TrainDirection;
                    LiveTrain.IsDestinationStationCancelled = SerializedTrain.IsDestinationStationCancelled;

                    if (SerializedTrain.BlockHistory != null)
                    {
                        foreach (var block in SerializedTrain.BlockHistory)
                        {
                            var estw2 = Area.ESTWs.SingleOrDefault(e => e.Id == block.EstwId);

                            if (estw2 == null || !estw2.Blocks.ContainsKey(block.Name))
                            {
                                continue;
                            }

                            LiveTrain.BlockHistory.AddIfNotNull(estw2.Blocks[block.Name].FirstOrDefault(b => b.Direction == block.Direction));
                        }
                    }

                    if (SerializedTrain.Block != null && Estw.Blocks.ContainsKey(SerializedTrain.Block))
                    {
                        LiveTrain.Block = Estw.Blocks[SerializedTrain.Block].FirstOrDefault(b => b.Direction == SerializedTrain.BlockDirection);
                    }

                    var SchedulesResult = CalculationBll.GetSchedulesByTime(Train.Schedules, Estw?.Time ?? SerializedTrain.LastModified);
                    ValidateResult(SchedulesResult);

                    foreach (var SerializedSchedule in SerializedTrain.Schedules)
                    {
                        var Schedule = SchedulesResult.Result.FirstOrDefault(s => s.Station.ShortSymbol == SerializedSchedule.StationShortSymbol &&
                                                                             s.Time == SerializedSchedule.StationTime &&
                                                                             (s.Station.ESTW.Id == SerializedSchedule.EstwId || SerializedSchedule.EstwId == null));

                        if (Schedule == null)
                        {
                            continue;
                        }

                        var LiveSchedule = new LiveSchedule(LiveTrain, Schedule);
                        LiveSchedule.LiveArrival        = SerializedSchedule.LiveArrival;
                        LiveSchedule.LiveDeparture      = SerializedSchedule.LiveDeparture;
                        LiveSchedule.IsArrived          = SerializedSchedule.IsArrived;
                        LiveSchedule.IsDeparted         = SerializedSchedule.IsDeparted;
                        LiveSchedule.ExpectedArrival    = SerializedSchedule.ExpectedArrival;
                        LiveSchedule.ExpectedDeparture  = SerializedSchedule.ExpectedDeparture;
                        LiveSchedule.IsComposed         = SerializedSchedule.IsComposed;
                        LiveSchedule.IsPrepared         = SerializedSchedule.IsPrepared;
                        LiveSchedule.IsCancelled        = SerializedSchedule.IsCancelled;
                        LiveSchedule.IsManuallyModified = SerializedSchedule.IsManuallyModified;

                        if (SerializedSchedule.ExpectedDelay.HasValue)
                        {
                            // Ensure compatibility
                            LiveSchedule.ExpectedDelayDeparture = SerializedSchedule.ExpectedDelay;
                        }
                        else
                        {
                            LiveSchedule.ExpectedDelayArrival   = SerializedSchedule.ExpectedDelayArrival;
                            LiveSchedule.ExpectedDelayDeparture = SerializedSchedule.ExpectedDelayDeparture;
                        }

                        if (SerializedSchedule.LiveTrack.IsNotNullOrEmpty())
                        {
                            LiveSchedule.LiveTrack = Schedule.Station.Tracks.SingleOrDefault(t => t.Name == SerializedSchedule.LiveTrack);
                        }

                        if (LiveSchedule.LiveArrival != null)
                        {
                            LiveSchedule.IsArrived = true;
                        }
                        if (LiveSchedule.LiveDeparture != null)
                        {
                            LiveSchedule.IsDeparted = true;
                        }

                        foreach (var SerializedDelay in SerializedSchedule.Delays)
                        {
                            var Delay = LiveSchedule.AddDelay(SerializedDelay.Minutes, SerializedDelay.Type);
                            Delay.Reason   = SerializedDelay.Reason;
                            Delay.CausedBy = SerializedDelay.CausedBy;
                        }

                        LiveTrain.AddSchedule(LiveSchedule);
                    }

                    if (Estw != null)
                    {
                        // Don't validate result here. When this fails, it's not so dramatic...
                        var prevResult = CalculationBll.GetPreviousService(Train, Estw);
                        if (prevResult.Succeeded)
                        {
                            LiveTrain.PreviousService = prevResult.Result;
                        }

                        var followUpResult = CalculationBll.GetFollowUpService(Train, Estw);
                        if (followUpResult.Succeeded)
                        {
                            LiveTrain.FollowUpService = followUpResult.Result;
                        }
                    }

                    if (LiveTrain.Schedules.Any())
                    {
                        Area.LiveTrains.TryAdd(Train.Number, LiveTrain);
                    }
                }

                foreach (var Estw in Area.ESTWs)
                {
                    if (Estw.StartTime == null)
                    {
                        var schedules = Area.LiveTrains.Values.SelectMany(t => t.Schedules).Where(s => s.Schedule.Station.ESTW == Estw);

                        if (schedules.Any())
                        {
                            Estw.StartTime = schedules.Min(s => s.LiveArrival);

                            var minStartTime = Estw.Time.AddHours(-12);

                            if (Estw.StartTime < minStartTime)
                            {
                                Estw.StartTime = minStartTime;
                            }
                        }
                        else
                        {
                            Estw.StartTime = Estw.Time;
                        }
                    }
                }

                Container.Area            = Area;
                Container.VisibleStations = Root.VisibleStations;
                Container.VisibleTrains   = Root.VisibleTrains;
                Container.HiddenSchedules = Root.HiddenSchedules;
                Container.Windows         = Root.Windows;
                Container.IsOldVersion    = Root.Version != Assembly.GetEntryAssembly().GetCustomAttribute <AssemblyInformationalVersionAttribute>()?.InformationalVersion;

                var Result = new OperationResult <SerializationContainer>();
                Result.Result    = Container;
                Result.Succeeded = true;
                return(Result);
            }
            catch (Exception ex)
            {
                return(new OperationResult <SerializationContainer> {
                    Message = ex.Message
                });
            }
        }