Index: Ringtoets/MacroStabilityInwards/src/Ringtoets.MacroStabilityInwards.Data/Ringtoets.MacroStabilityInwards.Data.csproj
===================================================================
diff -u -rf7df02224d9e80cda83c8b757617c449b3bcfd4e -rf6f910cf9e6c78af77bbac56f232242553e3f9de
--- Ringtoets/MacroStabilityInwards/src/Ringtoets.MacroStabilityInwards.Data/Ringtoets.MacroStabilityInwards.Data.csproj (.../Ringtoets.MacroStabilityInwards.Data.csproj) (revision f7df02224d9e80cda83c8b757617c449b3bcfd4e)
+++ Ringtoets/MacroStabilityInwards/src/Ringtoets.MacroStabilityInwards.Data/Ringtoets.MacroStabilityInwards.Data.csproj (.../Ringtoets.MacroStabilityInwards.Data.csproj) (revision f6f910cf9e6c78af77bbac56f232242553e3f9de)
@@ -57,6 +57,7 @@
+
@@ -69,6 +70,10 @@
Core.Common.Base
False
+
+ {88665510-CE20-4EF5-BE4A-39800720AA2C}
+ Core.Common.Geometry
+
{d4200f43-3f72-4f42-af0a-8ced416a38ec}
Ringtoets.Common.Data
Index: Ringtoets/MacroStabilityInwards/src/Ringtoets.MacroStabilityInwards.Data/SoilProfileUnderSurfaceLineFactory.cs
===================================================================
diff -u
--- Ringtoets/MacroStabilityInwards/src/Ringtoets.MacroStabilityInwards.Data/SoilProfileUnderSurfaceLineFactory.cs (revision 0)
+++ Ringtoets/MacroStabilityInwards/src/Ringtoets.MacroStabilityInwards.Data/SoilProfileUnderSurfaceLineFactory.cs (revision f6f910cf9e6c78af77bbac56f232242553e3f9de)
@@ -0,0 +1,154 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of Ringtoets.
+//
+// Ringtoets is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using Core.Common.Base.Geometry;
+using Core.Common.Geometry;
+using Ringtoets.MacroStabilityInwards.Primitives;
+
+namespace Ringtoets.MacroStabilityInwards.Data
+{
+ public class SoilProfileUnderSurfaceLineFactory
+ {
+ public static SoilProfileUnderSurfaceLine Create(MacroStabilityInwardsSoilProfile soilProfile, RingtoetsMacroStabilityInwardsSurfaceLine surfaceLine)
+ {
+ if (soilProfile == null)
+ {
+ throw new ArgumentNullException(nameof(soilProfile));
+ }
+ if (surfaceLine == null)
+ {
+ throw new ArgumentNullException(nameof(surfaceLine));
+ }
+ Point2D[] localizedSurfaceLine = surfaceLine.ProjectGeometryToLZ().ToArray();
+
+ IEnumerable surfaceLineGeometry = CreateSurfaceLineAreaToDepth(localizedSurfaceLine, soilProfile.Bottom);
+ IEnumerable layerGeometries = soilProfile.Layers.Select(l => As2DGeometry(l, soilProfile, localizedSurfaceLine.First().X, localizedSurfaceLine.Last().X));
+
+ return GeometriesToIntersections(layerGeometries, surfaceLineGeometry);
+ }
+
+ private static SoilProfileUnderSurfaceLine GeometriesToIntersections(IEnumerable layerGeometries, IEnumerable surfaceLineGeometry)
+ {
+ var collection = new Collection();
+
+ IEnumerable surfaceLineGeometryArray = surfaceLineGeometry.ToArray();
+
+ foreach (TempSoilLayerGeometry layer in layerGeometries)
+ {
+ foreach (Point2D[] soilLayerArea in CreateSoilLayerAreas(surfaceLineGeometryArray, layer.OuterLoop))
+ {
+ collection.Add(new SoilLayerUnderSurfaceLine(soilLayerArea, layer.Properties));
+ }
+ }
+
+ return new SoilProfileUnderSurfaceLine(collection);
+ }
+
+ private static TempSoilLayerGeometry As2DGeometry(MacroStabilityInwardsSoilLayer layer, MacroStabilityInwardsSoilProfile soilProfile, double minX, double maxX)
+ {
+ double top = layer.Top;
+ double bottom = layer.Top - soilProfile.GetLayerThickness(layer);
+
+ return new TempSoilLayerGeometry(new[]
+ {
+ new Point2D(minX, top),
+ new Point2D(maxX, top),
+ new Point2D(maxX, bottom),
+ new Point2D(minX, bottom)
+ }, layer.Properties);
+ }
+
+ private static IEnumerable CreateSurfaceLineAreaToDepth(Point2D[] localizedSurfaceLine, double soilProfileBottom)
+ {
+ foreach (Point2D point in localizedSurfaceLine)
+ {
+ yield return point;
+ }
+ double geometryBottom = Math.Min(soilProfileBottom, localizedSurfaceLine.Min(p => p.Y)) - 1;
+ yield return new Point2D(localizedSurfaceLine.Last().X, geometryBottom);
+ yield return new Point2D(localizedSurfaceLine.First().X, geometryBottom);
+ }
+
+ private static IEnumerable CreateSoilLayerAreas(IEnumerable surfaceLineGeometry, IEnumerable soilLayerGeometry)
+ {
+ return GetSoilLayerWithSurfaceLineIntersection(surfaceLineGeometry, soilLayerGeometry);
+ }
+
+ private static IEnumerable GetSoilLayerWithSurfaceLineIntersection(IEnumerable surfaceLineGeometry, IEnumerable soilLayerGeometry)
+ {
+ return AdvancedMath2D.PolygonIntersectionWithPolygon(surfaceLineGeometry, soilLayerGeometry).Where(arr => arr.Length > 2);
+ }
+
+ private class TempSoilLayerGeometry
+ {
+ public TempSoilLayerGeometry(Point2D[] outerLoop, SoilLayerProperties properties)
+ {
+ OuterLoop = outerLoop;
+ Properties = properties;
+ InnerLoops = Enumerable.Empty();
+ }
+
+ public Point2D[] OuterLoop { get; }
+ public SoilLayerProperties Properties { get; }
+ public IEnumerable InnerLoops { get; }
+ }
+ }
+
+ public class SoilProfileUnderSurfaceLine
+ {
+ public SoilProfileUnderSurfaceLine(IEnumerable layersUnderSurfaceLine)
+ {
+ if (layersUnderSurfaceLine == null)
+ {
+ throw new ArgumentNullException(nameof(layersUnderSurfaceLine));
+ }
+ LayersUnderSurfaceLine = layersUnderSurfaceLine;
+ }
+
+ public IEnumerable LayersUnderSurfaceLine { get; }
+ }
+
+ public class SoilLayerUnderSurfaceLine
+ {
+ public SoilLayerUnderSurfaceLine(Point2D[] outerLoop, SoilLayerProperties properties)
+ {
+ if (outerLoop == null)
+ {
+ throw new ArgumentNullException(nameof(outerLoop));
+ }
+ if (properties == null)
+ {
+ throw new ArgumentNullException(nameof(properties));
+ }
+ OuterLoop = outerLoop;
+ InnerLoops = Enumerable.Empty();
+ Properties = properties;
+ }
+
+ public Point2D[] OuterLoop { get; }
+ public IEnumerable InnerLoops { get; }
+ public SoilLayerProperties Properties { get; }
+ }
+}
\ No newline at end of file
Index: Ringtoets/MacroStabilityInwards/test/Ringtoets.MacroStabilityInwards.Data.Test/Ringtoets.MacroStabilityInwards.Data.Test.csproj
===================================================================
diff -u -rf7df02224d9e80cda83c8b757617c449b3bcfd4e -rf6f910cf9e6c78af77bbac56f232242553e3f9de
--- Ringtoets/MacroStabilityInwards/test/Ringtoets.MacroStabilityInwards.Data.Test/Ringtoets.MacroStabilityInwards.Data.Test.csproj (.../Ringtoets.MacroStabilityInwards.Data.Test.csproj) (revision f7df02224d9e80cda83c8b757617c449b3bcfd4e)
+++ Ringtoets/MacroStabilityInwards/test/Ringtoets.MacroStabilityInwards.Data.Test/Ringtoets.MacroStabilityInwards.Data.Test.csproj (.../Ringtoets.MacroStabilityInwards.Data.Test.csproj) (revision f6f910cf9e6c78af77bbac56f232242553e3f9de)
@@ -61,6 +61,7 @@
+
Index: Ringtoets/MacroStabilityInwards/test/Ringtoets.MacroStabilityInwards.Data.Test/SoilProfileUnderSurfaceLineFactory.cs
===================================================================
diff -u
--- Ringtoets/MacroStabilityInwards/test/Ringtoets.MacroStabilityInwards.Data.Test/SoilProfileUnderSurfaceLineFactory.cs (revision 0)
+++ Ringtoets/MacroStabilityInwards/test/Ringtoets.MacroStabilityInwards.Data.Test/SoilProfileUnderSurfaceLineFactory.cs (revision f6f910cf9e6c78af77bbac56f232242553e3f9de)
@@ -0,0 +1,302 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of Ringtoets.
+//
+// Ringtoets is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+using System;
+using System.Linq;
+using Core.Common.Base.Geometry;
+using NUnit.Framework;
+using Ringtoets.MacroStabilityInwards.Primitives;
+
+namespace Ringtoets.MacroStabilityInwards.Data.Test
+{
+ [TestFixture]
+ public class SoilProfileUnderSurfaceLineFactoryTest
+ {
+ [Test]
+ public void Create_SoilProfileNull_ThrowArgumentNullException()
+ {
+ // Setup
+ var surfaceLine = new RingtoetsMacroStabilityInwardsSurfaceLine();
+
+ // Call
+ TestDelegate test = () => SoilProfileUnderSurfaceLineFactory.Create(null, surfaceLine);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("soilProfile", exception.ParamName);
+ }
+
+ [Test]
+ public void Create_SurfaceLineNull_ThrowArgumentNullException()
+ {
+ // Setup
+ var soilProfile = new MacroStabilityInwardsSoilProfile("name", 2.0, new[]
+ {
+ new MacroStabilityInwardsSoilLayer(2)
+ }, SoilProfileType.SoilProfile1D, 0);
+
+ // Call
+ TestDelegate test = () => SoilProfileUnderSurfaceLineFactory.Create(soilProfile, null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("surfaceLine", exception.ParamName);
+ }
+
+ [Test]
+ public void Create_SurfaceLineOnTopOrAboveSoilLayer_ReturnsSoilLayerPointsAsRectangle()
+ {
+ // Setup
+ var surfaceLine = new RingtoetsMacroStabilityInwardsSurfaceLine();
+ surfaceLine.SetGeometry(new[]
+ {
+ new Point3D(0, 0, 4),
+ new Point3D(0, 0, 3.2),
+ new Point3D(2, 0, 4)
+ });
+ var soilLayer = new MacroStabilityInwardsSoilLayer(3.2);
+ var soilProfile = new MacroStabilityInwardsSoilProfile("name", 2.0, new[]
+ {
+ soilLayer
+ }, SoilProfileType.SoilProfile1D, 0);
+
+ // Call
+ SoilProfileUnderSurfaceLine areas = SoilProfileUnderSurfaceLineFactory.Create(soilProfile, surfaceLine);
+
+ // Assert
+ Assert.AreEqual(1, areas.LayersUnderSurfaceLine.Count());
+ CollectionAssert.AreEqual(new[]
+ {
+ new Point2D(2, 3.2),
+ new Point2D(2, 2),
+ new Point2D(0, 2),
+ new Point2D(0, 3.2)
+ }, areas.LayersUnderSurfaceLine.ElementAt(0).OuterLoop);
+ }
+
+ [Test]
+ public void Create_SurfaceLineBelowSoilLayer_ReturnsEmptyAreasCollection()
+ {
+ // Setup
+ var surfaceLine = new RingtoetsMacroStabilityInwardsSurfaceLine();
+ surfaceLine.SetGeometry(new[]
+ {
+ new Point3D(0, 0, 2.0),
+ new Point3D(2, 0, 2.0)
+ });
+ var soilLayer = new MacroStabilityInwardsSoilLayer(3.2);
+ var soilProfile = new MacroStabilityInwardsSoilProfile("name", 2.0, new[]
+ {
+ soilLayer
+ }, SoilProfileType.SoilProfile1D, 0);
+
+ // Call
+ SoilProfileUnderSurfaceLine areas = SoilProfileUnderSurfaceLineFactory.Create(soilProfile, surfaceLine);
+
+ // Assert
+ CollectionAssert.IsEmpty(areas.LayersUnderSurfaceLine);
+ }
+
+ [Test]
+ public void Create_SurfaceLineThroughMiddleLayerButNotSplittingIt_ReturnsSoilLayerPointsAsRectangleFollowingSurfaceLine()
+ {
+ // Setup
+ var surfaceLine = new RingtoetsMacroStabilityInwardsSurfaceLine();
+ surfaceLine.SetGeometry(new[]
+ {
+ new Point3D(0, 0, 3.0),
+ new Point3D(1, 0, 2.0),
+ new Point3D(2, 0, 3.0)
+ });
+ const double bottom = 1.5;
+ const double top = 2.5;
+ var soilLayer = new MacroStabilityInwardsSoilLayer(top);
+ var soilProfile = new MacroStabilityInwardsSoilProfile("name", bottom, new[]
+ {
+ soilLayer
+ }, SoilProfileType.SoilProfile1D, 0);
+
+ // Call
+ SoilProfileUnderSurfaceLine areas = SoilProfileUnderSurfaceLineFactory.Create(soilProfile, surfaceLine);
+
+ // Assert
+ Assert.AreEqual(1, areas.LayersUnderSurfaceLine.Count());
+ CollectionAssert.AreEqual(new[]
+ {
+ new Point2D(0.5, top),
+ new Point2D(1, 2.0),
+ new Point2D(1.5, top),
+ new Point2D(2, top),
+ new Point2D(2, bottom),
+ new Point2D(0, bottom),
+ new Point2D(0, top)
+ }, areas.LayersUnderSurfaceLine.ElementAt(0).OuterLoop);
+ }
+
+ [Test]
+ public void Create_SurfaceLineThroughMiddleLayerButNotSplittingItIntersectionOnTopLevel_ReturnsSoilLayerPointsAsRectangleFollowingSurfaceLine()
+ {
+ // Setup
+ var surfaceLine = new RingtoetsMacroStabilityInwardsSurfaceLine();
+ surfaceLine.SetGeometry(new[]
+ {
+ new Point3D(0, 0, 3.0),
+ new Point3D(0.5, 0, 2.5),
+ new Point3D(1, 0, 2.0),
+ new Point3D(1.5, 0, 2.5),
+ new Point3D(2, 0, 3.0)
+ });
+ const double bottom = 1.5;
+ const double top = 2.5;
+ var soilLayer = new MacroStabilityInwardsSoilLayer(top);
+ var soilProfile = new MacroStabilityInwardsSoilProfile("name", bottom, new[]
+ {
+ soilLayer
+ }, SoilProfileType.SoilProfile1D, 0);
+
+ // Call
+ SoilProfileUnderSurfaceLine areas = SoilProfileUnderSurfaceLineFactory.Create(soilProfile, surfaceLine);
+
+ // Assert
+ Assert.AreEqual(1, areas.LayersUnderSurfaceLine.Count());
+ CollectionAssert.AreEqual(new[]
+ {
+ new Point2D(0.5, top),
+ new Point2D(1, 2.0),
+ new Point2D(1.5, top),
+ new Point2D(2, top),
+ new Point2D(2, bottom),
+ new Point2D(0, bottom),
+ new Point2D(0, top)
+ }, areas.LayersUnderSurfaceLine.ElementAt(0).OuterLoop);
+ }
+
+ [Test]
+ public void Create_SurfaceLineStartsBelowLayerTopButAboveBottom_ReturnsSoilLayerPointsAsRectangleFollowingSurfaceLine()
+ {
+ // Setup
+ var surfaceLine = new RingtoetsMacroStabilityInwardsSurfaceLine();
+ surfaceLine.SetGeometry(new[]
+ {
+ new Point3D(0, 0, 2.0),
+ new Point3D(1, 0, 2.0),
+ new Point3D(2, 0, 3.0)
+ });
+ const double bottom = 1.5;
+ const double top = 2.5;
+ var soilLayer = new MacroStabilityInwardsSoilLayer(top);
+ var soilProfile = new MacroStabilityInwardsSoilProfile("name", bottom, new[]
+ {
+ soilLayer
+ }, SoilProfileType.SoilProfile1D, 0);
+
+ // Call
+ SoilProfileUnderSurfaceLine areas = SoilProfileUnderSurfaceLineFactory.Create(soilProfile, surfaceLine);
+
+ // Assert
+ Assert.AreEqual(1, areas.LayersUnderSurfaceLine.Count());
+ CollectionAssert.AreEqual(new[]
+ {
+ new Point2D(0, 2.0),
+ new Point2D(1, 2.0),
+ new Point2D(1.5, top),
+ new Point2D(2, top),
+ new Point2D(2, bottom),
+ new Point2D(0, bottom)
+ }, areas.LayersUnderSurfaceLine.ElementAt(0).OuterLoop);
+ }
+
+ [Test]
+ public void Create_SurfaceLineEndsBelowLayerTopButAboveBottom_ReturnsSoilLayerPointsAsRectangleFollowingSurfaceLine()
+ {
+ // Setup
+ var surfaceLine = new RingtoetsMacroStabilityInwardsSurfaceLine();
+ surfaceLine.SetGeometry(new[]
+ {
+ new Point3D(0, 0, 3.0),
+ new Point3D(1, 0, 2.0),
+ new Point3D(2, 0, 2.0)
+ });
+ const double bottom = 1.5;
+ const double top = 2.5;
+ var soilLayer = new MacroStabilityInwardsSoilLayer(top);
+ var soilProfile = new MacroStabilityInwardsSoilProfile("name", bottom, new[]
+ {
+ soilLayer
+ }, SoilProfileType.SoilProfile1D, 0);
+
+ // Call
+ SoilProfileUnderSurfaceLine areas = SoilProfileUnderSurfaceLineFactory.Create(soilProfile, surfaceLine);
+
+ // Assert
+ Assert.AreEqual(1, areas.LayersUnderSurfaceLine.Count());
+ CollectionAssert.AreEqual(new[]
+ {
+ new Point2D(0.5, top),
+ new Point2D(1, 2.0),
+ new Point2D(2, 2.0),
+ new Point2D(2, bottom),
+ new Point2D(0, bottom),
+ new Point2D(0, top)
+ }, areas.LayersUnderSurfaceLine.ElementAt(0).OuterLoop);
+ }
+
+ [Test]
+ public void Create_SurfaceLineZigZagsThroughSoilLayer_ReturnsSoilLayerPointsSplitInMultipleAreas()
+ {
+ // Setup
+ var surfaceLine = new RingtoetsMacroStabilityInwardsSurfaceLine();
+ surfaceLine.SetGeometry(new[]
+ {
+ new Point3D(0, 0, 4.0),
+ new Point3D(4, 0, 0.0),
+ new Point3D(8, 0, 4.0)
+ });
+ const int bottom = 1;
+ const int top = 3;
+ var soilLayer = new MacroStabilityInwardsSoilLayer(top);
+ var soilProfile = new MacroStabilityInwardsSoilProfile("name", bottom, new[]
+ {
+ soilLayer
+ }, SoilProfileType.SoilProfile1D, 0);
+
+ // Call
+ SoilProfileUnderSurfaceLine areas = SoilProfileUnderSurfaceLineFactory.Create(soilProfile, surfaceLine);
+
+ // Assert
+ Assert.AreEqual(2, areas.LayersUnderSurfaceLine.Count());
+ CollectionAssert.AreEqual(new[]
+ {
+ new Point2D(1, top),
+ new Point2D(3, bottom),
+ new Point2D(0, bottom),
+ new Point2D(0, top)
+ }, areas.LayersUnderSurfaceLine.ElementAt(0).OuterLoop);
+ CollectionAssert.AreEqual(new[]
+ {
+ new Point2D(5, bottom),
+ new Point2D(7, top),
+ new Point2D(8, top),
+ new Point2D(8, bottom)
+ }, areas.LayersUnderSurfaceLine.ElementAt(1).OuterLoop);
+ }
+ }
+}
\ No newline at end of file