/// <summary> /// Example of how to define data in a network, save it to disc, and read it again. /// <para> /// This example stores values of the complex type <see cref="MyData"/>, though simple /// types as string, int double are also supported. /// </para> /// </summary> public static void SaveNetworkData() { string filename = Path.Combine(ExampleBase.ExampleRoot, @"vidaUserData.myxml"); // This block will store some data in a MIKE 1D data object, and save it to an xml file { // Create a NetworkData that can store a user defined type, and add some data at some locations NetworkData <MyData> myComplexData = new NetworkData <MyData>() { CanInterpolate = false }; myComplexData.AddValue(new Location("SonderAa", 1034), new MyData() { SValue = "SA", DValue = 1.034 }); myComplexData.AddValue(new Location("LindSkov", 2860), new MyData() { SValue = "LS", DValue = 2.86 }); myComplexData.AddValue("MyNodeId", new MyData() { SValue = "Node", DValue = -42 }); // Xml writer settings for getting "pretty"/human readable xml text file XmlWriterSettings xmlWriterSettings = new XmlWriterSettings() { Indent = true, CheckCharacters = false, CloseOutput = true, NewLineHandling = NewLineHandling.Entitize }; // Open the file for writing XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(XmlWriter.Create(filename, xmlWriterSettings)); // Create a DataContractSerializer. It must in this case "preserveObjectReferences". In many cases that is not // required, for more simple types than NetworkData<MyData>, it can be set to false, which gives much nicer xml. Type[] knownTypes = new Type[] { typeof(NetworkData <double>) }; var dcs = new DataContractSerializer(typeof(NetworkData <MyData>), knownTypes, int.MaxValue, false /*ignoreExtensionDataObject*/, true /* preserveObjectReferences */, null /*Surrogate*/); // Write data to file dcs.WriteObject(writer, myComplexData); writer.Close(); } // This block will read the data agian { // Open the file for reading var fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read); XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas()); // Create a DataContractSerializer, matching the one used when writing the file Type[] knownTypes = new Type[] { typeof(NetworkData <double>) }; var dcs = new DataContractSerializer(typeof(NetworkData <MyData>), knownTypes, int.MaxValue, false /*ignoreExtensionDataObject*/, true /* preserveObjectReferences */, null /*Surrogate*/); // Read file again NetworkData <MyData> myComplexData = (NetworkData <MyData>)dcs.ReadObject(reader, true); reader.Close(); // Now we can extract our data again MyData v1034; bool ok1034 = myComplexData.GetValue(new Location("SonderAa", 1034), out v1034); MyData v2860; bool ok2860 = myComplexData.GetValue(new Location("LindSkov", 2860), out v2860); MyData vNode; bool okNode = myComplexData.GetValue("MyNodeId", out vNode); } }
/// <summary> /// This is basically the same example as the SaveNetworkData above, though /// this time the data is stored as a part of the MIKE 1D setup in the /// standard .m1dx file. /// <para> /// This is ONLY recommended for advanced users and use: /// The disadvantage of this approach is that the resulting .m1dx file can only be /// read again by a similar approach, i.e. it WILL ONLY run using the default engine /// when the custom assembly is available, hence it CAN NOT be read by others unless /// they are also provided with the custom assembly. /// </para> /// </summary> /// <param name="vidaaFilepath">Path and name of the Vidaa example</param> /// <param name="customAssemblyFile"></param> public static void SaveComplexNetworkDataWithSetup(string vidaaFilepath, string customAssemblyFile) { { // Creates a new Mike 1D controller and load the setup Mike1DControllerFactory controllerFactory = new Mike1DControllerFactory(); Diagnostics diagnostics = new Diagnostics("My Diagnostics"); IMike1DController controller = controllerFactory.OpenAndCreate(Connection.Create(vidaaFilepath), diagnostics); if (diagnostics.ErrorCountRecursive > 0) { throw new Exception("Loading errors, aborting"); } // Create a NetworkData that can store a user defined type, and add some data at some locations NetworkData <MyData> myComplexData = new NetworkData <MyData>() { CanInterpolate = false }; myComplexData.AddValue(new Location("SonderAa", 1034), new MyData() { SValue = "SA", DValue = 1.034 }); myComplexData.AddValue(new Location("LindSkov", 2860), new MyData() { SValue = "LS", DValue = 2.86 }); myComplexData.AddValue("MyNodeId", new MyData() { SValue = "Node", DValue = -42 }); // Set the NetworkData as additional data, using the string "UserData" as key controller.Mike1DData.SetAdditionalData("UserData", myComplexData); controller.Mike1DData.SetAdditionalData("UserData2", new MyData() { SValue = "Upstream", DValue = 15.03 }); // Saving the file again (same filename, new extension) controller.Mike1DData.Connection.BridgeName = "m1dx"; controller.Mike1DData.Connection.FilePath.Extension = ".m1dx"; // We need to add two custom types, in order to store data to .m1dx // The types are found in the DHI.Mike1D.Examples.dll, which cannot be found by the MIKE 1D engine unless an explicit path is provided // Make the path relative to the setup. string relativeAssemblyFile = FilePath.GetRelativeFilePath(customAssemblyFile, Path.GetDirectoryName(Path.GetFullPath(vidaaFilepath))); controller.Mike1DData.CustomTypes.AssemblyFiles.Add(relativeAssemblyFile); controller.Mike1DData.CustomTypes.Add(myComplexData.GetType()); controller.Mike1DData.CustomTypes.Add(typeof(MyData)); Mike1DBridge.Save(controller.Mike1DData); // Close any log files controller.Finish(); } { // Load the setup again, changing the extension to .m1dx FilePath vidaaFile = new FilePath(vidaaFilepath); vidaaFile.Extension = ".m1dx"; Mike1DControllerFactory controllerFactory = new Mike1DControllerFactory(); Diagnostics diagnostics = new Diagnostics("My Diagnostics"); IMike1DController controller = controllerFactory.OpenAndCreate(Connection.Create(vidaaFile), diagnostics); Mike1DData mike1DData = controller.Mike1DData; // Get the additional data using the string "UserData" as key, which we know is a NetworkData with MyData NetworkData <MyData> myComplexData = (NetworkData <MyData>)mike1DData.GetAdditionalData("UserData"); MyData myComplexData2 = (MyData)mike1DData.GetAdditionalData("UserData2"); // Now we can extract our data again MyData v1034; bool ok1034 = myComplexData.GetValue(new Location("SonderAa", 1034), out v1034); MyData v2860; bool ok2860 = myComplexData.GetValue(new Location("LindSkov", 2860), out v2860); MyData vNode; bool okNode = myComplexData.GetValue("MyNodeId", out vNode); controller.Finish(); } }