Contents
Exercise outline
The goal of this exercise is to create and register a WaterML2 importer class. In the end it should be possible to import WaterML2 files (containing time series data) into a Delta Shell project.
Information on WaterML2, a global standard for hydrological time series, can be found here: http://www.waterml2.org/
Create a new importer class
Add a new folder to the plugin project named Importers. In this folder, create a new class named DemoAppApplicationPlugin.cs and add the following code:
public class WaterML2TimeSeriesImporter : IFileImporter { private static readonly ILog log = LogManager.GetLogger(typeof(WaterML2TimeSeriesImporter)); public string Name { get { return "WaterML2 time series importer"; } } public string Category { get { return "DemoApp importers"; } } public Bitmap Image { get { return new Bitmap(16, 16);} } public IEnumerable<Type> SupportedItemTypes { get { yield return typeof(TimeSeries); } } public bool CanImportOnRootLevel { get { return true; } } public string FileFilter { get { return "WaterML2 files|*.XML"; } } public string TargetDataDirectory { get; set; } public bool ShouldCancel { get; set; } public ImportProgressChangedDelegate ProgressChanged { get; set; } public object ImportItem(string path, object target = null) { // Check the file path if (!File.Exists(path)) { log.Error("File does not exist"); return null; } // Obtain a new time series or check the provided target for being a time series var timeSeries = target == null ? new TimeSeries { Name = Path.GetFileNameWithoutExtension(path), Components = { new Variable<double>() } } : target as TimeSeries; if (timeSeries == null) { log.Error("Target is of the wrong type (should be time series)"); return null; } // Load the XML document var doc = XDocument.Load(path); // Obtain the document elements var xElements = doc.Descendants(); // Obtain the measurement TVP tags var measurements = xElements.Where(element => element.Name.LocalName == "MeasurementTVP"); // Get the corresponding time and value for each measurement tag foreach (var measurement in measurements) { var time = DateTime.Parse(measurement.Elements().First(e => e.Name.LocalName == "time").Value); var value = double.Parse(measurement.Elements().First(e => e.Name.LocalName == "value").Value); timeSeries[time] = value; } // Return the time series return timeSeries; } }
Fixme: Info on the code above.
Fixme snippet for actualy importing something...
Register the importer in the application plugin
[TODO] Fixme
Exercise results
[TODO] Description of the exercise results
1. Add a new folder to the project named "Importers"
2. Create a new class named "WaterML2TimeSeriesImporter"
3. Add the following contents to this class:
using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Xml.Linq; using DelftTools.Functions; using DelftTools.Functions.Generic; using DelftTools.Shell.Core; using log4net; namespace DeltaShell.Plugin.DemoApp.Importers { public class WaterML2TimeSeriesImporter : IFileImporter { private static readonly ILog log = LogManager.GetLogger(typeof(WaterML2TimeSeriesImporter)); public string Name { get { return "WaterML2 time series importer"; } } public string Category { get { return "DemoApp importers"; } } public Bitmap Image { get { return new Bitmap(16, 16);} } public IEnumerable<Type> SupportedItemTypes { get { yield return typeof(TimeSeries); } } public bool CanImportOnRootLevel { get { return true; } } public string FileFilter { get { return "WaterML2 files|*.XML"; } } public string TargetDataDirectory { get; set; } public bool ShouldCancel { get; set; } public ImportProgressChangedDelegate ProgressChanged { get; set; } public object ImportItem(string path, object target = null) { // Check the file path if (!File.Exists(path)) { log.Error("File does not exist"); return null; } // Obtain a new time series or check the provided target for being a time series var timeSeries = target == null ? new TimeSeries { Name = Path.GetFileNameWithoutExtension(path), Components = { new Variable<double>() } } : target as TimeSeries; if (timeSeries == null) { log.Error("Target is of the wrong type (should be time series)"); return null; } // Load the XML document var doc = XDocument.Load(path); // Obtain the document elements var xElements = doc.Descendants(); // Obtain the measurement TVP tags var measurements = xElements.Where(element => element.Name.LocalName == "MeasurementTVP"); // Get the corresponding time and value for each measurement tag foreach (var measurement in measurements) { var time = DateTime.Parse(measurement.Elements().First(e => e.Name.LocalName == "time").Value); var value = double.Parse(measurement.Elements().First(e => e.Name.LocalName == "value").Value); timeSeries[time] = value; } // Return the time series return timeSeries; } } }
4. Register the importer in the application plugin class by adding the following code to DemoAppApplicationPlugin:
public override IEnumerable<IFileImporter> GetFileImporters() { yield return new WaterML2TimeSeriesImporter(); }
5. Run the application, right click on Project and click Import. Select the newly implemented importer and press OK. [TODO: Image]
6. Select a file bla bla bla [TODO:Image]