Пример #1
0
        public object BackupTimetable()
        {
            var backupHandle = new object();

            timetableBackup[backupHandle] = Timetable.Clone();
            return(backupHandle);
        }
Пример #2
0
        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));
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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));
        }
Пример #5
0
 public async Task UpdateStudentTimetableAsync(Student studentToUpdate, Timetable studentTimetable)
 {
     studentToUpdate.Timetable = studentTimetable.Clone();
     await UpdateStudentAsync(studentToUpdate);
 }
Пример #6
0
        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);
        }
Пример #7
0
 /// <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;
 }
Пример #8
0
        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);
        }
Пример #9
0
        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);
        }
Пример #10
0
        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.
                }
            }
        }
Пример #11
0
 // Speichert den aktuellen Status, *vor* der Veränderung aufzurufen!
 public void StageUndoStep(Timetable tt)
 {
     stagedStep = tt.Clone();
 }
Пример #12
0
        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));
        }
Пример #13
0
        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));
        }
Пример #14
0
        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));
        }
Пример #15
0
        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));
        }