/// <summary> /// Läd eine XML Datei und versucht daraus den gespeicherten Zustand wiederherzustellen /// </summary> /// <param name="xd">XmlDocument mit den zu ladenden Daten</param> /// <param name="lf">LoadingForm für Statusinformationen</param> public List<Auftrag> LoadFromFile(XmlDocument xd, LoadingForm.LoadingForm lf) { lf.SetupLowerProgess("Parsing XML...", 3); List<Auftrag> toReturn = new List<Auftrag>(); int saveVersion = 0; // erstma alles vorhandene löschen nodes.Clear(); connections.Clear(); intersections.Clear(); _networkLayers.Clear(); XmlNode mainNode = xd.SelectSingleNode("//CityTrafficSimulator"); XmlNode saveVersionNode = mainNode.Attributes.GetNamedItem("saveVersion"); if (saveVersionNode != null) saveVersion = Int32.Parse(saveVersionNode.Value); else saveVersion = 0; XmlNode titleNode = xd.SelectSingleNode("//CityTrafficSimulator/Layout/title"); if (titleNode != null) { m_title = titleNode.InnerText; } XmlNode infoNode = xd.SelectSingleNode("//CityTrafficSimulator/Layout/infoText"); if (infoNode != null) { _infoText = infoNode.InnerText; } lf.StepLowerProgress(); // entsprechenden Node auswählen XmlNodeList xnlLineNode = xd.SelectNodes("//CityTrafficSimulator/Layout/LineNode"); foreach (XmlNode aXmlNode in xnlLineNode) { // Node in einen TextReader packen TextReader tr = new StringReader(aXmlNode.OuterXml); // und Deserializen XmlSerializer xs = new XmlSerializer(typeof(LineNode)); LineNode ln = (LineNode)xs.Deserialize(tr); // ab in die Liste nodes.Add(ln); } lf.StepLowerProgress(); // entsprechenden Node auswählen XmlNodeList xnlNetworkLayer = xd.SelectNodes("//CityTrafficSimulator/Layout/NetworkLayer"); foreach (XmlNode aXmlNode in xnlNetworkLayer) { // Node in einen TextReader packen TextReader tr = new StringReader(aXmlNode.OuterXml); // und Deserializen XmlSerializer xs = new XmlSerializer(typeof(NetworkLayer)); NetworkLayer nl = (NetworkLayer)xs.Deserialize(tr); // ab in die Liste _networkLayers.Add(nl); } lf.StepLowerProgress(); // entsprechenden NodeConnections auswählen XmlNodeList xnlNodeConnection = xd.SelectNodes("//CityTrafficSimulator/Layout/NodeConnection"); foreach (XmlNode aXmlNode in xnlNodeConnection) { // Node in einen TextReader packen TextReader tr = new StringReader(aXmlNode.OuterXml); // und Deserializen XmlSerializer xs = new XmlSerializer(typeof(NodeConnection)); NodeConnection ln = (NodeConnection)xs.Deserialize(tr); // ab in die Liste connections.Add(ln); } lf.SetupLowerProgess("Restoring LineNodes...", _nodes.Count); // Nodes wiederherstellen foreach (LineNode ln in _nodes) { ln.RecoverFromLoad(saveVersion, _nodes); lf.StepLowerProgress(); } lf.SetupLowerProgess("Restoring NetworkLayers...", _networkLayers.Count); // restore NetworkLayers if (saveVersion >= 6) { foreach (NetworkLayer nl in _networkLayers) { foreach (int hash in nl._nodeHashes) { LineNode tmp = GetLineNodeByHash(nodes, hash); if (tmp != null) tmp.networkLayer = nl; } nl.TitleChanged += new NetworkLayer.TitleChangedEventHandler(nl_TitleChanged); nl.VisibleChanged +=new NetworkLayer.VisibleChangedEventHandler(nl_VisibleChanged); } } else { AddNetworkLayer("Layer 1", true); foreach (LineNode ln in _nodes) { ln.networkLayer = _networkLayers[0]; } } InvokeNetworkLayersChanged(new NetworkLayersChangedEventArgs(NetworkLayersChangedEventArgs.InvalidationLevel.COLLECTION_CHANGED)); lf.SetupLowerProgess("Restoring NodeConnections...", _connections.Count); // LineNodes wiederherstellen foreach (NodeConnection nc in _connections) { nc.RecoverFromLoad(saveVersion, nodes); TellNodesTheirConnection(nc); nc.lineSegment = new LineSegment(0, nc.startNode.position, nc.startNode.outSlopeAbs, nc.endNode.inSlopeAbs, nc.endNode.position); lf.StepLowerProgress(); } lf.SetupLowerProgess("Calculate Intersections and Line Change Points...", _connections.Count); // Intersections wiederherstellen foreach (NodeConnection nc in _connections) { UpdateNodeConnection(nc); lf.StepLowerProgress(); } // Fahraufträge laden // entsprechenden Node auswählen if (saveVersion < 5) { XmlNodeList xnlAuftrag = xd.SelectNodes("//CityTrafficSimulator/Traffic/Auftrag"); lf.SetupLowerProgess("Load Old Traffic Volume...", 2 * xnlAuftrag.Count); foreach (XmlNode aXmlNode in xnlAuftrag) { // Node in einen TextReader packen TextReader tr = new StringReader(aXmlNode.OuterXml); // und Deserializen XmlSerializer xs = new XmlSerializer(typeof(Auftrag)); Auftrag ln = (Auftrag)xs.Deserialize(tr); // in alten Dateien wurde das Feld häufigkeit statt trafficDensity gespeichert. Da es dieses Feld heute nicht mehr gibt, müssen wir konvertieren: if (saveVersion < 1) { // eigentlich wollte ich hier direkt mit aXmlNode arbeiten, das hat jedoch komische Fehler verursacht (SelectSingleNode) wählt immer den gleichen aus) // daher der Umweg über das neue XmlDocument. XmlDocument doc = new XmlDocument(); XmlElement elem = doc.CreateElement("Auftrag"); elem.InnerXml = aXmlNode.InnerXml; doc.AppendChild(elem); XmlNode haeufigkeitNode = doc.SelectSingleNode("//Auftrag/häufigkeit"); if (haeufigkeitNode != null) { ln.trafficDensity = 72000 / Int32.Parse(haeufigkeitNode.InnerXml); } haeufigkeitNode = null; } // ab in die Liste toReturn.Add(ln); lf.StepLowerProgress(); } // Nodes wiederherstellen foreach (Auftrag a in toReturn) { a.RecoverFromLoad(saveVersion, nodes); lf.StepLowerProgress(); } } return toReturn; }
/// <summary> /// Loads the traffic volume setup from the given XML file /// </summary> /// <param name="xd">XmlDocument to parse</param> /// <param name="nodesList">List of all existing LineNodes</param> /// <param name="lf">LoadingForm for status updates</param> public void LoadFromFile(XmlDocument xd, List<LineNode> nodesList, LoadingForm.LoadingForm lf) { lf.SetupLowerProgess("Parsing XML...", 3); // clear everything first _trafficVolumes.Clear(); _startPoints.Clear(); _destinationPoints.Clear(); // parse save file version (currently not needed, but probably in future) int saveVersion = 0; XmlNode mainNode = xd.SelectSingleNode("//CityTrafficSimulator"); XmlNode saveVersionNode = mainNode.Attributes.GetNamedItem("saveVersion"); if (saveVersionNode != null) saveVersion = Int32.Parse(saveVersionNode.Value); else saveVersion = 0; // Load start points: lf.StepLowerProgress(); // get corresponding XML nodes XmlNodeList xnlStartNodes = xd.SelectNodes("//CityTrafficSimulator/TrafficVolumes/StartPoints/BunchOfNodes"); foreach (XmlNode aXmlNode in xnlStartNodes) { // Deserialize each node TextReader tr = new StringReader(aXmlNode.OuterXml); XmlSerializer xs = new XmlSerializer(typeof(BunchOfNodes)); BunchOfNodes bof = (BunchOfNodes)xs.Deserialize(tr); bof.RecoverFromLoad(saveVersion, nodesList); _startPoints.Add(bof); } // Load destination points: lf.StepLowerProgress(); // get corresponding XML nodes XmlNodeList xnlDestinationNodes = xd.SelectNodes("//CityTrafficSimulator/TrafficVolumes/DestinationPoints/BunchOfNodes"); foreach (XmlNode aXmlNode in xnlDestinationNodes) { // Deserialize each node TextReader tr = new StringReader(aXmlNode.OuterXml); XmlSerializer xs = new XmlSerializer(typeof(BunchOfNodes)); BunchOfNodes bof = (BunchOfNodes)xs.Deserialize(tr); bof.RecoverFromLoad(saveVersion, nodesList); // ensure that no hashcode is assigned twice BunchOfNodes.hashcodeIndex = Math.Max(bof.hashcode + 1, BunchOfNodes.hashcodeIndex); _destinationPoints.Add(bof); } // Load traffic volumes: lf.StepLowerProgress(); // get corresponding XML nodes XmlNodeList xnlTrafficVolumes = xd.SelectNodes("//CityTrafficSimulator/TrafficVolumes/TrafficVolume"); foreach (XmlNode aXmlNode in xnlTrafficVolumes) { // Deserialize each node TextReader tr = new StringReader(aXmlNode.OuterXml); XmlSerializer xs = new XmlSerializer(typeof(TrafficVolume)); TrafficVolume tv = (TrafficVolume)xs.Deserialize(tr); tv.RecoverFromLoad(saveVersion, startPoints, destinationPoints); if (tv.startNodes != null && tv.destinationNodes != null) { _trafficVolumes.Add(tv); tv.VehicleSpawned += new TrafficVolume.VehicleSpawnedEventHandler(newTV_VehicleSpawned); } else { lf.Log("Error during traffic volume deserialization: Could not dereference start-/end nodes. Traffic volume was dismissed."); } } OnStartPointsChanged(new StartPointsChangedEventArgs()); OnDestinationPointsChanged(new DestinationPointsChangedEventArgs()); }
/// <summary> /// Läd eine XML Datei und versucht daraus den gespeicherten Zustand wiederherzustellen /// </summary> /// <param name="xd">XmlDocument mit den zu ladenden Daten</param> /// <param name="nodesList">Liste von allen existierenden LineNodes</param> /// <param name="lf">LoadingForm für Statusinformationen</param> public void LoadFromFile(XmlDocument xd, List<LineNode> nodesList, LoadingForm.LoadingForm lf) { lf.SetupLowerProgess("Parsing XML...", 1); int saveVersion = 0; // erstma alles vorhandene löschen foreach (TimelineGroup tg in _groups) { foreach (TimelineEntry te in tg.entries) { // Löschen vorbereiten te.Dispose(); } tg.entries.Clear(); } _groups.Clear(); XmlNode mainNode = xd.SelectSingleNode("//CityTrafficSimulator"); XmlNode saveVersionNode = mainNode.Attributes.GetNamedItem("saveVersion"); if (saveVersionNode != null) saveVersion = Int32.Parse(saveVersionNode.Value); else saveVersion = 0; lf.StepLowerProgress(); if (saveVersion >= 4) { XmlNode xnlTrafficLights = xd.SelectSingleNode("//CityTrafficSimulator/TrafficLights"); XmlNode cycleTimeNode = xnlTrafficLights.Attributes.GetNamedItem("cycleTime"); if (cycleTimeNode != null) maxTime = Double.Parse(cycleTimeNode.Value); } else { maxTime = 50; } if (saveVersion >= 3) { // entsprechenden Node auswählen XmlNodeList xnlLineNode = xd.SelectNodes("//CityTrafficSimulator/TrafficLights/TimelineGroup"); Type[] extraTypes = { typeof(TrafficLight) }; foreach (XmlNode aXmlNode in xnlLineNode) { // Node in einen TextReader packen TextReader tr = new StringReader(aXmlNode.OuterXml); // und Deserializen XmlSerializer xs = new XmlSerializer(typeof(TimelineGroup), extraTypes); TimelineGroup tg = (TimelineGroup)xs.Deserialize(tr); // ab in die Liste tg.GroupChanged += new TimelineGroup.GroupChangedEventHandler(tg_GroupChanged); _groups.Add(tg); } } else { TimelineGroup unsortedGroup = new TimelineGroup("Unsorted Signals", false); // entsprechenden Node auswählen XmlNodeList xnlLineNode = xd.SelectNodes("//CityTrafficSimulator/Layout/LineNode/tLight"); foreach (XmlNode aXmlNode in xnlLineNode) { // der XMLNode darf nicht tLight heißen, sondern muss TrafficLight heißen. Das müssen wir mal anpassen: XmlDocument doc = new XmlDocument(); XmlElement elem = doc.CreateElement("TrafficLight"); elem.InnerXml = aXmlNode.InnerXml; doc.AppendChild(elem); // so, das war nicht wirklich hübsch und schnell, aber es funktioniert ;) // Node in einen TextReader packen StringReader tr = new StringReader(doc.InnerXml); // und Deserializen XmlSerializer xs = new XmlSerializer(typeof(TrafficLight)); TrafficLight tl = (TrafficLight)xs.Deserialize(tr); XmlNode pnhNode = doc.SelectSingleNode("//TrafficLight/parentNodeHash"); tl.parentNodeHash = Int32.Parse(pnhNode.InnerXml); unsortedGroup.AddEntry(tl); } // ab in die Liste _groups.Add(unsortedGroup); } lf.SetupLowerProgess("Restoring Signals...", _groups.Count); // Abschließende Arbeiten: Referenzen auflösen foreach (TimelineGroup tg in _groups) { tg.RecoverFromLoad(saveVersion, nodesList); lf.StepLowerProgress(); } OnGroupsChanged(); }