Index: DamClients/DamUI/trunk/src/Dam/Tests/Deltares.Dam.Tests.csproj
===================================================================
diff -u -r3008 -r3015
--- DamClients/DamUI/trunk/src/Dam/Tests/Deltares.Dam.Tests.csproj (.../Deltares.Dam.Tests.csproj) (revision 3008)
+++ DamClients/DamUI/trunk/src/Dam/Tests/Deltares.Dam.Tests.csproj (.../Deltares.Dam.Tests.csproj) (revision 3015)
@@ -149,6 +149,7 @@
+
Index: DamClients/DamUI/trunk/src/DamClientsLibrary/Deltares.Dam.Data/StiImporter/SoilProfile2DImporter.cs
===================================================================
diff -u
--- DamClients/DamUI/trunk/src/DamClientsLibrary/Deltares.Dam.Data/StiImporter/SoilProfile2DImporter.cs (revision 0)
+++ DamClients/DamUI/trunk/src/DamClientsLibrary/Deltares.Dam.Data/StiImporter/SoilProfile2DImporter.cs (revision 3015)
@@ -0,0 +1,96 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Deltares.Geotechnics.Soils;
+using Deltares.Standard.Logging;
+
+namespace Deltares.Dam.Data.StiImporter
+{
+ ///
+ /// Importer to import .
+ ///
+ public class SoilProfile2DImporter
+ {
+ ///
+ /// Imports the that are contained within .
+ ///
+ /// The directory to retrieve the soil profiles from.
+ /// The to import the soil profiles for.
+ /// The that contains all the valid soil materials.
+ /// A collection of .
+ ///
+ /// Thrown when or is null.
+ ///
+ /// Thrown when
+ /// is null, empty or consist of only whitespaces.
+ ///
+ /// Thrown when no soil profiles could be read from .
+ ///
+ public IEnumerable Import(string soilProfileDirectory, Segment segment, SoilList availableSoils)
+ {
+ if (segment == null)
+ {
+ throw new ArgumentNullException(nameof(segment));
+ }
+
+ if (availableSoils == null)
+ {
+ throw new ArgumentNullException(nameof(availableSoils));
+ }
+
+ if (string.IsNullOrWhiteSpace(soilProfileDirectory))
+ {
+ throw new ArgumentException($"'{nameof(soilProfileDirectory)}' cannot be null or consist of whitespaces only.");
+ }
+
+ // Extract all soil profile 2D from a segment
+ var soilProfiles = segment.SoilProfileProbabilities
+ .Where(sp => sp.SoilProfileType == SoilProfileType.SoilGeometryStiFile);
+
+ var importedSoilProfiles = new List();
+ foreach (SoilGeometryProbability profile in soilProfiles)
+ {
+ string soilProfileFile = profile.SoilGeometry2DName;
+ SoilProfile2D readSoilProfile = ReadSoilProfile(soilProfileDirectory, soilProfileFile);
+ if (readSoilProfile != null)
+ {
+ if (IsValidSoilProfile(availableSoils, readSoilProfile))
+ {
+ importedSoilProfiles.Add(readSoilProfile);
+ }
+ else
+ {
+ LogManager.Messages.Add(new LogMessage(LogMessageType.Error, this, $"'{soilProfileFile}' contains undefined soil materials."));
+ }
+ }
+ }
+
+ return importedSoilProfiles;
+ }
+
+ private SoilProfile2D ReadSoilProfile(string soilProfileDirectory, string soilProfileFile)
+ {
+ string filePath = Path.Combine(soilProfileDirectory, soilProfileFile);
+
+ try
+ {
+ var reader = new StiFileReader();
+ SoilProfile2D readSoilProfile = reader.ReadSoilProfile(filePath);
+ return readSoilProfile;
+ }
+ catch (StiFileReadException e)
+ {
+ LogManager.Messages.Add(new LogMessage(LogMessageType.Error, this, e.Message));
+ }
+
+ return null;
+ }
+
+ private static bool IsValidSoilProfile(SoilList availableSoils, SoilProfile2D profile)
+ {
+ var soilNames = new HashSet(availableSoils.Soils.Select(s => s.Name));
+ return profile.Surfaces.All(soilLayer => soilNames.Contains(soilLayer.Name));
+ }
+ }
+}
\ No newline at end of file
Index: DamClients/DamUI/trunk/src/DamClientsLibrary/Deltares.Dam.Data/Deltares.Dam.Data.csproj
===================================================================
diff -u -r3007 -r3015
--- DamClients/DamUI/trunk/src/DamClientsLibrary/Deltares.Dam.Data/Deltares.Dam.Data.csproj (.../Deltares.Dam.Data.csproj) (revision 3007)
+++ DamClients/DamUI/trunk/src/DamClientsLibrary/Deltares.Dam.Data/Deltares.Dam.Data.csproj (.../Deltares.Dam.Data.csproj) (revision 3015)
@@ -200,6 +200,7 @@
+
Index: DamClients/DamUI/trunk/src/Dam/Tests/StiImporter/SoilProfile2DImporterTest.cs
===================================================================
diff -u
--- DamClients/DamUI/trunk/src/Dam/Tests/StiImporter/SoilProfile2DImporterTest.cs (revision 0)
+++ DamClients/DamUI/trunk/src/Dam/Tests/StiImporter/SoilProfile2DImporterTest.cs (revision 3015)
@@ -0,0 +1,219 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Deltares.Dam.Data;
+using Deltares.Dam.Data.StiImporter;
+using Deltares.Standard.Logging;
+using NUnit.Framework;
+using Soil = Deltares.Geotechnics.Soils.Soil;
+using SoilList = Deltares.Geotechnics.Soils.SoilList;
+using SoilProfile2D = Deltares.Geotechnics.Soils.SoilProfile2D;
+
+namespace Deltares.Dam.Tests.StiImporter
+{
+ [TestFixture]
+ public class SoilProfile2DImporterTest
+ {
+ private const string TestDataFolder = @"TestData\StiImporter\";
+
+ [Test]
+ [TestCase(null)]
+ [TestCase(" ")]
+ [TestCase("")]
+ public void Import_InvalidSoilProfileDirectory_ThrowsArgumentException(string invalidSoilProfileDirectory)
+ {
+ // Setup
+ var importer = new SoilProfile2DImporter();
+
+ // Call
+ TestDelegate call = () => importer.Import(invalidSoilProfileDirectory, new Segment(), new SoilList());
+
+ // Assert
+ Assert.That(call, Throws.ArgumentException
+ .With.Message.EqualTo("'soilProfileDirectory' cannot be null or consist of whitespaces only."));
+ }
+
+ [Test]
+ public void Import_SegmentNull_ThrowsArgumentNullException()
+ {
+ // Setup
+ var importer = new SoilProfile2DImporter();
+
+ // Call
+ TestDelegate call = () => importer.Import(string.Empty, null, new SoilList());
+
+ // Assert
+ Assert.That(call, Throws.TypeOf()
+ .With.Property(nameof(ArgumentNullException.ParamName))
+ .EqualTo("segment"));
+ }
+
+ [Test]
+ public void Import_AvailableSoilsNull_ThrowsArgumentNullException()
+ {
+ // Setup
+ var importer = new SoilProfile2DImporter();
+
+ // Call
+ TestDelegate call = () => importer.Import(string.Empty, new Segment(), null);
+
+ // Assert
+ Assert.That(call, Throws.TypeOf()
+ .With.Property(nameof(ArgumentNullException.ParamName))
+ .EqualTo("availableSoils"));
+ }
+
+ [Test]
+ public void Import_WithValidArguments_ReturnsExpectedSoilProfiles()
+ {
+ // Setup
+ Segment segment = CreateSegmentWithProfiles(new[]
+ {
+ "SimpleProfile.sti",
+ "Tutorial-1a 10.1.4.3.sti"
+ });
+ SoilList availableSoils = CreateSoilList(new[]
+ {
+ "Soft Clay",
+ "Sand",
+ "Peat",
+ "Muck"
+ });
+
+ var importer = new SoilProfile2DImporter();
+
+ // Call
+ IEnumerable soilProfiles = importer.Import(TestDataFolder, segment, availableSoils);
+
+ // Assert
+ Assert.That(soilProfiles, Has.Count.EqualTo(2));
+ SoilProfile2D soilProfileOne = soilProfiles.ElementAt(0);
+ CollectionAssert.AreEqual(new[]
+ {
+ "Soft Clay",
+ "Muck"
+ }, soilProfileOne.Surfaces.Select(s => s.Name));
+
+ SoilProfile2D soilProfileTwo = soilProfiles.ElementAt(1);
+ CollectionAssert.AreEqual(new[]
+ {
+ "Soft Clay",
+ "Sand",
+ "Peat",
+ "Soft Clay"
+ }, soilProfileTwo.Surfaces.Select(s => s.Name));
+ }
+
+ [Test]
+ public void Import_WithIncompleteSoilList_ReturnsOnlyCompleteSoilProfilesAndLogsMessage()
+ {
+ // Setup
+ LogManager.Messages.Clear(); // Clear all messages as it is a singleton
+
+ const string invalidSoilProfile = "Tutorial-1a 10.1.4.3.sti"; // Soil profile also contains peat and sand for its layers
+ Segment segment = CreateSegmentWithProfiles(new[]
+ {
+ "SimpleProfile.sti",
+ invalidSoilProfile
+ });
+ SoilList availableSoils = CreateSoilList(new[]
+ {
+ "Soft Clay",
+ "Muck"
+ });
+
+ var importer = new SoilProfile2DImporter();
+
+ // Call
+ IEnumerable soilProfiles = importer.Import(TestDataFolder, segment, availableSoils);
+
+ // Assert
+ Assert.That(soilProfiles, Has.Count.EqualTo(1));
+ SoilProfile2D soilProfileOne = soilProfiles.ElementAt(0);
+ CollectionAssert.AreEqual(new[]
+ {
+ "Soft Clay",
+ "Muck"
+ }, soilProfileOne.Surfaces.Select(s => s.Name));
+
+ string expectedMessage = $"'{invalidSoilProfile}' contains undefined soil materials.";
+ CollectionAssert.AreEqual(new[]
+ {
+ expectedMessage
+ }, LogManager.Messages.Select(m => m.Message));
+ CollectionAssert.AreEqual(new[]
+ {
+ LogMessageType.Error
+ }, LogManager.Messages.Select(m => m.MessageType));
+ CollectionAssert.AreEqual(new[]
+ {
+ importer
+ }, LogManager.Messages.Select(m => m.Subject));
+ }
+
+ [Test]
+ public void Import_WithSoilProfileCausingReadException_ReturnsOnlyCompleteSoilProfilesAndLogsMessage()
+ {
+ // Setup
+ LogManager.Messages.Clear(); // Clear all messages as it is a singleton
+
+ const string invalidSoilProfile = "NonExistentSoilProfile";
+ Segment segment = CreateSegmentWithProfiles(new[]
+ {
+ "SimpleProfile.sti",
+ invalidSoilProfile
+ });
+ SoilList availableSoils = CreateSoilList(new[]
+ {
+ "Soft Clay",
+ "Muck"
+ });
+
+ var importer = new SoilProfile2DImporter();
+
+ // Call
+ IEnumerable soilProfiles = importer.Import(TestDataFolder, segment, availableSoils);
+
+ // Assert
+ Assert.That(soilProfiles, Has.Count.EqualTo(1));
+ SoilProfile2D soilProfileOne = soilProfiles.ElementAt(0);
+ CollectionAssert.AreEqual(new[]
+ {
+ "Soft Clay",
+ "Muck"
+ }, soilProfileOne.Surfaces.Select(s => s.Name));
+
+ LogMessage logMessage = LogManager.Messages.Single();
+ Assert.That(logMessage.Message, Is.Not.Empty);
+ Assert.That(logMessage.MessageType, Is.EqualTo(LogMessageType.Error));
+ Assert.That(logMessage.Subject, Is.SameAs(importer));
+ }
+
+ private static Segment CreateSegmentWithProfiles(IEnumerable soilProfileNames)
+ {
+ var random = new Random(21);
+
+ var segment = new Segment();
+ foreach (string soilProfileName in soilProfileNames)
+ {
+ segment.AddSoilGeometry2DProbability(soilProfileName, random.NextDouble(), null);
+ }
+
+ return segment;
+ }
+
+ private static SoilList CreateSoilList(IEnumerable soilNames)
+ {
+ var soilList = new SoilList();
+ foreach (string soilName in soilNames)
+ {
+ soilList.Add(new Soil
+ {
+ Name = soilName
+ });
+ }
+
+ return soilList;
+ }
+ }
+}
\ No newline at end of file