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
h2.
scrollbar

Exercise

...

outline

...

The

...

goal

...

of

...

this

...

exercise

...

is

...

to

...

create

...

and

...

register

...

a

...

WaterML2

...

importer

...

class.

...

At

...

the

...

end,

...

it

...

should

...

be

...

possible

...

to

...

import

...

WaterML2

...

files

...

(containing

...

time

...

series

...

data)

...

into

...

a

...

Delta

...

Shell

...

project.

Info

Information on

{info} Information on

WaterML2,

a

global

standard

for

hydrological

time

series,

can

be

found at [

found at http://www.waterml2.org/.

Create a new importer class

Add to the plugin project a new folder named Importers. In this folder, create a new class named WaterML2TimeSeriesImporter.cs and 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].
{info}

h2. Create a new importer class

Add to the plugin project a new folder named _Importers_. In this folder, create a new class named _WaterML2TimeSeriesImporter.cs_ and adapt the contents as shown below:

{code}
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 DelftToolsSystem.Shell.CoreDrawing;
using log4netSystem.IO;

namespaceusing DeltaShell.Plugins.VolumeModel.Importers
{
    /// <summary>
    /// Importer for importing WaterML2 data to time series objects
    /// </summary>
    public class WaterML2TimeSeriesImporter : IFileImporter
    {
        private static readonly ILog Log = LogManager.GetLogger(typeof(WaterML2TimeSeriesImporter)); // Handle for writing log messages

    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>
        /// TheImporter namefor ofimporting theWaterML2 importer
data to time      /// </summary>
   series objects
     /// <remarks>Used in importer selection dialogs</remarks>
        public string Name </summary>
    public class WaterML2TimeSeriesImporter : {IFileImporter
    {
        getprivate {static returnreadonly "WaterML2ILog timeLog series importer"; }
        }= LogManager.GetLogger(typeof(WaterML2TimeSeriesImporter)); // Handle for writing log messages

        /// <summary>
        /// The categoryname of the importer
        /// </summary>
        /// <remarks>Used in importer selection dialogs</remarks>
        public string CategoryName
        {
            get { return "VolumeWaterML2 time modelseries importersimporter"; }
        }

        /// <summary>
        /// The imagecategory of the importer
        /// </summary>
        /// <remarks>Used in importer selection dialogs</remarks>
        public Bitmapstring ImageCategory
        {
            get { return new Bitmap(16, 16)"Volume model importers"; }
        }

        /// <summary>
        /// The data types supported byimage of the importer
        /// </summary>
        public IEnumerable<Type> SupportedItemTypes
        {
          /// <remarks>Used getin {importer yield return typeof(TimeSeries); }
selection dialogs</remarks>
        public Bitmap }Image

        /// <summary>{
        /// Indicates that the importerget can{ importreturn at root level (folder/project). In othernew Bitmap(16, 16); }
        /// words, indicates that the <see cref="ImportItem"/> method can be called without}

        /// <summary>
        /// specifying a time series target...The data types supported by the importer
        /// </summary>
        public boolIEnumerable<Type> CanImportOnRootLevelSupportedItemTypes
        {
            get { yield return truetypeof(TimeSeries); }
        }

        /// <summary>
        /// Indicates that the importer can import at root level (folder/project). In other
        /// words, indicates that the <see  /// The file filter of the importercref="ImportItem"/> method can be called without
        /// </summary> specifying a time series target...
        /// <remarks>Used in file selection dialogs</remarks></summary>
        public stringbool FileFilterCanImportOnRootLevel
        {
            get { return "WaterML2 files|*.XML"true; }
        }

        /// <summary>
        /// The file filter of the importer
        /// </summary>
        /// <remarks>Used in file selection  /// Path where external data files can be copied intodialogs</remarks>
        public string FileFilter
        /// </summary>{
        /// <remarks>Not relevant in this tutorial</remarks>
     get { return "WaterML2 files|*.XML"; }
   public string TargetDataDirectory { get; set; }

        /// <summary>
        /// WhetherPath orwhere notexternal andata importfiles taskcan shouldbe becopied cancelledinto
        /// </summary>
        /// <remarks>Not partrelevant ofin this tutorial</remarks>
        public boolstring ShouldCancelTargetDataDirectory { get; set; }

        /// <summary>
        /// Fired when progress has been changed Whether or not an import task should be cancelled
        /// </summary>
        /// <remarks>Not part inof this tutorial</remarks>
        public ImportProgressChangedDelegatebool ProgressChangedShouldCancel { get; set; }

        /// <summary>
        /// Imports WaterML2 data from the file with path <paramref name="path"/> to the Fired when progress has been changed
        /// </summary>
        /// <remarks>Not timepart seriesin <paramref name="target"/>
this tutorial</remarks>
        public ImportProgressChangedDelegate ProgressChanged {  /// </summary>get; set; }

        /// <remarks><summary>
        /// TheImports targetWaterML2 parameter is optional. If a target time series is specified, the
        /// importer should import the WaterML2 data to this existing time series. Whendata from the file with path <paramref name="path"/> to the
        /// time series <paramref name="target"/>
        /// </summary>
 no target is set, the importer should create a new time series./// <remarks>
        /// </remarks>
The target parameter is optional. If a target publictime objectseries ImportItem(stringis pathspecified, objectthe
  target = null)
    /// importer should import {
the WaterML2 data to this existing time series. When
    // Check the file path
//  no target is set, the importer should create a new iftime (!File.Exists(path))series.
            {/// </remarks>
        public object ImportItem(string path, object target =  Log.Error("File does not exist");

null)
        {
            return null;
   // Check the file path
         }

   if (!File.Exists(path))
        // Obtain a new time{
 series or check the provided target for being a time series
     Log.Error("File does not exist");

    var timeSeries = target == null
       return null;
        ? new TimeSeries { Name = Path.GetFileNameWithoutExtension(path), Components = { new Variable<double>() } }
 }

            // Obtain a new time series or check the provided target for :being targeta astime TimeSeries;
series
            ifvar (timeSeries = target == null)
            {
    ? new TimeSeries { Name        Log.Error("Target is of the wrong type (should be time series)");

= Path.GetFileNameWithoutExtension(path), Components = { new Variable<double>() } }
                : target returnas nullTimeSeries;

            }

if (timeSeries == null)
            {
     // Load the WaterML2 XML document
      Log.Error("Target is of the wrong type var(should docbe = XDocument.Load(pathtime series)");

             // Obtain the documentreturn elementsnull;
            var xElements = doc.Descendants();}

            // ObtainLoad the measurementWaterML2 TVPXML tagsdocument
            var measurementsdoc = xElements.Where(element => element.Name.LocalName == "MeasurementTVP"XDocument.Load(path);

            // GetObtain the corresponding time and value for each measurement tag
 document elements
           foreach (var measurementxElements in measurements)
= doc.Descendants();

            {
// Obtain the measurement TVP tags
            var time = DateTime.Parse(measurement.Elements().First(emeasurements = xElements.Where(element => eelement.Name.LocalName == "timeMeasurementTVP").Value);

            // Get the corresponding time varand value for =each double.Parse(measurement.Elements().First(e => e.Name.LocalName == "value").Value);
measurement tag
            foreach (var measurement in measurements)
            {
    timeSeries[time] = value;
          var time }

     = DateTime.Parse(measurement.Elements().First(e => e.Name.LocalName == "time").Value);
       // Return the time series
     var value = double.Parse(measurement.Elements().First(e => e.Name.LocalName  return timeSeries== "value").Value);

        }
     }
}
{code}

{note}
In order to successfully build the code, 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_)_._
{note}
{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.
{info}



h2. Register the importer in the application plugin class

Register the importer in the application plugin by adding the following code to _VolumeModelApplicationPlugin.cs_:

{code}timeSeries[time] = value;
            }

            // Return the time series
            return timeSeries;
        }
    }
}
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
{code}

and

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

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 ...).


!ImporterDialog.png!\\ \\ 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,&nbsp;should be added to the project (double click the precipitation item in the _Project_ window): !importedTimeSeriesGraph.png!\\ \\ 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 ...). \\ VolumeModel.zipThe code results up until the end of this exercise can be downloaded here
scrollbar
Panel
borderStylenone
Align
centercenter