Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin

Contents

3
Panel
Panel
borderStylesolid
Page Tree
rootTOOLS:Tutorial
startDepth
scrollbar

Exercise outline

The goal of this exercise is to create and register a WaterML2 importer class. In At the end, it should be possible to import WaterML2 files (containing time series data) into a Delta Shell project.

Info

Information on WaterML2, a global standard for hydrological time series, can be found here: at http://www.waterml2.org/.

Create a new importer class

Add a new folder to the plugin project a new folder named Importers. In this folder, create a new class named DemoAppApplicationPluginWaterML2TimeSeriesImporter.cs and add the following code:adapt the contents as shown below.

Note

In order to successfully build the code below, references need to be added to:

  • log4net (right click the References folder of the project in the Solution Explorer | Add Reference... | Browse... | Select D:\VolumeModel\packages\DeltaShell.1.0.0\delta-shell\bin\log4net.dll);
  • System.Drawing (right click the References folder of the project in the Solution Explorer | Add Reference... | Assemblies | Framework | Select System.Drawing).
Code Block

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.Plugins.VolumeModel.Importers
{
    /// <summary>
    /// Importer for importing WaterML2 data to time series objects
    /// </summary>
    public class WaterML2TimeSeriesImporter : IFileImporter
    {
Code Block

    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
        {
private static readonly ILog Log = LogManager.GetLogger(typeof(WaterML2TimeSeriesImporter)); // Handle for writing  get { return "DemoApp importers"; }
log messages

        /// <summary>
   }

     /// The name publicof Bitmapthe Imageimporter
        {/// </summary>
        /// <remarks>Used in importer get { return new Bitmap(16, 16);}
        }
selection dialogs</remarks>
        public IEnumerable<Type>string SupportedItemTypesName
        {
            get { yieldreturn return typeof(TimeSeries)"WaterML2 time series importer"; }
        }

        /// <summary>
 public bool CanImportOnRootLevel
     /// The category {
of the importer
        /// </summary>
 get { return true; }
   /// <remarks>Used in importer selection }dialogs</remarks>

        public string FileFilterCategory
        {
            get { return "WaterML2 files|*.XMLVolume model importers"; }
        }

        public string TargetDataDirectory { get; set; }

/// <summary>
        /// The image of the publicimporter
 bool ShouldCancel { get; set; }

  /// </summary>
     public ImportProgressChangedDelegate ProgressChanged { get; set; }

  /// <remarks>Used in importer selection dialogs</remarks>
        public object ImportItem(string path, object target = null)Bitmap Image
        {
            //get Check{ thereturn file path
  new Bitmap(16, 16); }
        }

  if (!File.Exists(path))
     /// <summary>
      {
  /// The data types supported by the importer
       log.Error("File does not exist");

 /// </summary>
        public IEnumerable<Type> SupportedItemTypes
       return null;{
            }

get { yield return typeof(TimeSeries); }
       // Obtain}

 a new time series or check the provided target for being a time series
/// <summary>
        /// Indicates that the importer can import at root var timeSeries = target == null
level (folder/project). In other
        /// words, indicates that the <see cref="ImportItem"/> method can be ?called newwithout
 TimeSeries { Name = Path.GetFileNameWithoutExtension(path), Components = { new Variable<double>() } } /// specifying a time series target...
        /// </summary>
       : targetpublic asbool TimeSeries;
CanImportOnRootLevel
        {
    if (timeSeries == null)
        get { return true; {}
        }

        log.Error("Target is of the wrong type (should be time series)");

      /// <summary>
        /// The file filter of the importer
          return null;/// </summary>
        /// <remarks>Used in  }

file selection dialogs</remarks>
        public string FileFilter
    // Load the XML document{
            get var{ docreturn = XDocument.Load(path);

"WaterML2 files|*.XML"; }
        }

        /// Obtain<summary>
 the document elements
            var xElements = doc.Descendants();

          /// Path where external data files can be copied into
        /// </summary>
        /// Obtain<remarks>Not therelevant measurementin TVPthis tagstutorial</remarks>
        public string TargetDataDirectory { varget; measurements = xElements.Where(element => element.Name.LocalName == "MeasurementTVP");

    set; }

        /// <summary>
        /// GetWhether theor correspondingnot timean andimport valuetask forshould eachbe measurement tagcancelled
        /// </summary>
        /// foreach<remarks>Not (varpart measurementof in measurements)
this tutorial</remarks>
        public bool ShouldCancel { get; set; {}

        /// <summary>
       var time/// = DateTime.Parse(measurement.Elements().First(e => e.Name.LocalName == "time").Value);
Fired when progress has been changed
        /// </summary>
        /// var<remarks>Not valuepart = double.Parse(measurement.Elements().First(e => e.Name.LocalName == "value").Value);

in this tutorial</remarks>
        public ImportProgressChangedDelegate ProgressChanged { get; set; }

     timeSeries[time] = value;
 /// <summary>
        /// Imports }

WaterML2 data from the file with path      // Return the time series<paramref name="path"/> to the
        /// time series  return timeSeries;<paramref name="target"/>
        }
    }
Info

Fixme: Info on the code above.

Register the importer in the application plugin

Wiki Markup
*\[TODO\]* Fixme

Exercise results

Wiki Markup
*\[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:

Code Block

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/// </summary>
        /// <remarks>
        /// The target parameter is optional. If a target time series is specified, the
        /// importer should import the WaterML2 data to this existing time series. When
        //  no target is set, the importer should create a new time series.
        /// </remarks>
        public object ImportItem(string path, object target = null)
        {
            get// {Check returnthe "WaterML2 time series importer"; }file path
        }

    if (!File.Exists(path))
   public string Category
        {
             get { return "DemoApp importers"; }
Log.Error("File does not exist");

         }

       return null;
  public Bitmap Image
        {}

            get// {Obtain returna new Bitmap(16, 16);}
        }

  time series or check the provided target for being a time series
      public IEnumerable<Type> SupportedItemTypes
    var timeSeries = target {
== null
                ? getnew TimeSeries { yieldName return= typeofPath.GetFileNameWithoutExtension(TimeSeriespath);, }
Components = { new Variable<double>()  }  }

         public bool CanImportOnRootLevel
     : target as {TimeSeries;

            get { return true; }
if (timeSeries == null)
            }

{
               public string FileFilter
        {
 Log.Error("Target is of the wrong type (should be time series)");

              get { return "WaterML2 files|*.XML"; }
null;
            }

           public string// TargetDataDirectoryLoad {the get;WaterML2 set;XML }document

          public bool ShouldCancelvar {doc get; set; }= XDocument.Load(path);

        public ImportProgressChangedDelegate ProgressChanged { get; set; }
  // Obtain the document elements
        public object ImportItem(string path, objectvar targetxElements = nulldoc.Descendants()
        {;

            // CheckObtain the measurement fileTVP pathtags
            var if (!File.Exists(path))
    measurements = xElements.Where(element => element.Name.LocalName == "MeasurementTVP");

        {
    // Get the corresponding time and value for each measurement tag
  log.Error("File does not exist");

       foreach (var measurement       return null;in measurements)
            }{

             // Obtain a newvar time series or check the provided target for being a time series
= DateTime.Parse(measurement.Elements().First(e => e.Name.LocalName == "time").Value);
                var value var timeSeries= double.Parse(measurement.Elements().First(e => targete.Name.LocalName == null"value").Value);

                ? new TimeSeries { Name = Path.GetFileNameWithoutExtension(path), Components = { new Variable<double>() } }
timeSeries[time] = value;
            }

            // Return the  : target as TimeSeries;

time series
            ifreturn (timeSeries == null)timeSeries;
        }
    {
                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:

Code Block

        public override IEnumerable<IFileImporter> GetFileImporters()
        {
            yield return new WaterML2TimeSeriesImporter();
        }

Wiki Markup
5. Run the application, right click on Project and click Import. Select the newly implemented importer and press OK. \[TODO: Image\]

...

}
}
Info

The importer class is derived from the IFileImporter interface so that it can be registered in the application plugin (see the next step).

The comments in the code explain the different parts of the importer implementation.

Register the importer in the application plugin class

Register the importer in the application plugin by adding the following code to VolumeModelApplicationPlugin.cs:

Code Block

using System.Collections.Generic;
using DeltaShell.Plugins.VolumeModel.Importers;

and

Code Block

public override IEnumerable<IFileImporter> GetFileImporters()
{
    yield return new WaterML2TimeSeriesImporter();
}

Delta Shell should now be able to find the importer when importing data on new or existing time series objects.

Exercise results

First of all, download the following WaterML2 XML: WaterML2_precipitation_data.XML.

Then, run the application and start importing a new project item (right click on project | Import...). Make sure that the new importer is selected in the dialog:

Image Added

If you next click on OK, a file selection dialog pops up. Select the previously downloaded WaterML2 XML file and continue with the wizard.

After finishing the import, a new time series item, containing the data as shown in the following image, should be added to the project (double click the precipitation item in the Project window):

Image Added

In the steps above, a project level import has been performed which creates a completely new time series item. The importer, however, is also able to import WaterML2 data into existing time series. Although this feature will be further used in some of the upcoming exercises, it can already be tested by sequentially:

  • clearing (a part of) the imported time series data via the table view;
  • importing the downloaded WaterML2 XML file directly onto this just modified time series item (right click on the time series item | Import ...).


scrollbar

...