public object BackupTimetable() { var backupHandle = new object(); timetableBackup[backupHandle] = Timetable.Clone(); return(backupHandle); }
public bool Export(Timetable tt, string filename, IInfo info) { if (tt.Type == TimetableType.Network) { throw new Exception("Der Fahrplan ist bereits ein Netzwerk-Fahrplan"); } var clone = tt.Clone(); var trainPaths = new Dictionary <Train, TrainPathData>(); foreach (var orig in clone.Trains) { trainPaths[orig] = new TrainPathData(clone, orig); } var rt = Timetable.LINEAR_ROUTE_ID.ToString(); var id = 0; var y = 0; foreach (var sta in clone.Stations) { ConvertStationLinToNet(sta); sta.SetAttribute("fpl-rt", rt); sta.SetAttribute("fpl-pos", (y += 40).ToString() + ";0"); sta.SetAttribute("fpl-id", id++.ToString()); } var actions = info.GetRegistered <ITimetableTypeChangeAction>(); foreach (var action in actions) { action.ToNetwork(clone); } clone.SetAttribute("version", TimetableVersion.Extended_FPL.ToNumberString()); foreach (var train in clone.Trains) { var data = trainPaths[train]; train.Children.Clear(); train.AddAllArrDeps(data.GetRawPath()); train.XMLEntity.XName = "tr"; foreach (var sta in data.PathEntries) { if (sta.ArrDep != null) { train.GetArrDep(sta.Station).ApplyCopy(sta.ArrDep); } } } ColorTimetableConverter.ConvertAll(clone); return(new XMLExport().Export(clone, filename, info)); }
public bool Export(Timetable tt, string filename, IInfo info) { if (info.Timetable.Type == TimetableType.Network) { MessageBox.Show("Der aktuelle Fahrplan ist ein Netzwerk-Fahrplan. Aus diesem erweiterten Fahrplanformat können aus technischen Gründen nicht alle von FPLedit angelegten Daten gelöscht werden."); return(false); } var res = MessageBox.Show("Hiermit werden alle in FPLedit zusätzlich eingebenen Werte (z.B. Lokomotiven, Lasten, Mindestbremshundertstel, Geschwindigkeiten, Wellenlinien, Trapeztafelhalte und Zuglaufmeldungen) und Buchfahrplaneinstellungen aus dem gespeicherten Fahrplan gelöscht! Fortfahren?", "FPLedit", MessageBoxButtons.YesNo, MessageBoxType.Warning); if (res == DialogResult.No) { return(false); } bool debug = info.Settings.Get <bool>("xml.indent"); #if DEBUG debug = true; #endif try { var clone = tt.Clone(); // Klon zum anschließenden Verwerfen! var ttElm = BuildNode(clone.XMLEntity); using (var writer = new XmlTextWriter(filename, new UTF8Encoding(false))) { if (debug) { writer.Formatting = Formatting.Indented; } ttElm.Save(writer); } return(true); } catch (Exception ex) { info.Logger.Error("XMLExport: " + ex.Message); return(false); } }
public bool Export(Timetable tt, string filename, IInfo info) { if (tt.Version.Compare(TimetableVersion.JTG3_1) >= 0) { throw new Exception("Nur mit jTrainGraph 2.x oder 3.0x erstellte Fahrpläne können aktualisiert werden."); } var origVersion = tt.Version; var clone = tt.Clone(); clone.SetAttribute("version", "010"); if (origVersion == TimetableVersion.JTG2_x) { var shv = clone.GetAttribute <bool>("shV"); clone.SetAttribute("shV", shv ? "1" : "0"); // km -> kml/kmr foreach (var sta in clone.Stations) { var km_old = sta.GetAttribute("km", ""); sta.SetAttribute("kml", km_old); sta.SetAttribute("kmr", km_old); sta.RemoveAttribute("km"); } // Allocate train ids var nextId = clone.Trains.DefaultIfEmpty().Max(t => t?.Id) ?? 0; foreach (var orig in clone.Trains) { if (orig.Id == -1) { orig.Id = ++nextId; } } } ColorTimetableConverter.ConvertAll(clone); return(new XMLExport().Export(clone, filename, info)); }
public async Task UpdateStudentTimetableAsync(Student studentToUpdate, Timetable studentTimetable) { studentToUpdate.Timetable = studentTimetable.Clone(); await UpdateStudentAsync(studentToUpdate); }
public void FlatSqueezedFitCourses(List<Course> courses, Timetable timetable, int resolution) { ClearTables(); bool allCoursesFitted = true; // We will keep squeezing the timetable as long as all the courses got fitted. while (allCoursesFitted) { // First we will get all the timeunits that exist in the timetable IEnumerable<TimeUnit> timeUnits = (from day in timetable.Days from room in day.Rooms from time in room.Time select time); // and find the one that has the largest duration. timeUnits = timeUnits.Where(unit => unit.Duration() > resolution); TimeUnit max = timeUnits.Aggregate((x, y) => x.Duration() > y.Duration() ? x : y); // If this timeunit's duration is large enough the be squeezed, then squeeze. if (max.Shorten(resolution)) { Timetable clone = (Timetable)timetable.Clone(); // We need to know if all the courses got fitted with this version of the timetable. allCoursesFitted = FitCourses(courses, clone); } } UniquelyGeneratedTables = getUniques(GeneratedTables); }
/// <summary> /// list of courses /// timetable /// /// for each course in the list of courses /// try to fit this course in the timetable /// fit is found: /// fit course in a copy of the timetable /// make a copy of the list of courses and remove the reference to this course (shallow) /// call this method with the copied list and timetable /// fit is not found: /// try the next course in the list of courses /// </summary> private bool FitCourses(List<Course> courses, Timetable timetable) { int before = GeneratedTables.Count; if (courses.Any()) { foreach (Course course in courses) { // TODO: optimise for speed by combining check and actually fitting if (timetable.CanFit(course)) { // Clone the list of courses left to fit List<Course> coursesLeft = (List<Course>)courses.Clone(); // Remove the course that's going to be fitted from this cloned list coursesLeft.Remove(course); // Clone the timetable Timetable newTimetable = (Timetable)timetable.Clone(); // Fit the course in the cloned timetable newTimetable.Fit(course); // Try to fit the remaining courses FitCourses(coursesLeft, newTimetable); } } } else { bool added = GeneratedTables.Add(timetable); string output = String.Format("Item was added? {0}", added); Console.Out.WriteLine(output); } return before < GeneratedTables.Count; }
public void PushedFitCourses(List<Course> courses, Timetable timetable, int resolution) { ClearTables(); bool allCoursesFitted = false; // We will traverse the timetable one timeunit at a time. foreach (Day day in timetable.Days) { foreach (BookableRoom room in day.Rooms) { foreach (TimeUnit time in room.Time) { // And should the timeunit's duration be large enough to be squeezed, we will squeeze it. while (time.Shorten(resolution)) { Timetable clone = (Timetable)timetable.Clone(); // And try to fit the courses again. clone = (Timetable)timetable.Clone(); allCoursesFitted = FitCourses(courses, clone); // In the event that not all courses got fitted, we will backtrack this last squeeze and move on // to the next timeunit. if (!allCoursesFitted) { time.Lengthen(resolution); break; } } } } } UniquelyGeneratedTables = getUniques(GeneratedTables); }
public Timetable GetRouteTimetable(TimetableVersion targetVersion) { var copy = orig.Clone(); var route = copy.GetRoute(routeIndex); for (int si = 0; si < copy.Stations.Count; si++) { var sta = copy.Stations[si]; if (!route.Stations.Contains(sta)) { copy.RemoveStation(sta); si--; continue; } } // XML-Elemente wirklich sortieren. In copy.Stations wird nicht zurückgesynct, // daher eine eigene sortierte Liste für später var sortedStations = copy.Stations.OrderBy(s => s.Positions.GetPosition(routeIndex)).ToList(); var stasElm = copy.Children.First(x => x.XName == "stations"); stasElm.Children = stasElm.Children.OrderBy(c => { if (c.XName == "sta") { return(copy.Stations.FirstOrDefault(s => s.XMLEntity == c)?.Positions.GetPosition(routeIndex)); } return(null); }).ToList(); int syncId = 0; for (int ti = 0; ti < copy.Trains.Count; ti++) { var tra = copy.Trains[ti]; var ardps = tra.GetArrDeps(); var path = tra.GetPath(); var pf = path.FirstOrDefault(); var pl = path.LastOrDefault(); var isEmpty = pf != null && pl != null && ((ardps[pf].Arrival != default && ardps[pf].Departure == default) || (ardps[pl].Departure != default && ardps[pl].Arrival == default)); if (ardps.Count == 0 || ardps.All(a => !a.Value.HasMinOneTimeSet) || isEmpty) // Dieser Zug berührt diese Route nicht { copy.RemoveTrain(tra); ti--; continue; } tra.SetAttribute("fpl-sync-id", syncId++.ToString()); trainMap.Add(tra); // Der Index wird immer um 1 hochegzählt, daher brauchts hier kein Dictionary // Fahrtzeiteneinträge setzen tra.Children.Clear(); tra.AddAllArrDeps(sortedStations); foreach (var ardp in ardps) { if (sortedStations.Contains(ardp.Key)) { tra.GetArrDep(ardp.Key).ApplyCopy(ardp.Value); } } // Lineare Fahrtrichtung bestimmen var sta1 = ardps.FirstOrDefault().Key; var sta2 = ardps.LastOrDefault().Key; var dir = TrainDirection.ti; if (sta1 != sta2) { if (sortedStations.IndexOf(sta1) > sortedStations.IndexOf(sta2)) { dir = TrainDirection.ta; } } else if (sortedStations.IndexOf(sta1) == sortedStations.Count - 1) { dir = TrainDirection.ta; } tra.XMLEntity.XName = dir.ToString(); } // Am Ende die Kilometer & anderen Attribute auf den linearen Stil setzen foreach (var sta in copy.Stations) { ConvertStationNetToLin(sta, routeIndex, targetVersion); } copy.SetAttribute("version", targetVersion.ToNumberString()); // Wir gehen aus dem Extended-Modus raus ColorTimetableConverter.ConvertAll(copy); // Zum Ziel-Farbformat konvertieren return(copy); }
public void InitPrint() { var form = new FDialog <bool>(); var routesDropDown = new RoutesDropDown(); var routeStack = new StackLayout(routesDropDown) { Orientation = Orientation.Horizontal, Padding = new Eto.Drawing.Padding(10), Spacing = 5 }; var routeGroup = new GroupBox { Content = routeStack, Text = T._("Strecke auswählen") }; var widthLabel = new Label { Text = T._("Breite des Bildes (px)") }; var widthTextBox = new TextBox { Text = "1000" }; var exportButton = new Button { Text = T._("Exportieren") }; var printerStack = new StackLayout(widthLabel, widthTextBox, exportButton) { Orientation = Orientation.Horizontal, Padding = new Eto.Drawing.Padding(10), Spacing = 5 }; var printerGroup = new GroupBox { Content = printerStack, Text = T._("Exporteinstellungen") }; var stack = new StackLayout(routeGroup, printerGroup) { Orientation = Orientation.Vertical, Padding = new Eto.Drawing.Padding(10), Spacing = 5 }; routesDropDown.Initialize(pluginInterface); routesDropDown.EnableVirtualRoutes = true; form.Content = stack; form.DefaultButton = exportButton; form.Title = T._("Bildfahrplan drucken"); exportButton.Click += (s, e) => { form.Result = true; form.Close(); }; if (form.ShowModal()) { var width = 0; int.TryParse(widthTextBox.Text, out width); if (width == 0) { pluginInterface.Logger.Error("Ungültige Breite angegeben!"); return; } var exportFileDialog = new SaveFileDialog { Title = T._("Bildfahrplan exportieren") }; exportFileDialog.Filters.Add(new FileFilter("PNG-Datei", ".png")); if (exportFileDialog.ShowDialog(pluginInterface.RootForm) == DialogResult.Ok) { var filename = exportFileDialog.FileName; var export = new BitmapExport(routesDropDown.SelectedRoute, width, ImageFormat.Png); pluginInterface.Logger.Info(T._("Exportiere Bildfahrplan in Datei {0}", filename)); var tsk = export.GetAsyncSafeExport(tt.Clone(), filename, pluginInterface); tsk.ContinueWith((t, o) => { if (t.Result == false) { pluginInterface.Logger.Error(T._("Exportieren des Bildfahrplans fehlgeschlagen!")); } else { pluginInterface.Logger.Info(T._("Exportieren des Bildfahrplans erfolgreich abgeschlossen!")); } }, null, TaskScheduler.Default); tsk.Start(); // Non-blocking operation. } } }
// Speichert den aktuellen Status, *vor* der Veränderung aufzurufen! public void StageUndoStep(Timetable tt) { stagedStep = tt.Clone(); }
public void Equals_InHashSet() { HashSet<Timetable> set = new HashSet<Timetable>(); Assert.IsTrue(set.Add(table1)); Assert.IsFalse(set.Add(table1)); Assert.IsFalse(set.Add((Timetable)table1.Clone())); Assert.IsTrue(set.Add(table2)); Timetable table3 = new Timetable(new List<Day>() { day1, day2 }); Assert.IsFalse(set.Add(table3)); Timetable table4 = new Timetable(new List<Day>() { (Day) day1.Clone(), (Day) day2.Clone() }); Assert.IsFalse(set.Add(table4)); Timetable table5 = (Timetable) table4.Clone(); Timetable table6 = (Timetable) table4.Clone(); table5.Fit(course1); table6.Fit(course1); Assert.IsTrue(set.Add(table5)); Assert.IsFalse(set.Add(table6)); }
public bool Export(Timetable tt, Stream stream, IReducedPluginInterface pluginInterface, string[] flags = null) { if (tt.Type == TimetableType.Linear) { throw new TimetableTypeNotSupportedException(TimetableType.Linear, "convert to linear"); } if (tt.GetRoutes().Length != 1) { throw new NotSupportedException(T._("Der Fahrplan hat mehr als eine oder keine Strecke")); } if (tt.Version.CompareTo(TimetableVersion.Extended_FPL2) >= 0 && Timetable.DefaultLinearVersion.CompareTo(TimetableVersion.JTG3_3) < 0) { throw new NotSupportedException(T._("Eine Fahrplandatei der Version >= 101 kann nicht als lineare Datei <= 012 exportiert werden!")); } var clone = tt.Clone(); var trainPaths = new Dictionary <ITrain, TrainPathData>(); foreach (var orig in clone.Trains) { trainPaths[orig] = new TrainPathData(clone, orig); } var route = clone.GetRoutes().Single().Index; foreach (var sta in clone.Stations) { ConvertStationNetToLin(sta, route); sta.RemoveAttribute("fpl-rt"); sta.RemoveAttribute("fpl-pos"); sta.RemoveAttribute("fpl-id"); } var actions = pluginInterface.GetRegistered <ITimetableTypeChangeAction>(); foreach (var action in actions) { action.ToLinear(clone); } clone.SetVersion(Timetable.DefaultLinearVersion); var sortedStations = clone.GetRoutes()[Timetable.LINEAR_ROUTE_ID].Stations; foreach (var t in clone.Trains) { var data = trainPaths[t]; var sta1 = data.PathEntries.FirstOrDefault()?.Station; var sta2 = data.PathEntries.LastOrDefault()?.Station; var dir = TrainDirection.ti; if (sta1 != sta2) { if (sortedStations.IndexOf(sta1) > sortedStations.IndexOf(sta2)) { dir = TrainDirection.ta; } } else if (sortedStations.IndexOf(sta1) == sortedStations.Count - 1) { dir = TrainDirection.ta; } t.XMLEntity.XName = dir.ToString(); if (!(t is IWritableTrain wt)) { continue; } wt.Children.Clear(); // Clear all existing arrdeps... wt.AddLinearArrDeps(); // ...and re-add all linear ones. foreach (var sta in data.PathEntries) { if (sta.ArrDep != null) { t.GetArrDep(sta.Station).ApplyCopy(sta.ArrDep); } } } return(new XMLExport().Export(clone, stream, pluginInterface)); }
public bool Export(Timetable tt, string filename, IInfo info) { if (tt.Type == TimetableType.Linear) { throw new Exception("Der Fahrplan ist bereits ein Linear-Fahrplan"); } if (tt.GetRoutes().Count() != 1) { throw new Exception("Der Fahrplan hat mehr als eine oder keine Strecke"); } var clone = tt.Clone(); var trainPaths = new Dictionary <Train, TrainPathData>(); foreach (var orig in clone.Trains) { trainPaths[orig] = new TrainPathData(clone, orig); } var route = clone.GetRoutes().FirstOrDefault().Index; foreach (var sta in clone.Stations) { ConvertStationNetToLin(sta, route, Timetable.DefaultLinearVersion); sta.RemoveAttribute("fpl-rt"); sta.RemoveAttribute("fpl-pos"); sta.RemoveAttribute("fpl-id"); } var actions = info.GetRegistered <ITimetableTypeChangeAction>(); foreach (var action in actions) { action.ToLinear(clone); } clone.SetAttribute("version", Timetable.DefaultLinearVersion.ToNumberString()); var sortedStations = clone.GetRoutes()[Timetable.LINEAR_ROUTE_ID].GetOrderedStations(); foreach (var t in clone.Trains) { var data = trainPaths[t]; var sta1 = data.PathEntries.FirstOrDefault()?.Station; var sta2 = data.PathEntries.LastOrDefault()?.Station; var dir = TrainDirection.ti; if (sta1 != sta2) { if (sortedStations.IndexOf(sta1) > sortedStations.IndexOf(sta2)) { dir = TrainDirection.ta; } } else if (sortedStations.IndexOf(sta1) == sortedStations.Count - 1) { dir = TrainDirection.ta; } t.XMLEntity.XName = dir.ToString(); t.Children.Clear(); t.AddLinearArrDeps(); foreach (var sta in data.PathEntries) { if (sta.ArrDep != null) { t.GetArrDep(sta.Station).ApplyCopy(sta.ArrDep); } } } ColorTimetableConverter.ConvertAll(clone); return(new XMLExport().Export(clone, filename, info)); }
public bool Export(Timetable tt, Stream stream, IReducedPluginInterface pluginInterface, string[] flags = null) { if (tt.Type == TimetableType.Network) { throw new TimetableTypeNotSupportedException(TimetableType.Network, "convert to network"); } if (tt.Version.CompareTo(TimetableVersion.JTG3_3) <= 0) { pluginInterface.Logger.Error(T._("Bitte zuerst die lineare Strecke auf die neueste Version aktualisieren!")); return(false); } var clone = tt.Clone(); var trainPaths = new Dictionary <ITrain, TrainPathData>(); foreach (var orig in clone.Trains) { trainPaths[orig] = new TrainPathData(clone, orig); } var rt = Timetable.LINEAR_ROUTE_ID.ToString(); var id = 0; var y = 0; foreach (var sta in clone.Stations) { ConvertStationLinToNet(sta); sta.SetAttribute("fpl-rt", rt); // Normally this would need a cache invalidation, but here it does not. sta.SetAttribute("fpl-pos", (y += 40).ToString() + ";0"); sta.SetAttribute("fpl-id", id++.ToString()); } var actions = pluginInterface.GetRegistered <ITimetableTypeChangeAction>(); foreach (var action in actions) { action.ToNetwork(clone); } clone.SetVersion(TimetableVersion.Extended_FPL2); foreach (var train in clone.Trains) { var data = trainPaths[train]; if (!(train is IWritableTrain wt)) { continue; } wt.Children.Clear(); wt.AddAllArrDeps(data.GetRawPath()); wt.XMLEntity.XName = "tr"; foreach (var sta in data.PathEntries) { if (sta.ArrDep != null) { wt.GetArrDep(sta.Station).ApplyCopy(sta.ArrDep); } } } return(new XMLExport().Export(clone, stream, pluginInterface)); }