Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Importers/PipingSoilProfileTransformer.cs =================================================================== diff -u -r15ba57d868f00dfd3d6b52ac2e03a202d47d0303 -r22002c62bf845369153bab8a9530dc1168f3870f --- Ringtoets/Piping/src/Ringtoets.Piping.IO/Importers/PipingSoilProfileTransformer.cs (.../PipingSoilProfileTransformer.cs) (revision 15ba57d868f00dfd3d6b52ac2e03a202d47d0303) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Importers/PipingSoilProfileTransformer.cs (.../PipingSoilProfileTransformer.cs) (revision 22002c62bf845369153bab8a9530dc1168f3870f) @@ -20,8 +20,10 @@ // All rights reserved. using System; +using System.Collections.Generic; using Ringtoets.Common.IO.Exceptions; using Ringtoets.Common.IO.SoilProfile; +using Ringtoets.Piping.IO.Properties; using Ringtoets.Piping.Primitives; namespace Ringtoets.Piping.IO.Importers @@ -36,9 +38,7 @@ /// soil profile of type . /// /// The soil profile to use in the transformation. - /// A new based on the given data, or null when - /// is not of a type that can be transformed to - /// the mechanism specific . + /// A new based on the given data. /// Thrown when is null. /// Thrown when transformation would not result /// in a valid transformed instance. @@ -61,12 +61,45 @@ return CreatePipingSoilProfile(soilProfile2D); } - return null; + string message = $"Soil profile of type '{soilProfile.GetType().Name}' is not supported." + + $"Only soil profiles of type '{nameof(SoilProfile1D)}' or '{nameof(SoilProfile2D)}' are supported."; + throw new ImportedDataTransformException(message); } + /// + /// Creates a new instances of the based on the . + /// + /// The soil profile to use in the transformation. + /// The created . + /// Thrown when: + /// + /// The can not be used to determine intersections with; + /// Transforming the failed. + /// + /// private static PipingSoilProfile CreatePipingSoilProfile(SoilProfile2D soilProfile2D) { - return null; + string profileName = soilProfile2D.Name; + double intersectionX = soilProfile2D.IntersectionX; + + if (double.IsNaN(intersectionX)) + { + string message = string.Format(Resources.Error_SoilProfileBuilder_cant_determine_intersect_SoilProfileName_0_at_double_NaN, profileName); + throw new ImportedDataTransformException(message); + } + + var layers = new List(); + double bottom = double.MaxValue; + foreach (SoilLayer2D soilLayer2D in soilProfile2D.Layers) + { + double newBottom; + + layers.AddRange(PipingSoilLayerTransformer.Transform(soilLayer2D, intersectionX, out newBottom)); + + bottom = Math.Min(bottom, newBottom); + } + + return new PipingSoilProfile(profileName, bottom, layers, SoilProfileType.SoilProfile2D, 0); } private static PipingSoilProfile CreatePipingSoilProfile(SoilProfile1D soilProfile1D) Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Importers/PipingStochasticSoilModelTransformer.cs =================================================================== diff -u -r03fa491ac6713c77d10987a9ba1d0776dfdf82e9 -r22002c62bf845369153bab8a9530dc1168f3870f --- Ringtoets/Piping/src/Ringtoets.Piping.IO/Importers/PipingStochasticSoilModelTransformer.cs (.../PipingStochasticSoilModelTransformer.cs) (revision 03fa491ac6713c77d10987a9ba1d0776dfdf82e9) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Importers/PipingStochasticSoilModelTransformer.cs (.../PipingStochasticSoilModelTransformer.cs) (revision 22002c62bf845369153bab8a9530dc1168f3870f) @@ -39,8 +39,9 @@ { if (stochasticSoilModel.FailureMechanismType != FailureMechanismType.Piping) { - throw new ImportedDataTransformException($"Stochastic soil model of failure mechanism type '{stochasticSoilModel.FailureMechanismType}' is not supported." + - $"Only '{FailureMechanismType.Piping}' is supported."); + string message = $"Stochastic soil model of failure mechanism type '{stochasticSoilModel.FailureMechanismType}' is not supported." + + $"Only stochastic soil model of failure mechanism type '{FailureMechanismType.Piping}' is supported."; + throw new ImportedDataTransformException(message); } IEnumerable pipingStochasticSoilProfiles = TransformStochasticSoilProfiles(stochasticSoilModel.StochasticSoilProfiles); Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Importers/PipingSoilProfileTransformerTest.cs =================================================================== diff -u -r15ba57d868f00dfd3d6b52ac2e03a202d47d0303 -r22002c62bf845369153bab8a9530dc1168f3870f --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Importers/PipingSoilProfileTransformerTest.cs (.../PipingSoilProfileTransformerTest.cs) (revision 15ba57d868f00dfd3d6b52ac2e03a202d47d0303) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Importers/PipingSoilProfileTransformerTest.cs (.../PipingSoilProfileTransformerTest.cs) (revision 22002c62bf845369153bab8a9530dc1168f3870f) @@ -20,8 +20,14 @@ // All rights reserved. using System; +using System.Collections.Generic; +using System.Linq; +using Core.Common.Base.Geometry; using NUnit.Framework; +using Ringtoets.Common.IO.Exceptions; using Ringtoets.Common.IO.SoilProfile; +using Ringtoets.Common.IO.TestUtil; +using Ringtoets.Piping.Data.TestUtil; using Ringtoets.Piping.IO.Importers; using Ringtoets.Piping.Primitives; @@ -42,18 +48,330 @@ } [Test] - public void Transform_InvalidSoilProfile_ReturnsNull() + public void Transform_InvalidSoilProfile_ThrowsImportedDataTransformException() { // Setup var invalidType = new TestSoilProfile(); // Call - PipingSoilProfile transformed = PipingSoilProfileTransformer.Transform(invalidType); + TestDelegate test = () => PipingSoilProfileTransformer.Transform(invalidType); // Assert - Assert.IsNull(transformed); + var exception = Assert.Throws(test); + Assert.AreEqual("Soil profile of type 'TestSoilProfile' is not supported." + + "Only soil profiles of type 'SoilProfile1D' or 'SoilProfile2D' are supported.", exception.Message); } + [Test] + public void Transform_SoilProfile2DWithoutIntersection_ThrowsImportedDataTransformException() + { + // Setup + const string name = "name"; + var profile = new SoilProfile2D(0, name, Enumerable.Empty()); + + // Call + TestDelegate test = () => PipingSoilProfileTransformer.Transform(profile); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual($"Geen geldige X waarde gevonden om intersectie te maken uit 2D profiel '{name}'.", + exception.Message); + } + + [Test] + public void Transform_ValidSoilProfile2D_ReturnsExpectedPipingSoilProfile() + { + // Setup + const string name = "name"; + const double bottom = 0.5; + const double intersectionX = 1.0; + + SoilLayer2D layer = SoilLayer2DTestFactory.CreateSoilLayer2D(new List(), + new List + { + new Segment2D(new Point2D(1.0, bottom), + new Point2D(1.2, 1)), + new Segment2D(new Point2D(1.2, 1), + new Point2D(1.0, bottom)) + }); + var profile = new SoilProfile2D(0, name, new[] + { + layer + }) + { + IntersectionX = intersectionX + }; + + // Call + PipingSoilProfile transformed = PipingSoilProfileTransformer.Transform(profile); + + // Assert + Assert.AreEqual(name, transformed.Name); + Assert.AreEqual(SoilProfileType.SoilProfile2D, transformed.SoilProfileType); + Assert.AreEqual(bottom, transformed.Bottom); + + double bottomOut; + IEnumerable actualPipingSoilLayers = PipingSoilLayerTransformer.Transform( + layer, intersectionX, out bottomOut); + + AssertPipingSoilLayers(actualPipingSoilLayers, transformed.Layers); + } + + [Test] + public void Transform_LayerWithVerticalLineOnXInXml_ThrowsImportedDataTransformException() + { + // Setup + const string profileName = "SomeProfile"; + const double atX = 0.0; + + SoilLayer2D layer = SoilLayer2DTestFactory.CreateSoilLayer2D( + new List(), + new List + { + new Segment2D(new Point2D(atX, 0.0), + new Point2D(atX, 1.0)), + new Segment2D(new Point2D(atX, 1.0), + new Point2D(0.5, 0.5)), + new Segment2D(new Point2D(0.5, 0.5), + new Point2D(atX, 0.0)) + }); + + var profile = new SoilProfile2D(0, profileName, new[] + { + layer + }) + { + IntersectionX = atX + }; + + // Call + TestDelegate test = () => PipingSoilProfileTransformer.Transform(profile); + + // Assert + var exception = Assert.Throws(test); + string message = "Er kan geen 1D-profiel bepaald worden wanneer segmenten in een 2D " + + $"laag verticaal lopen op de gekozen positie: x = {atX}."; + Assert.AreEqual(message, exception.Message); + } + + [Test] + public void Transform_WithOutLayers_ThrowsImportedDataTransformException() + { + // Setup + const string profileName = "SomeProfile"; + var profile = new SoilProfile2D(0, profileName, new[] + { + new SoilLayer2D() + }); + + // Call + TestDelegate test = () => PipingSoilProfileTransformer.Transform(profile); + + // Assert + Assert.Throws(test); + } + + [Test] + public void Transform_WithSingleLayerOnlyOuterLoop_ReturnsProfileWithBottomAndALayer() + { + // Setup + const string profileName = "SomeProfile"; + var firstPoint = new Point2D(-0.5, 1.0); + var secondPoint = new Point2D(0.5, 1.0); + var thirdPoint = new Point2D(0.5, -1.0); + var fourthPoint = new Point2D(-0.5, -1.0); + + SoilLayer2D layer = SoilLayer2DTestFactory.CreateSoilLayer2D( + new List(), + new List + { + new Segment2D(firstPoint, secondPoint), + new Segment2D(secondPoint, thirdPoint), + new Segment2D(thirdPoint, fourthPoint), + new Segment2D(fourthPoint, firstPoint) + }); + layer.IsAquifer = true; + + var profile = new SoilProfile2D(0, profileName, new[] + { + layer + }) + { + IntersectionX = 0.0 + }; + + // Call + PipingSoilProfile transformed = PipingSoilProfileTransformer.Transform(profile); + + // Assert + Assert.AreEqual(profileName, transformed.Name); + Assert.AreEqual(1, transformed.Layers.Count()); + Assert.AreEqual(1.0, transformed.Layers.ToArray()[0].Top); + Assert.AreEqual(-1.0, transformed.Bottom); + Assert.AreEqual(SoilProfileType.SoilProfile2D, transformed.SoilProfileType); + } + + [Test] + public void Transform_WithMultipleLayersOnlyOuterLoop_ReturnsProfileWithBottomAndALayers() + { + // Setup + const string profileName = "SomeProfile"; + const long pipingSoilProfileId = 1234L; + + var profile = new SoilProfile2D(pipingSoilProfileId, profileName, + new List + { + SoilLayer2DTestFactory.CreateSoilLayer2D( + new List(), + Segment2DLoopCollectionHelper.CreateFromString( + string.Join(Environment.NewLine, + "10", + "...", + "...", + "...", + "...", + "...", + "...", + "...", + "1.2", + "4.3", + "..."))), + SoilLayer2DTestFactory.CreateSoilLayer2D( + new List(), + Segment2DLoopCollectionHelper.CreateFromString( + string.Join(Environment.NewLine, + "10", + "...", + "...", + "...", + "...", + "...", + "4.3", + "...", + "1.2", + "...", + "..."))), + SoilLayer2DTestFactory.CreateSoilLayer2D( + new List(), + Segment2DLoopCollectionHelper.CreateFromString( + string.Join(Environment.NewLine, + "10", + "...", + "1.2", + "...", + "...", + "...", + "4.3", + "...", + "...", + "...", + "..."))) + }) + { + IntersectionX = 1.0 + }; + + // Call + PipingSoilProfile transformed = PipingSoilProfileTransformer.Transform(profile); + + // Assert + Assert.AreEqual(profileName, transformed.Name); + Assert.AreEqual(3, transformed.Layers.Count()); + CollectionAssert.AreEquivalent(new[] + { + 2.0, + 4.0, + 8.0 + }, transformed.Layers.Select(rl => rl.Top)); + Assert.AreEqual(1.0, transformed.Bottom); + } + + [Test] + public void Transform_WithLayerFilledWithOtherLayer_ReturnsProfileWithBottomAndALayers() + { + // Setup + const string profileName = "SomeProfile"; + const long pipingSoilProfileId = 1234L; + List loopHole = Segment2DLoopCollectionHelper.CreateFromString( + string.Join(Environment.NewLine, + "5", + ".....", + ".4.1.", + ".3.2.", + ".....", + ".....")); + + SoilLayer2D soilLayer2D = SoilLayer2DTestFactory.CreateSoilLayer2D( + new[] + { + loopHole + }, + Segment2DLoopCollectionHelper.CreateFromString( + string.Join(Environment.NewLine, + "5", + "2...3", + ".....", + ".....", + ".....", + "1...4"))); + soilLayer2D.IsAquifer = true; + + var profile = new SoilProfile2D(pipingSoilProfileId, profileName, + new List + { + soilLayer2D, + SoilLayer2DTestFactory.CreateSoilLayer2D( + new List(), + loopHole) + } + ) + { + IntersectionX = 2.0 + }; + + // Call + PipingSoilProfile transformed = PipingSoilProfileTransformer.Transform(profile); + + // Assert + Assert.AreEqual(profileName, transformed.Name); + Assert.AreEqual(3, transformed.Layers.Count()); + CollectionAssert.AreEquivalent(new[] + { + 4.0, + 3.0, + 2.0 + }, transformed.Layers.Select(rl => rl.Top)); + Assert.AreEqual(0.0, transformed.Bottom); + } + + private static void AssertPipingSoilLayers(IEnumerable expectedSoilLayer2Ds, + IEnumerable actualSoilLayer2Ds) + { + PipingSoilLayer[] expectedSoilLayer2DsArray = expectedSoilLayer2Ds.ToArray(); + PipingSoilLayer[] actualSoilLayers2DArray = actualSoilLayer2Ds.ToArray(); + Assert.AreEqual(expectedSoilLayer2DsArray.Length, actualSoilLayers2DArray.Length); + + for (var i = 0; i < expectedSoilLayer2DsArray.Length; i++) + { + AssertPipingSoilLayer(expectedSoilLayer2DsArray[i], actualSoilLayers2DArray[i]); + } + } + + private static void AssertPipingSoilLayer(PipingSoilLayer expected, PipingSoilLayer actual) + { + Assert.AreEqual(expected.Top, actual.Top); + Assert.AreEqual(expected.IsAquifer, actual.IsAquifer); + Assert.AreEqual(expected.BelowPhreaticLevelMean, actual.BelowPhreaticLevelMean); + Assert.AreEqual(expected.BelowPhreaticLevelDeviation, actual.BelowPhreaticLevelDeviation); + Assert.AreEqual(expected.BelowPhreaticLevelShift, actual.BelowPhreaticLevelShift); + Assert.AreEqual(expected.DiameterD70Mean, actual.DiameterD70Mean); + Assert.AreEqual(expected.DiameterD70CoefficientOfVariation, actual.DiameterD70CoefficientOfVariation); + Assert.AreEqual(expected.PermeabilityMean, actual.PermeabilityMean); + Assert.AreEqual(expected.PermeabilityCoefficientOfVariation, actual.PermeabilityCoefficientOfVariation); + Assert.AreEqual(expected.MaterialName, actual.MaterialName); + Assert.AreEqual(expected.Color, actual.Color); + } + private class TestSoilProfile : ISoilProfile { public string Name { get; } Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Importers/PipingStochasticSoilModelTransformerTest.cs =================================================================== diff -u -r03fa491ac6713c77d10987a9ba1d0776dfdf82e9 -r22002c62bf845369153bab8a9530dc1168f3870f --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Importers/PipingStochasticSoilModelTransformerTest.cs (.../PipingStochasticSoilModelTransformerTest.cs) (revision 03fa491ac6713c77d10987a9ba1d0776dfdf82e9) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Importers/PipingStochasticSoilModelTransformerTest.cs (.../PipingStochasticSoilModelTransformerTest.cs) (revision 22002c62bf845369153bab8a9530dc1168f3870f) @@ -58,7 +58,7 @@ // Assert var exception = Assert.Throws(test); Assert.AreEqual($"Stochastic soil model of failure mechanism type '{failureMechanismType}' is not supported." + - $"Only '{FailureMechanismType.Piping}' is supported.", exception.Message); + $"Only stochastic soil model of failure mechanism type '{FailureMechanismType.Piping}' is supported.", exception.Message); } private static IEnumerable InvalidFailureMechanismTypes()