public void Refresh(Area Area) { var SettingsResult = m_SettingsBll.GetSettings(); if (!SettingsResult.Succeeded) { MessageBox.Show(SettingsResult.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); return; } var Settings = SettingsResult.Result; var CurrentSchedules = new List <TrainScheduleStationViewModel>(); var Estw = Area.ESTWs.FirstOrDefault(estw => estw.Time != null); if (Estw == null) { return; } var SchedulesResult = m_CalculationBll.GetSchedulesByTime(CurrentTrain.Schedules, Estw.Time); if (!SchedulesResult.Succeeded) { Dispatcher.Invoke(() => MessageBox.Show(SchedulesResult.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error)); return; } bool HasStartStation = SchedulesResult.Result.Any(s => s.Handling == eHandling.Start); bool HasDestinationStation = SchedulesResult.Result.Any(s => s.Handling == eHandling.Destination); TrainScheduleStationViewModel FirstStationSchedule = null; TrainScheduleStationViewModel FirstStationDummy = null; TrainScheduleStationViewModel LastStationSchedule = null; TrainScheduleStationViewModel LastStationDummy = null; if (!HasStartStation && CurrentTrain.Start != null) { FirstStationSchedule = Stations.FirstOrDefault(); FirstStationDummy = Stations.ElementAtOrDefault(1); if (FirstStationSchedule == null || FirstStationSchedule.HasSchedule) { FirstStationDummy = new TrainScheduleStationViewModel(); FirstStationSchedule = new TrainScheduleStationViewModel(CurrentTrain.Start, false); Dispatcher.Invoke(() => Stations.Insert(0, FirstStationDummy)); Dispatcher.Invoke(() => Stations.Insert(0, FirstStationSchedule)); } CurrentSchedules.Add(FirstStationDummy); CurrentSchedules.Add(FirstStationSchedule); } if (!HasDestinationStation && CurrentTrain.Destination != null) { LastStationSchedule = Stations.LastOrDefault(); LastStationDummy = Stations.ElementAtOrDefault(Stations.Count - 2); if (LastStationSchedule == null || LastStationSchedule.HasSchedule || LastStationSchedule == FirstStationDummy) { LastStationDummy = new TrainScheduleStationViewModel(); LastStationSchedule = new TrainScheduleStationViewModel(CurrentTrain.Destination, true); Dispatcher.Invoke(() => Stations.Add(LastStationDummy)); Dispatcher.Invoke(() => Stations.Add(LastStationSchedule)); } CurrentSchedules.Add(LastStationDummy); CurrentSchedules.Add(LastStationSchedule); } bool PreviousVisible = false; bool DummyFlag = false; bool Reorder = false; // Group schedules by station and time to avoid duplicate entries for stations that are located between ESTW bordery stations when both ESTWs are loaded // i.e. Bosserode and Obersuhl are located between Hönebach (ESTW Bebra) and Gerstungen (ESTW Eisenach) foreach (var ScheduleGroup in SchedulesResult.Result.GroupBy(s => new { s.Station.ShortSymbol, s.Time })) { bool GroupVisible = false; foreach (var Schedule in ScheduleGroup) { if (Schedule.Station == null) { continue; } bool Visible = true; bool IsNew = false; var Current = Stations.FirstOrDefault(s => s.CurrentSchedule == Schedule); if (Current == null) { Current = new TrainScheduleStationViewModel(Schedule); Current.PropertyChanged += __Station_PropertyChanged; IsNew = true; } else if (Reorder) { Dispatcher.Invoke(() => Stations.Remove(Current)); IsNew = true; } Current.Departure = Schedule.Departure; // For special trains schedule is generated at runtime if (!Settings.DisplayCompleteTrainSchedule && !Schedule.Station.ESTW.Stations.Any(s => Runtime.VisibleStations.Contains(s))) { Visible = Schedule.Handling == eHandling.Start || Schedule.Handling == eHandling.Destination; } if (Area.LiveTrains.ContainsKey(CurrentTrain.Number)) { m_LiveTrain = Area.LiveTrains[CurrentTrain.Number]; var LiveSchedule = m_LiveTrain.Schedules.FirstOrDefault(s => s.Schedule == Schedule); if (LiveSchedule != null) { if (FirstStationSchedule != null) { FirstStationSchedule.IsArrived = m_LiveTrain.Schedules.Any(s => s.IsArrived); FirstStationSchedule.IsDeparted = FirstStationSchedule.IsArrived; } if (FirstStationDummy != null) { FirstStationDummy.IsArrived = m_LiveTrain.Schedules.Any(s => s.IsArrived); FirstStationDummy.IsDeparted = FirstStationDummy.IsArrived; } if (LiveSchedule.ExpectedArrival != null && Schedule.Arrival != null) { Current.DelayArrival = (LiveSchedule.ExpectedArrival - Schedule.Arrival).TotalMinutes; } else { Current.DelayArrival = null; } if (LiveSchedule.ExpectedDeparture != null && Schedule.Departure != null) { Current.DelayDeparture = (LiveSchedule.ExpectedDeparture - Schedule.Departure).TotalMinutes; } else { Current.DelayDeparture = null; } Current.IsDelayManuallySet = LiveSchedule.ExpectedDelay.HasValue && !LiveSchedule.IsDeparted; var Index = m_LiveTrain.Schedules.IndexOf(LiveSchedule); if (m_LiveTrain.Schedules.Where((schedule, index) => index > Index && (schedule.Schedule.Station.ShortSymbol != Schedule.Station.ShortSymbol || schedule.Schedule.Time != Schedule.Time) && schedule.IsArrived).Any()) { Current.IsArrived = true; Current.IsDeparted = true; var isSkipped = !LiveSchedule.IsArrived && !LiveSchedule.IsDeparted; if (Current.IsSkipped && !isSkipped) { // Trigger re-ordering of this and all subsequent entries Dispatcher.Invoke(() => Stations.Remove(Current)); IsNew = true; Reorder = true; } Current.IsSkipped = isSkipped; } else { Current.IsArrived = LiveSchedule.IsArrived; Current.IsDeparted = LiveSchedule.IsDeparted; } Current.LiveTrack = LiveSchedule.LiveTrack; var Minutes = LiveSchedule.Delays.Sum(d => d.Minutes); if (LiveSchedule.Delays.Any(d => d.Reason.IsNullOrWhiteSpace()) && Schedule.Station.ESTW.Stations.Any(s => Runtime.VisibleStations.Contains(s))) { Current.DelayInfo = String.Format("+{0} Bitte begründen!", Minutes); Dispatcher.Invoke(() => Current.IsDelayJustified = false); } else if (LiveSchedule.Delays.Any(d => d.Reason.IsNotNullOrWhiteSpace())) { Current.DelayInfo = String.Format("+{0} {1}", Minutes, String.Join(", ", LiveSchedule.Delays.Where(d => d.Reason.IsNotNullOrWhiteSpace()).Select(d => { string result = d.Reason; if (d.CausedBy.HasValue) { result += String.Format(" ({0})", d.CausedBy); } return(result); }))); Dispatcher.Invoke(() => Current.IsDelayJustified = true); } else { Current.DelayInfo = null; } } } GroupVisible |= Visible; if (Visible) { if (IsNew) { int Index = -1; if (Current.LiveTime != null) { for (int i = 0; i < Stations.Count; i++) { if (Stations[i].HasSchedule && Stations[i].LiveTime > Current.LiveTime) { Index = i; break; } } } if (Index == -1) { for (int i = 0; i < Stations.Count; i++) { if (Stations[i].HasSchedule && Stations[i].CurrentSchedule.Time > Current.CurrentSchedule.Time) { Index = i; break; } } } if (Index == -1) { Index = Stations.Count; } Dispatcher.Invoke(() => Stations.Insert(Index, Current)); } CurrentSchedules.Add(Current); if (DummyFlag) { var Index = Stations.IndexOf(Current); var Dummy = Stations.ElementAtOrDefault(Index - 1); if (Dummy == null || Dummy.HasStation) { Dummy = new TrainScheduleStationViewModel(); Dispatcher.Invoke(() => Stations.Insert(Index, Dummy)); } Dummy.IsArrived = Current.IsArrived; Dummy.IsDeparted = Current.IsArrived; CurrentSchedules.Add(Dummy); DummyFlag = false; } break; } } if (!GroupVisible && PreviousVisible) { DummyFlag = true; } PreviousVisible = GroupVisible; } var RemovedItems = Stations.Except(CurrentSchedules).ToList(); Dispatcher.Invoke(() => RemovedItems.ForEach(s => Stations.Remove(s))); }
public void Refresh(Area Area) { var CurrentSchedules = new List <TimeTableItemViewModel>(); var SchedulesResult = m_CalculationBll.GetSchedulesByTime(CurrentStation.Schedules, CurrentStation.ESTW.Time); if (!SchedulesResult.Succeeded) { Dispatcher.Invoke(() => MessageBox.Show(SchedulesResult.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error)); return; } foreach (var Schedule in SchedulesResult.Result) { if (Schedule.Train == null) { continue; } bool Visible = true; bool IsNew = false; if (Schedule.Time < CurrentStation.ESTW.Time) { Visible = false; } var Current = Schedules.FirstOrDefault(s => s.TrainNumber == Schedule.Train.Number); if (Current == null) { Current = new TimeTableItemViewModel(Schedule); IsNew = true; } if (Area.LiveTrains.ContainsKey(Current.TrainNumber)) { var LiveTrain = Area.LiveTrains[Current.TrainNumber]; Current.Delay = LiveTrain.Delay; var LiveSchedule = LiveTrain.Schedules.FirstOrDefault(s => s.Schedule == Schedule); if (LiveSchedule != null) { Visible = true; Current.LiveTrack = LiveSchedule.LiveTrack; var Index = LiveTrain.Schedules.IndexOf(LiveSchedule); if (LiveSchedule.LiveDeparture != null || LiveTrain.Schedules.Where((s, i) => i > Index && s.LiveArrival != null).Count() > 0) { Visible = false; } } LeibitTime ActualTime; if (LiveTrain.Block != null && LiveTrain.Block.Track != null) { ActualTime = LiveTrain.Block.Track.Station.ESTW.Time; } else { ActualTime = Area.ESTWs.Where(e => e.IsLoaded).DefaultIfEmpty().Max(e => e.Time); } if (ActualTime != null && LiveTrain.LastModified != null && ActualTime > LiveTrain.LastModified.AddMinutes(1)) { Visible = false; } if (Visible) { var DelayInfos = LiveTrain.Schedules.SelectMany(s => s.Delays).Where(d => d.Reason.IsNotNullOrWhiteSpace()).Select(d => d.Reason); if (DelayInfos.Count() > 0) { Current.DelayReason = String.Join(", ", DelayInfos); } var StartSchedule = LiveTrain.Schedules.SingleOrDefault(s => s.Schedule.Handling == eHandling.Start && s.Schedule.Station == CurrentStation); Current.IsReady = StartSchedule != null && StartSchedule.Schedule.Station.ESTW.Time >= StartSchedule.Schedule.Departure.AddMinutes(-2); } } if (Visible) { if (IsNew) { Dispatcher.Invoke(() => Schedules.Add(Current)); } CurrentSchedules.Add(Current); } } var RemovedItems = Schedules.Except(CurrentSchedules).ToList(); Dispatcher.Invoke(() => RemovedItems.ForEach(s => Schedules.Remove(s))); }
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); }