Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Extensions.cs =================================================================== diff -u -r955 -r967 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Extensions.cs (.../SurfaceLine2Extensions.cs) (revision 955) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Extensions.cs (.../SurfaceLine2Extensions.cs) (revision 967) @@ -485,7 +485,37 @@ (dikeToeInward.X - dikeTopAtPolder.X); } + /// + /// Determines the shoulder length for given shoulder top inside. + /// + /// The line. + /// The shoulder top inside. + /// + public static double DetermineShoulderLengthForGivenShoulderTopInside(this SurfaceLine2 line, GeometryPoint shoulderTopInside) + { + GeometryPoint geometryPoint1 = line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder); + GeometryPoint geometryPoint2 = line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); + GeometryPoint p2 = line.HasShoulderInside() ? line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside) : geometryPoint2; + GeometryPoint geometryPoint3 = line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelOutside); + GeometryPoint withExtrapolation = LineHelper.GetIntersectionPointWithExtrapolation(geometryPoint1, p2, shoulderTopInside, new GeometryPoint(geometryPoint3.X, shoulderTopInside.Z)); + return shoulderTopInside.X - withExtrapolation.X; + } + /// + /// Determines the height of the shoulder. + /// + /// The line. + /// + public static double DetermineShoulderHeight(this SurfaceLine2 line) + { + GeometryPoint geometryPoint1 = line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + GeometryPoint geometryPoint2 = line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); + if (geometryPoint1 != null && geometryPoint2 != null) + return geometryPoint1.Z - line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; + return 0.0; + } + + #region Private methods /// /// Create a horizontal line from a given starting X coordinate and ending at the /// X coordinate of defined @@ -551,5 +581,6 @@ Level, dikeTopAtRiver.Z)); } } + #endregion Private methods } } \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/DikesDesign/SurfaceLineShoulderAdapterTest.cs =================================================================== diff -u --- DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/DikesDesign/SurfaceLineShoulderAdapterTest.cs (revision 0) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/DikesDesign/SurfaceLineShoulderAdapterTest.cs (revision 967) @@ -0,0 +1,1669 @@ +// Copyright (C) Stichting Deltares 2018. All rights reserved. +// +// This file is part of the Dam Engine. +// +// The Dam Engine is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero 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 Deltares.DamEngine.Calculators.DikesDesign; +using Deltares.DamEngine.Calculators.Dikes_Design; +using Deltares.DamEngine.Data.General; +using Deltares.DamEngine.Data.Geometry; +using Deltares.DamEngine.Data.Geotechnics; +using NUnit.Framework; + +namespace Deltares.DamEngine.Calculators.Tests.DikesDesign +{ + [TestFixture] + public class SurfaceLineShoulderAdapterTest + { + const double pointCoordinateTolerance = 0.001; + + [Test] + [ExpectedException(typeof(SurfaceLineAdapterException))] + public void ThrowsAnExceptionWhenNoSurfaceLevelPointExist() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 1, Z = 1 }; + var pointAtTopPolder = new GeometryPoint { X = 2, Z = 1 }; + var pointAtToePolder = new GeometryPoint { X = 3, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + } + + /// + /// Test if ConstructNewSurfaceLine returns a new surface line. + /// + [Test] + public void ConstructNewSurfaceLineReturnsANewSurfaceLine() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 1, Z = 1 }; + var pointAtTopPolder = new GeometryPoint { X = 2, Z = 1 }; + var pointAtToePolder = new GeometryPoint { X = 3, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 10, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + var constructNewSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(0, 0, false); + Assert.IsNotNull(constructNewSurfaceLine); + } + + /// + /// Test if adapt the surface line without shoulder returns surfaceline with both characteristic points at shoulder inside. + /// + [Test] + public void AdaptedSurfaceLineWithoutShoulderMustHaveBothCharacteristicPointsAtShoulderInside() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 1; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 2, Z = 2 }; + var pointAtTopPolder = new GeometryPoint { X = 3, Z = 2 }; + var pointAtToePolder = new GeometryPoint { X = 4, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 10, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + Assert.IsNull(surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside)); + Assert.IsNull(surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside)); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + Assert.IsNotNull(adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside)); + Assert.IsNotNull(adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside)); + } + + /// + /// Test if adapted surface line without shoulder has correct point at top shoulder inside. + /// + [Test] + public void AdaptedSurfaceLineWithoutShoulderHasCorrectPointAtTopShoulderInside() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 1; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 1, Z = 1 }; + var pointAtTopPolder = new GeometryPoint { X = 2, Z = 1 }; + var pointAtToePolder = new GeometryPoint { X = 3, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + surfaceLineAdapter.MaxShoulderLevel = 0.67; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + double expectedShoulderHeight = Math.Min(shoulderHeight, surfaceLineAdapter.MaxShoulderLevel - pointAtToePolder.Z); + var expectedPoint = new GeometryPoint(3.33, expectedShoulderHeight); + var actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + Assert.IsTrue(expectedPoint.LocationEquals(actualPoint)); + } + + /// + /// Test if adapted surface line without shoulder has correct intersection point at dike. + /// + [Test] + public void AdaptedSurfaceLineWithoutShoulderHasCorrectIntersectionPointAtDike() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 1; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 2, Z = 2 }; + var pointAtTopPolder = new GeometryPoint { X = 3, Z = 2 }; + var pointAtToePolder = new GeometryPoint { X = 4, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 10, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + var expectedPoint = new GeometryPoint(3.5, 1); + var actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); + Assert.IsTrue(expectedPoint.LocationEquals(actualPoint)); + } + + /// + /// Test if adapted surface line without shoulder has correct intersection point at ground level. + /// + [Test] + public void AdaptedSurfaceLineWithoutShoulderHasCorrectIntersectionPointAtGroundLevel() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 1; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 1, Z = 1 }; + var pointAtTopPolder = new GeometryPoint { X = 2, Z = 1 }; + var pointAtToePolder = new GeometryPoint { X = 3, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + double expectedShoulderHeight = Math.Min(shoulderHeight, (surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z - surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z)); + var expectedPoint = new GeometryPoint( + pointAtTopPolder.X + (1 - expectedShoulderHeight) + shoulderWidth + expectedShoulderHeight * surfaceLineAdapter.SlopeOfNewShoulder, 0); + var actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); + Assert.IsTrue(expectedPoint.LocationEquals(actualPoint)); + } + + /// + /// Test if adapted surface line without shoulder that the new shoulder should is not higher then top of dike. + /// + [Test] + public void AdaptedSurfaceLineWithoutShoulderNewShoulderShouldNotBeHeigherThenTopOfDike() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 1; + const int shoulderHeight = 3; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 2, Z = 2 }; + var pointAtTopPolder = new GeometryPoint { X = 3, Z = 2 }; + var pointAtToePolder = new GeometryPoint { X = 4, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 10, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + var expectedZ = pointAtTopPolder.Z; + var actualZ = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside).Z; + Assert.AreEqual(expectedZ, actualZ); + } + + [Test] + public void AdaptedSurfaceLineWithoutShoulderNewShoulderWidthShouldExpand() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 3; + const int shoulderHeight = 3; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 1, Z = 1 }; + var pointAtTopPolder = new GeometryPoint { X = 2, Z = 1 }; + var pointAtToePolder = new GeometryPoint { X = 3, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location) { SlopeOfNewShoulder = 2 }; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + double expectedShoulderHeight = Math.Min(shoulderHeight, (surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z - surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z)); + double expectedShoulderBaseX = pointAtTopPolder.X + (1 - expectedShoulderHeight); + Assert.AreEqual(expectedShoulderBaseX, adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside).X); + Assert.AreEqual(expectedShoulderHeight, adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside).Z); + Assert.AreEqual(expectedShoulderBaseX + shoulderWidth, adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside).X); + Assert.AreEqual(expectedShoulderHeight, adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside).Z); + Assert.AreEqual(expectedShoulderBaseX + shoulderWidth + surfaceLineAdapter.SlopeOfNewShoulder * expectedShoulderHeight, adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X); + Assert.AreEqual(0, adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z); + } + + [Test] + public void AdaptedSurfaceLineWithShoulderHasCorrectPointAtTopShoulderInside() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 1; + const int shoulderHeight = 1; + surfaceLine.EnsurePointOfType(-100, 0, CharacteristicPointType.SurfaceLevelOutside); + surfaceLine.EnsurePointOfType(0, 0, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(1, 1, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(2, 1, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(3, 0.5, CharacteristicPointType.ShoulderBaseInside); + surfaceLine.EnsurePointOfType(4, 0.5, CharacteristicPointType.ShoulderTopInside); + surfaceLine.EnsurePointOfType(5, 0, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(100, 0, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + surfaceLineAdapter.MaxShoulderLevel = 0.67; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + var expectedPoint = new GeometryPoint(3.66, 0.67); + var actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + Assert.IsTrue(expectedPoint.LocationEquals(actualPoint)); + } + + [Test] + public void AdaptedSurfaceLineWithShoulderHasCorrectShoulderPoints() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 2; + const int shoulderHeight = 1; + surfaceLine.EnsurePointOfType(-100, 0, CharacteristicPointType.SurfaceLevelOutside); + surfaceLine.EnsurePointOfType(0, 1, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(1, 2, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(2, 2, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(3, 1.5, CharacteristicPointType.ShoulderBaseInside); + surfaceLine.EnsurePointOfType(4, 1.5, CharacteristicPointType.ShoulderTopInside); + surfaceLine.EnsurePointOfType(5, 1, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(100, 1, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location) { SlopeOfNewShoulder = 2 }; + surfaceLineAdapter.MaxShoulderLevel = 0.67 + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + var expectedPoint = new GeometryPoint(6.00, 1); + var actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); + Assert.AreEqual(expectedPoint.X, actualPoint.X, pointCoordinateTolerance); + Assert.AreEqual(expectedPoint.Z, actualPoint.Z, pointCoordinateTolerance); + expectedPoint = new GeometryPoint(4.66, 1.67); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + Assert.AreEqual(expectedPoint.X, actualPoint.X, pointCoordinateTolerance); + Assert.AreEqual(expectedPoint.Z, actualPoint.Z, pointCoordinateTolerance); + expectedPoint = new GeometryPoint(2.66, 1.67); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); + Assert.AreEqual(expectedPoint.X, actualPoint.X, pointCoordinateTolerance); + Assert.AreEqual(expectedPoint.Z, actualPoint.Z, pointCoordinateTolerance); + } + + [Test] + public void AdaptedSurfaceLineWithShoulderHasCorrectPointAtInsteekShoulderInside() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 1; + const int shoulderHeight = 1; + surfaceLine.EnsurePointOfType(-1, 0, CharacteristicPointType.SurfaceLevelOutside); + surfaceLine.EnsurePointOfType(0, 0, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(1, 4, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(2, 4, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(3, 0.5, CharacteristicPointType.ShoulderBaseInside); + surfaceLine.EnsurePointOfType(4, 0.5, CharacteristicPointType.ShoulderTopInside); + surfaceLine.EnsurePointOfType(5, 0, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(10, 0, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + var expectedPoint = new GeometryPoint(2.857, 1.0); + var actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); + Assert.AreEqual(expectedPoint.X, actualPoint.X, pointCoordinateTolerance); + Assert.AreEqual(expectedPoint.Z, actualPoint.Z, pointCoordinateTolerance); + } + + [Test] + public void AdaptedSurfaceLineHasCorrectTail() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 1; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 1, Z = 4 }; + var pointAtTopPolder = new GeometryPoint { X = 2, Z = 4 }; + var pointAtShoulderInsteek = new GeometryPoint { X = 3, Z = 0.5 }; + var pointAtShoulderTop = new GeometryPoint { X = 4, Z = 0.5 }; + var pointAtToePolder = new GeometryPoint { X = 5, Z = 0 }; + var extraPoint1 = new GeometryPoint { X = 8, Z = -2 }; + var extraPoint2 = new GeometryPoint { X = 9, Z = -1 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 10, Z = 0 }; + var pointAtSurfaceLevelOutside = new GeometryPoint { X = -1, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtShoulderInsteek.X, pointAtShoulderInsteek.Z, CharacteristicPointType.ShoulderBaseInside); + surfaceLine.EnsurePointOfType(pointAtShoulderTop.X, pointAtShoulderTop.Z, CharacteristicPointType.ShoulderTopInside); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePoint(extraPoint1.X, extraPoint1.Z); + surfaceLine.EnsurePoint(extraPoint2.X, extraPoint2.Z); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelOutside.X, pointAtSurfaceLevelOutside.Z, CharacteristicPointType.SurfaceLevelOutside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location) { SlopeOfNewShoulder = 2 }; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + double xToePolder = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X; + double xSurfaceLevelInside = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside).X; + var actualExtraPoints = adaptedSurfaceLine.GetPointSegmentIncluding(xToePolder, xSurfaceLevelInside); + const int expectedNumberOfPoints = 9; + Assert.AreEqual(expectedNumberOfPoints, adaptedSurfaceLine.Geometry.Points.Count); + const int expectedNumberOfExtraPoints = 3; + Assert.AreEqual(expectedNumberOfExtraPoints, actualExtraPoints.Count()); + var actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside); + var actualXValue = pointAtSurfaceLevelInside.X; + Assert.AreEqual(actualXValue, actualPoint.X, pointCoordinateTolerance); + Assert.AreEqual(pointAtSurfaceLevelInside.Z, actualPoint.Z, pointCoordinateTolerance); + Assert.IsTrue(adaptedSurfaceLine.Geometry.Points.Any(p => p.LocationEquals(extraPoint2))); + Assert.IsFalse(adaptedSurfaceLine.Geometry.Points.Any(p => p.LocationEquals(extraPoint1))); + } + + private SurfaceLine2 CreateSurfaceLineWithSkewedSurfaceLevelInside() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = { GeometryMustContainPoint = true }, + Geometry = new GeometryPointString() + }; + var pointSurfaceLevelOutside = new GeometryPoint { X = -1, Z = -1 }; + var pointDikeToeAtRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointDikeTopAtRiver = new GeometryPoint { X = 4, Z = 4 }; + var pointDikeTopAtPolder = new GeometryPoint { X = 6, Z = 4 }; + var pointDikeToeAtPolder = new GeometryPoint { X = 10, Z = 0 }; + var pointSurfaceLevelInside = new GeometryPoint { X = 18, Z = -1 }; + + surfaceLine.EnsurePointOfType(pointSurfaceLevelOutside.X, pointSurfaceLevelOutside.Z, CharacteristicPointType.SurfaceLevelOutside); + surfaceLine.EnsurePointOfType(pointDikeToeAtRiver.X, pointDikeToeAtRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointDikeTopAtRiver.X, pointDikeTopAtRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointDikeTopAtPolder.X, pointDikeTopAtPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointDikeToeAtPolder.X, pointDikeToeAtPolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(pointSurfaceLevelInside.X, pointSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + surfaceLine.SortPoints(); + return surfaceLine; + } + + private void EvaluateAdaptedSurfaceLineWithSkewedSurfaceLevelInside(SurfaceLine2 surfaceLine, SurfaceLine2 adaptedSurfaceLine, double shoulderHeight, double shoulderWidth) + { + const double cTolerance = 0.0000001; + Assert.IsNotNull(adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside)); + Assert.IsNotNull(adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside)); + Assert.AreEqual(surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z + shoulderHeight, adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside).Z, cTolerance); + double intersectionInsideSlopeWithDikeBaseXCoordinate = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X + (surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z - surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z); + Assert.AreEqual(intersectionInsideSlopeWithDikeBaseXCoordinate - shoulderHeight, adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside).X, cTolerance); + Assert.AreEqual(surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z + shoulderHeight, adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside).Z, cTolerance); + Assert.AreEqual(intersectionInsideSlopeWithDikeBaseXCoordinate - shoulderHeight + shoulderWidth, adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside).X, cTolerance); + double rightShift = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X - surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X; + Assert.AreEqual(surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside).X, adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside).X, cTolerance); + Assert.AreEqual(surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside).Z, adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside).Z, cTolerance); + } + + [Test] + public void AdaptedSurfaceLineWithoutShoulderWithSkewedSurfaceLevelInsideHasCorrectPointsInside() + { + var surfaceLine = CreateSurfaceLineWithSkewedSurfaceLevelInside(); + var location = new Location(); + const int shoulderWidth = 2; + const int shoulderHeight = 1; + Assert.IsNull(surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside)); + Assert.IsNull(surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside)); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + EvaluateAdaptedSurfaceLineWithSkewedSurfaceLevelInside(surfaceLine, adaptedSurfaceLine, shoulderHeight, shoulderWidth); + } + + [Test] + public void AdaptedSurfaceLineWithoutShoulderWithSkewedSurfaceLevelInsideAndInbetweenPointInSlopeHasCorrectPointsInside() + { + var surfaceLine = CreateSurfaceLineWithSkewedSurfaceLevelInside(); + var location = new Location(); + const int shoulderWidth = 2; + const int shoulderHeight = 1; + surfaceLine.EnsurePoint(8, 1.9); + surfaceLine.SortPoints(); + Assert.IsNull(surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside)); + Assert.IsNull(surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside)); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + Assert.AreEqual(7, surfaceLine.Geometry.Points.Count); + Assert.AreEqual(8, adaptedSurfaceLine.Geometry.Points.Count); + EvaluateAdaptedSurfaceLineWithSkewedSurfaceLevelInside(surfaceLine, adaptedSurfaceLine, shoulderHeight, shoulderWidth); + } + + private SurfaceLine2 CreateSurfaceLineWithShoulderAndSkewedSurfaceLevelInside() + { + var surfaceLine = CreateSurfaceLineWithSkewedSurfaceLevelInside(); + var pointShoulderBaseInside = new GeometryPoint { X = 9, Z = 1 }; + var pointShoulderTopInside = new GeometryPoint { X = 11, Z = 0.9 }; + var pointDikeToeAtPolder = new GeometryPoint { X = 13, Z = 0 }; + + surfaceLine.EnsurePointOfType(pointShoulderBaseInside.X, pointShoulderBaseInside.Z, CharacteristicPointType.ShoulderBaseInside); + surfaceLine.EnsurePointOfType(pointShoulderTopInside.X, pointShoulderTopInside.Z, CharacteristicPointType.ShoulderTopInside); + surfaceLine.EnsurePointOfType(pointDikeToeAtPolder.X, pointDikeToeAtPolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.SortPoints(); + return surfaceLine; + } + + [Test] + public void AdaptedSurfaceLineWithShoulderWithSkewedSurfaceLevelInsideHasCorrectPointsInside() + { + var surfaceLine = CreateSurfaceLineWithShoulderAndSkewedSurfaceLevelInside(); + var location = new Location(); + const int shoulderWidth = 2; + const int shoulderHeight = 1; + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + EvaluateAdaptedSurfaceLineWithSkewedSurfaceLevelInside(surfaceLine, adaptedSurfaceLine, shoulderHeight, shoulderWidth); + } + + [Test] + public void AdaptedSurfaceLineWithShoulderWithSkewedSurfaceLevelInsideAndInbetweenPointsHasCorrectPointsInside() + { + var surfaceLine = CreateSurfaceLineWithShoulderAndSkewedSurfaceLevelInside(); + var location = new Location(); + const int shoulderWidth = 2; + const int shoulderHeight = 1; + surfaceLine.EnsurePoint(8, 1.9); + surfaceLine.EnsurePoint(10, 1); + surfaceLine.EnsurePoint(12, 0.5); + surfaceLine.EnsurePoint(14, -0.5); + surfaceLine.SortPoints(); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location) { SlopeOfNewShoulder = 2 }; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + Assert.AreEqual(12, surfaceLine.Geometry.Points.Count); + Assert.AreEqual(9, adaptedSurfaceLine.Geometry.Points.Count); + EvaluateAdaptedSurfaceLineWithSkewedSurfaceLevelInside(surfaceLine, adaptedSurfaceLine, shoulderHeight, shoulderWidth); + } + + [Test] + public void AdaptedSurfaceLineWithTrafficLoadPointsShouldAdjustThosePoints() + { + var surfaceLine = CreateSurfaceLineWithShoulderAndSkewedSurfaceLevelInside(); + var location = new Location(); + const double cTolerance = 0.0000001; + var pointTrafficLoadOutside = new GeometryPoint { X = 9.5, Z = 0.975 }; + var pointTrafficLoadInside = new GeometryPoint { X = 10.5, Z = 0.925 }; + surfaceLine.EnsurePointOfType(pointTrafficLoadOutside.X, pointTrafficLoadOutside.Z, CharacteristicPointType.TrafficLoadOutside); + surfaceLine.EnsurePointOfType(pointTrafficLoadInside.X, pointTrafficLoadInside.Z, CharacteristicPointType.TrafficLoadInside); + const int shoulderWidth = 2; + const int shoulderHeight = 1; + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + var expectedPointTrafficLoadOutside = new GeometryPoint { X = 9.5, Z = 1.0 }; + var expectedPointTrafficLoadInside = new GeometryPoint { X = 10.5, Z = 1.0 }; + Assert.AreEqual(expectedPointTrafficLoadOutside.X, adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.TrafficLoadOutside).X, cTolerance); + Assert.AreEqual(expectedPointTrafficLoadInside.X, adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.TrafficLoadInside).X, cTolerance); + Assert.AreEqual(expectedPointTrafficLoadOutside.Z, adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.TrafficLoadOutside).Z, cTolerance); + Assert.AreEqual(expectedPointTrafficLoadInside.Z, adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.TrafficLoadInside).Z, cTolerance); + } + + [Test] + public void AdaptedSurfaceLineWithoutShoulderHasCorrectIntersectionPointAtDikeAndDitch() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 1; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 2, Z = 2 }; + var pointAtTopPolder = new GeometryPoint { X = 3, Z = 2 }; + var pointAtToePolder = new GeometryPoint { X = 4, Z = 0 }; + var ditchTopAtDikeSide = new GeometryPoint { X = 5, Z = 0 }; + var ditchBottomAtDikeSide = new GeometryPoint { X = 6, Z = -2 }; + var ditchBottomAtPolderSide = new GeometryPoint { X = 7, Z = -2 }; + var ditchTopAtPolderSide = new GeometryPoint { X = 8, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(ditchTopAtDikeSide.X, ditchTopAtDikeSide.Z, CharacteristicPointType.DitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtDikeSide.X, ditchBottomAtDikeSide.Z, CharacteristicPointType.BottomDitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtPolderSide.X, ditchBottomAtPolderSide.Z, CharacteristicPointType.BottomDitchPolderSide); + surfaceLine.EnsurePointOfType(ditchTopAtPolderSide.X, ditchTopAtPolderSide.Z, CharacteristicPointType.DitchPolderSide); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location) { SlopeOfNewShoulder = 2 }; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + var expectedPoint = new GeometryPoint(3.5, 1); + var actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); + Assert.IsTrue(expectedPoint.LocationEquals(actualPoint)); + var expectedShoulderTopInside = new GeometryPoint(4.5, 1); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + Assert.IsTrue(expectedShoulderTopInside.LocationEquals(actualPoint)); + var expectedDikeToePolder = new GeometryPoint(6.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); + Assert.IsTrue(expectedDikeToePolder.LocationEquals(actualPoint)); + var expectedDitchDikeSide = new GeometryPoint(11.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide); + Assert.IsTrue(expectedDitchDikeSide.LocationEquals(actualPoint)); + var expectedBottomDitchDikeSide = new GeometryPoint(12.5, -2); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchDikeSide); + Assert.IsTrue(expectedBottomDitchDikeSide.LocationEquals(actualPoint)); + var expectedBottomDitchPolderSide = new GeometryPoint(13.5, -2); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchPolderSide); + Assert.IsTrue(expectedBottomDitchPolderSide.LocationEquals(actualPoint)); + var expectedDitchPolderSide = new GeometryPoint(14.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide); + Assert.IsTrue(expectedDitchPolderSide.LocationEquals(actualPoint)); + Assert.AreEqual(9, surfaceLine.Geometry.Points.Count); + Assert.AreEqual(12, adaptedSurfaceLine.Geometry.Points.Count); + } + + [Test] + public void AdaptedSurfaceLineWithoutShoulderHasDitchBottomMadeHorizontal() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 1; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 2, Z = 2 }; + var pointAtTopPolder = new GeometryPoint { X = 3, Z = 2 }; + var pointAtToePolder = new GeometryPoint { X = 4, Z = 0 }; + var ditchTopAtDikeSide = new GeometryPoint { X = 5, Z = 0 }; + var ditchBottomAtDikeSide = new GeometryPoint { X = 6, Z = -2 }; + var ditchBottomAtPolderSide = new GeometryPoint { X = 7, Z = -3 }; + var ditchTopAtPolderSide = new GeometryPoint { X = 8, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(ditchTopAtDikeSide.X, ditchTopAtDikeSide.Z, CharacteristicPointType.DitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtDikeSide.X, ditchBottomAtDikeSide.Z, CharacteristicPointType.BottomDitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtPolderSide.X, ditchBottomAtPolderSide.Z, CharacteristicPointType.BottomDitchPolderSide); + surfaceLine.EnsurePointOfType(ditchTopAtPolderSide.X, ditchTopAtPolderSide.Z, CharacteristicPointType.DitchPolderSide); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location) { SlopeOfNewShoulder = 2 }; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + var expectedPoint = new GeometryPoint(3.5, 1); + var actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); + Assert.IsTrue(expectedPoint.LocationEquals(actualPoint)); + var expectedShoulderTopInside = new GeometryPoint(4.5, 1); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + Assert.IsTrue(expectedShoulderTopInside.LocationEquals(actualPoint)); + var expectedDikeToePolder = new GeometryPoint(6.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); + Assert.IsTrue(expectedDikeToePolder.LocationEquals(actualPoint)); + var expectedDitchDikeSide = new GeometryPoint(11.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide); + Assert.IsTrue(expectedDitchDikeSide.LocationEquals(actualPoint)); + var expectedBottomDitchDikeSide = new GeometryPoint(12.5, -2); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchDikeSide); + Assert.IsTrue(expectedBottomDitchDikeSide.LocationEquals(actualPoint)); + var expectedBottomDitchPolderSide = new GeometryPoint(13.5, -2); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchPolderSide); + Assert.IsTrue(expectedBottomDitchPolderSide.LocationEquals(actualPoint)); + var expectedDitchPolderSide = new GeometryPoint(14.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide); + Assert.IsTrue(expectedDitchPolderSide.LocationEquals(actualPoint)); + Assert.AreEqual(9, surfaceLine.Geometry.Points.Count); + Assert.AreEqual(12, adaptedSurfaceLine.Geometry.Points.Count); + } + + [Test] + public void AdaptedSurfaceLineWithoutShoulderHasNoInBetweenPointAfterAdaption() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 1; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 2, Z = 2 }; + var pointAtTopPolder = new GeometryPoint { X = 3, Z = 2 }; + var pointAtToePolder = new GeometryPoint { X = 4, Z = 0 }; + var ditchTopAtDikeSide = new GeometryPoint { X = 5, Z = 0 }; + var ditchBottomAtDikeSide = new GeometryPoint { X = 6, Z = -2 }; + var ditchBottomAtPolderSide = new GeometryPoint { X = 7, Z = -2 }; + var ditchTopAtPolderSide = new GeometryPoint { X = 12, Z = 0 }; + var inBetweenPointAtSurfaceLevelInside = new GeometryPoint { X = 10, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = -90 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(ditchTopAtDikeSide.X, ditchTopAtDikeSide.Z, CharacteristicPointType.DitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtDikeSide.X, ditchBottomAtDikeSide.Z, CharacteristicPointType.BottomDitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtPolderSide.X, ditchBottomAtPolderSide.Z, CharacteristicPointType.BottomDitchPolderSide); + surfaceLine.EnsurePointOfType(ditchTopAtPolderSide.X, ditchTopAtPolderSide.Z, CharacteristicPointType.DitchPolderSide); + surfaceLine.EnsurePoint(inBetweenPointAtSurfaceLevelInside.X, inBetweenPointAtSurfaceLevelInside.Z); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location) { SlopeOfNewShoulder = 2 }; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + var expectedPoint = new GeometryPoint(3.5, 1); + var actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); + Assert.IsTrue(expectedPoint.LocationEquals(actualPoint)); + var expectedShoulderTopInside = new GeometryPoint(4.5, 1); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + Assert.IsTrue(expectedShoulderTopInside.LocationEquals(actualPoint)); + var expectedDikeToePolder = new GeometryPoint(6.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); + Assert.IsTrue(expectedDikeToePolder.LocationEquals(actualPoint)); + Assert.AreEqual(10, surfaceLine.Geometry.Points.Count); + Assert.AreEqual(11, adaptedSurfaceLine.Geometry.Points.Count); + } + + [Test] + public void AdaptedSurfaceLineWithoutShoulderHasCorrectIntersectionPointAtDikeAndDitchWithPointsAtNewDitchLocation() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 1; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 2, Z = 2 }; + var pointAtTopPolder = new GeometryPoint { X = 3, Z = 2 }; + var pointAtToePolder = new GeometryPoint { X = 4, Z = 0 }; + var ditchTopAtDikeSide = new GeometryPoint { X = 5, Z = 0 }; + var ditchBottomAtDikeSide = new GeometryPoint { X = 6, Z = -2 }; + var ditchBottomAtPolderSide = new GeometryPoint { X = 7, Z = -2 }; + var ditchTopAtPolderSide = new GeometryPoint { X = 12, Z = 0 }; + var apoint = new GeometryPoint { X = 12.5, Z = 0 }; + var apoint2 = new GeometryPoint { X = 13, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(ditchTopAtDikeSide.X, ditchTopAtDikeSide.Z, CharacteristicPointType.DitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtDikeSide.X, ditchBottomAtDikeSide.Z, CharacteristicPointType.BottomDitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtPolderSide.X, ditchBottomAtPolderSide.Z, CharacteristicPointType.BottomDitchPolderSide); + surfaceLine.EnsurePointOfType(ditchTopAtPolderSide.X, ditchTopAtPolderSide.Z, CharacteristicPointType.DitchPolderSide); + surfaceLine.EnsurePointOfType(apoint.X, apoint.Z, null); + surfaceLine.EnsurePointOfType(apoint2.X, apoint2.Z, null); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location) { SlopeOfNewShoulder = 2 }; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + var expectedPoint = new GeometryPoint(3.5, 1); + var actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); + Assert.IsTrue(expectedPoint.LocationEquals(actualPoint)); + var expectedShoulderTopInside = new GeometryPoint(4.5, 1); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + Assert.IsTrue(expectedShoulderTopInside.LocationEquals(actualPoint)); + var expectedDikeToePolder = new GeometryPoint(6.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); + Assert.IsTrue(expectedDikeToePolder.LocationEquals(actualPoint)); + var expectedDitchDikeSide = new GeometryPoint(11.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide); + Assert.IsTrue(expectedDitchDikeSide.LocationEquals(actualPoint)); + var expectedBottomDitchDikeSide = new GeometryPoint(12.5, -2); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchDikeSide); + Assert.IsTrue(expectedBottomDitchDikeSide.LocationEquals(actualPoint)); + var expectedBottomDitchPolderSide = new GeometryPoint(13.5, -2); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchPolderSide); + Assert.IsTrue(expectedBottomDitchPolderSide.LocationEquals(actualPoint)); + var expectedDitchPolderSide = new GeometryPoint(18.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide); + Assert.IsTrue(expectedDitchPolderSide.LocationEquals(actualPoint)); + Assert.AreEqual(11, surfaceLine.Geometry.Points.Count); + Assert.AreEqual(11, adaptedSurfaceLine.Geometry.Points.Count); + } + + [Test] + public void AdaptedSurfaceLineWithoutShoulderHasCorrectIntersectionPointAtDikeAndDitchWithPointsAtAndBeyondNewDitchLocation() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 1; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 2, Z = 2 }; + var pointAtTopPolder = new GeometryPoint { X = 3, Z = 2 }; + var pointAtToePolder = new GeometryPoint { X = 4, Z = 0 }; + var ditchTopAtDikeSide = new GeometryPoint { X = 5, Z = 0 }; + var ditchBottomAtDikeSide = new GeometryPoint { X = 6, Z = -2 }; + var ditchBottomAtPolderSide = new GeometryPoint { X = 7, Z = -2 }; + var ditchTopAtPolderSide = new GeometryPoint { X = 8, Z = 0 }; + var apoint = new GeometryPoint { X = 12, Z = 0 }; + var apoint2 = new GeometryPoint { X = 13, Z = 0 }; + var apoint3 = new GeometryPoint { X = 20, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(ditchTopAtDikeSide.X, ditchTopAtDikeSide.Z, CharacteristicPointType.DitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtDikeSide.X, ditchBottomAtDikeSide.Z, CharacteristicPointType.BottomDitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtPolderSide.X, ditchBottomAtPolderSide.Z, CharacteristicPointType.BottomDitchPolderSide); + surfaceLine.EnsurePointOfType(ditchTopAtPolderSide.X, ditchTopAtPolderSide.Z, CharacteristicPointType.DitchPolderSide); + surfaceLine.EnsurePointOfType(apoint.X, apoint.Z, null); + surfaceLine.EnsurePointOfType(apoint2.X, apoint2.Z, null); + surfaceLine.EnsurePointOfType(apoint3.X, apoint3.Z, null); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + Assert.AreEqual(12, surfaceLine.Geometry.Points.Count); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location) { SlopeOfNewShoulder = 2 }; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + var expectedPoint = new GeometryPoint(3.5, 1); + var actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); + Assert.IsTrue(expectedPoint.LocationEquals(actualPoint)); + var expectedShoulderTopInside = new GeometryPoint(4.5, 1); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + Assert.IsTrue(expectedShoulderTopInside.LocationEquals(actualPoint)); + var expectedDikeToePolder = new GeometryPoint(6.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); + Assert.IsTrue(expectedDikeToePolder.LocationEquals(actualPoint)); + var expectedDitchDikeSide = new GeometryPoint(11.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide); + Assert.IsTrue(expectedDitchDikeSide.LocationEquals(actualPoint)); + var expectedBottomDitchDikeSide = new GeometryPoint(12.5, -2); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchDikeSide); + Assert.IsTrue(expectedBottomDitchDikeSide.LocationEquals(actualPoint)); + var expectedBottomDitchPolderSide = new GeometryPoint(13.5, -2); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchPolderSide); + Assert.IsTrue(expectedBottomDitchPolderSide.LocationEquals(actualPoint)); + var expectedDitchPolderSide = new GeometryPoint(14.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide); + Assert.IsTrue(expectedDitchPolderSide.LocationEquals(actualPoint)); + var expectedExtraPointBeyondDitchUnchanged = new GeometryPoint(20, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints[adaptedSurfaceLine.CharacteristicPoints.Count - 2]; + Assert.IsTrue(expectedExtraPointBeyondDitchUnchanged.LocationEquals(actualPoint)); + Assert.AreEqual(12, surfaceLine.Geometry.Count); + Assert.AreEqual(13, adaptedSurfaceLine.Geometry.Count); + } + + /// + /// Test whether adapted the surface line without shoulder has correct intersection point at dike and ditch with points at and beyond new ditch location2. + /// + [Test] + public void AdaptedSurfaceLineWithoutShoulderHasCorrectIntersectionPointAtDikeAndDitchWithPointsAtAndBeyondNewDitchLocation2() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 1; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 2, Z = 2 }; + var pointAtTopPolder = new GeometryPoint { X = 3, Z = 2 }; + var pointAtToePolder = new GeometryPoint { X = 4, Z = 0 }; + var ditchTopAtDikeSide = new GeometryPoint { X = 5, Z = 0 }; + var ditchBottomAtDikeSide = new GeometryPoint { X = 6, Z = -2 }; + var ditchBottomAtPolderSide = new GeometryPoint { X = 7, Z = -2 }; + var ditchTopAtPolderSide = new GeometryPoint { X = 8, Z = 0 }; + var apoint = new GeometryPoint { X = 12, Z = 0 }; + var apoint2 = new GeometryPoint { X = 19, Z = 0 }; + var apoint3 = new GeometryPoint { X = 20, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(ditchTopAtDikeSide.X, ditchTopAtDikeSide.Z, CharacteristicPointType.DitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtDikeSide.X, ditchBottomAtDikeSide.Z, CharacteristicPointType.BottomDitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtPolderSide.X, ditchBottomAtPolderSide.Z, CharacteristicPointType.BottomDitchPolderSide); + surfaceLine.EnsurePointOfType(ditchTopAtPolderSide.X, ditchTopAtPolderSide.Z, CharacteristicPointType.DitchPolderSide); + surfaceLine.EnsurePointOfType(apoint.X, apoint.Z, null); + surfaceLine.EnsurePointOfType(apoint2.X, apoint2.Z, null); + surfaceLine.EnsurePointOfType(apoint3.X, apoint3.Z, null); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + Assert.AreEqual(12, surfaceLine.Geometry.Count); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location) { SlopeOfNewShoulder = 2 }; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + var expectedPoint = new GeometryPoint(3.5, 1); + var actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); + Assert.IsTrue(expectedPoint.LocationEquals(actualPoint)); + var expectedShoulderTopInside = new GeometryPoint(4.5, 1); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + Assert.IsTrue(expectedShoulderTopInside.LocationEquals(actualPoint)); + var expectedDikeToePolder = new GeometryPoint(6.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); + Assert.IsTrue(expectedDikeToePolder.LocationEquals(actualPoint)); + var expectedDitchDikeSide = new GeometryPoint(11.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide); + Assert.IsTrue(expectedDitchDikeSide.LocationEquals(actualPoint)); + var expectedBottomDitchDikeSide = new GeometryPoint(12.5, -2); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchDikeSide); + Assert.IsTrue(expectedBottomDitchDikeSide.LocationEquals(actualPoint)); + var expectedBottomDitchPolderSide = new GeometryPoint(13.5, -2); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchPolderSide); + Assert.IsTrue(expectedBottomDitchPolderSide.LocationEquals(actualPoint)); + var expectedDitchPolderSide = new GeometryPoint(14.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide); + Assert.IsTrue(expectedDitchPolderSide.LocationEquals(actualPoint)); + var expectedExtraPointBeyondDitchUnchanged1 = new GeometryPoint(19, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints[adaptedSurfaceLine.CharacteristicPoints.Count - 3]; + Assert.IsTrue(expectedExtraPointBeyondDitchUnchanged1.LocationEquals(actualPoint)); + var expectedExtraPointBeyondDitchUnchanged2 = new GeometryPoint(20, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints[adaptedSurfaceLine.CharacteristicPoints.Count - 2]; + Assert.IsTrue(expectedExtraPointBeyondDitchUnchanged2.LocationEquals(actualPoint)); + Assert.AreEqual(12, surfaceLine.Geometry.Count); + Assert.AreEqual(14, adaptedSurfaceLine.Geometry.Count); + } + + [Test] + [ExpectedException(typeof(SurfaceLineAdapterException))] + public void ThrowsAnExceptionWhenNewShoulderDoesNotFit() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 100; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 2, Z = 2 }; + var pointAtTopPolder = new GeometryPoint { X = 3, Z = 2 }; + var pointAtToePolder = new GeometryPoint { X = 4, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + var line = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + } + + [Test] + [ExpectedException(typeof(SurfaceLineAdapterException))] + public void ThrowsAnExceptionWhenNewShoulderDoesJustNotFit() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const double shoulderWidth = 94.51; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 2, Z = 2 }; + var pointAtTopPolder = new GeometryPoint { X = 3, Z = 2 }; + var pointAtToePolder = new GeometryPoint { X = 4, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, + CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + var line = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + } + + [Test] + [ExpectedException(typeof(SurfaceLineAdapterException))] + public void ThrowsAnExceptionWhenNewShoulderDoesJustNotFitWithDitch() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const double shoulderWidth = 90.51; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 2, Z = 2 }; + var pointAtTopPolder = new GeometryPoint { X = 3, Z = 2 }; + var pointAtToePolder = new GeometryPoint { X = 4, Z = 0 }; + var ditchTopAtDikeSide = new GeometryPoint { X = 5, Z = 0 }; + var ditchBottomAtDikeSide = new GeometryPoint { X = 6, Z = -2 }; + var ditchBottomAtPolderSide = new GeometryPoint { X = 7, Z = -2 }; + var ditchTopAtPolderSide = new GeometryPoint { X = 8, Z = 0 }; + var apoint = new GeometryPoint { X = 9, Z = 0 }; + var apoint2 = new GeometryPoint { X = 19, Z = 0 }; + var apoint3 = new GeometryPoint { X = 20, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(ditchTopAtDikeSide.X, ditchTopAtDikeSide.Z, CharacteristicPointType.DitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtDikeSide.X, ditchBottomAtDikeSide.Z, CharacteristicPointType.BottomDitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtPolderSide.X, ditchBottomAtPolderSide.Z, CharacteristicPointType.BottomDitchPolderSide); + surfaceLine.EnsurePointOfType(ditchTopAtPolderSide.X, ditchTopAtPolderSide.Z, CharacteristicPointType.DitchPolderSide); + surfaceLine.EnsurePointOfType(apoint.X, apoint.Z, null); + surfaceLine.EnsurePointOfType(apoint2.X, apoint2.Z, null); + surfaceLine.EnsurePointOfType(apoint3.X, apoint3.Z, null); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + var line = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + } + + [Test] + public void AdaptedSurfaceLineWithoutShoulderHasCorrectPointAtTopShoulderInsideWithLimitedMaxHeight05() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + location.UseNewMaxHeightShoulderAsFraction = true; + location.NewMaxHeightShoulderAsFraction = 0.5; + const int shoulderWidth = 1; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 1, Z = 1 }; + var pointAtTopPolder = new GeometryPoint { X = 2, Z = 1 }; + var pointAtToePolder = new GeometryPoint { X = 3, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + surfaceLineAdapter.MaxShoulderLevel = location.NewMaxHeightShoulderAsFraction * + (surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z - surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z) + + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + double expectedShoulderHeight = Math.Min(shoulderHeight, surfaceLineAdapter.MaxShoulderLevel + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z); + var expectedPoint = new GeometryPoint(3.5, expectedShoulderHeight); + var actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + Assert.IsTrue(expectedPoint.LocationEquals(actualPoint)); + } + + [Test] + public void AdaptedSurfaceLineWithoutShoulderHasCorrectPointAtTopShoulderInsideWithLimitedMaxHeight1() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + location.UseNewMaxHeightShoulderAsFraction = true; + location.NewMaxHeightShoulderAsFraction = 1; + const int shoulderWidth = 1; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 1, Z = 1 }; + var pointAtTopPolder = new GeometryPoint { X = 2, Z = 1 }; + var pointAtToePolder = new GeometryPoint { X = 3, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + double expectedShoulderHeight = Math.Min(shoulderHeight, (surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z - surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z)); + var expectedPoint = new GeometryPoint(3, expectedShoulderHeight); + var actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + Assert.IsTrue(expectedPoint.LocationEquals(actualPoint)); + } + + [Test] + public void AdaptedSurfaceLineWithoutShoulderHasCorrectPointAtTopShoulderInsideWithResetLimitedMaxHeight() + { + const double maxFractionOfDikeHeightForShoulderHeight = 0.5; + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + location.UseNewMaxHeightShoulderAsFraction = true; + location.NewMaxHeightShoulderAsFraction = 1; + const int shoulderWidth = 1; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 1, Z = 1 }; + var pointAtTopPolder = new GeometryPoint { X = 2, Z = 1 }; + var pointAtToePolder = new GeometryPoint { X = 3, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + surfaceLineAdapter.MaxShoulderLevel = maxFractionOfDikeHeightForShoulderHeight * (surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z - + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z) + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + double expectedShoulderHeight = Math.Min(shoulderHeight, surfaceLineAdapter.MaxShoulderLevel + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z); + var expectedPoint = new GeometryPoint(3.5, expectedShoulderHeight); + var actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + Assert.IsTrue(expectedPoint.LocationEquals(actualPoint)); + } + + [Test] + public void AdaptedSurfaceLineWithNewTopSlopeAngle() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + location.UseNewShoulderTopSlope = true; + location.NewShoulderTopSlope = 0.05; + const double shoulderWidth = 4.5; + const double shoulderHeight = 0.5; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 1, Z = 1 }; + var pointAtTopPolder = new GeometryPoint { X = 2, Z = 1 }; + var pointAtToePolder = new GeometryPoint { X = 3, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + surfaceLineAdapter.MaxShoulderLevel = 0.8 * (surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z - + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z) + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + var expectedBasePoint = new GeometryPoint(2.263, 0.737); + var actualBasePoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); + Assert.IsTrue(expectedBasePoint.LocationEquals(actualBasePoint)); + var expectedTopPoint = new GeometryPoint(7, 0.5); + var actualTopPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + Assert.IsTrue(expectedTopPoint.LocationEquals(actualTopPoint)); + var expectedToePoint = new GeometryPoint(8.5, 0.0); + var actualToePoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); + Assert.IsTrue(expectedToePoint.LocationEquals(actualToePoint)); + } + + [Test] + [ExpectedException(typeof(SurfaceLineAdapterException))] + public void AdaptedSurfaceLineWithNewVerySteepTopSlopeAngle() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + location.UseNewShoulderTopSlope = true; + location.NewShoulderTopSlope = 0.5; + const double shoulderWidth = 4.5; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 1, Z = 1 }; + var pointAtTopPolder = new GeometryPoint { X = 2, Z = 1 }; + var pointAtToePolder = new GeometryPoint { X = 3, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + surfaceLineAdapter.MaxShoulderLevel = 0.5 * (surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z - + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z) + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + // TODO (The) what to do with the outcommented code? + // Dike top polder now coincides with the shoulder base. + // var expectedBasePoint = GeometryPoint.CreateNewXZPoint(2, 1); + // var actualBasePoint = adaptedSurfaceLine[CharacteristicPointType.ShoulderBaseInside]; + // Assert.IsTrue(expectedBasePoint.LocationEquals(actualBasePoint)); + // var actualDikeTopPoint = adaptedSurfaceLine[CharacteristicPointType.DikeTopAtPolder]; + // Assert.IsTrue(expectedBasePoint.LocationEquals(actualDikeTopPoint)); + // var expectedTopPoint = GeometryPoint.CreateNewXZPoint(7, 0.5); + // var actualTopPoint = adaptedSurfaceLine[CharacteristicPointType.ShoulderTopInside]; + // Assert.IsTrue(expectedTopPoint.LocationEquals(actualTopPoint)); + // var expectedToePoint = GeometryPoint.CreateNewXZPoint(8.5, 0.0); + // var actualToePoint = adaptedSurfaceLine[CharacteristicPointType.DikeToeAtPolder]; + // Assert.IsTrue(expectedToePoint.LocationEquals(actualToePoint)); + } + + [Test] + public void AdaptedSurfaceLineWithNewBaseSlopeAngle() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + location.UseNewShoulderBaseSlope = true; + location.NewShoulderBaseSlope = 1; + const double shoulderWidth = 4.5; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 1, Z = 1 }; + var pointAtTopPolder = new GeometryPoint { X = 2, Z = 1 }; + var pointAtToePolder = new GeometryPoint { X = 3, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + surfaceLineAdapter.MaxShoulderLevel = 0.5 * (surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z - + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z) + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + var expectedBasePoint = new GeometryPoint(2.5, 0.5); + var actualBasePoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); + Assert.IsTrue(expectedBasePoint.LocationEquals(actualBasePoint)); + var expectedTopPoint = new GeometryPoint(7, 0.5); + var actualTopPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + Assert.IsTrue(expectedTopPoint.LocationEquals(actualTopPoint)); + var expectedToePoint = new GeometryPoint(7.5, 0.0); + var actualToePoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); + Assert.IsTrue(expectedToePoint.LocationEquals(actualToePoint)); + } + + [Test] + public void AdaptedSurfaceLineWithNewBaseSlopeAngleButWithReset() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + location.UseNewShoulderBaseSlope = true; + location.NewShoulderBaseSlope = 1; + const double shoulderWidth = 4.5; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 1, Z = 1 }; + var pointAtTopPolder = new GeometryPoint { X = 2, Z = 1 }; + var pointAtToePolder = new GeometryPoint { X = 3, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + surfaceLineAdapter.MaxShoulderLevel = 0.5 * (surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z - + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z) + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; + surfaceLineAdapter.SlopeOfNewShoulder = 2; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + var expectedBasePoint = new GeometryPoint(2.5, 0.5); + var actualBasePoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); + Assert.IsTrue(expectedBasePoint.LocationEquals(actualBasePoint)); + var expectedTopPoint = new GeometryPoint(7, 0.5); + var actualTopPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + Assert.IsTrue(expectedTopPoint.LocationEquals(actualTopPoint)); + var expectedToePoint = new GeometryPoint(8, 0.0); + var actualToePoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); + Assert.IsTrue(expectedToePoint.LocationEquals(actualToePoint)); + } + + [Test] + [ExpectedException(typeof(SurfaceLineAdapterException))] + public void AdaptedSurfaceLineWithNewBaseSlopeAngleFarTooShallow() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + location.UseNewShoulderBaseSlope = true; + location.NewShoulderBaseSlope = 0.001; + const double shoulderWidth = 4.5; + const int shoulderHeight = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 1, Z = 1 }; + var pointAtTopPolder = new GeometryPoint { X = 2, Z = 1 }; + var pointAtToePolder = new GeometryPoint { X = 3, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location); + surfaceLineAdapter.MaxShoulderLevel = 0.5 * (surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z - + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z) + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + } + + [Test] + public void AdaptedSurfaceLineWithNewMinDistanceFromToe() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 1; + const int shoulderHeight = 1; + location.UseNewMinDistanceDikeToeStartDitch = true; + location.NewMinDistanceDikeToeStartDitch = 1; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 2, Z = 2 }; + var pointAtTopPolder = new GeometryPoint { X = 3, Z = 2 }; + var pointAtToePolder = new GeometryPoint { X = 4, Z = 0 }; + var ditchTopAtDikeSide = new GeometryPoint { X = 5, Z = 0 }; + var ditchBottomAtDikeSide = new GeometryPoint { X = 6, Z = -2 }; + var ditchBottomAtPolderSide = new GeometryPoint { X = 7, Z = -2 }; + var ditchTopAtPolderSide = new GeometryPoint { X = 8, Z = 0 }; + var apoint = new GeometryPoint { X = 9, Z = 0 }; + var apoint2 = new GeometryPoint { X = 10, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(ditchTopAtDikeSide.X, ditchTopAtDikeSide.Z, CharacteristicPointType.DitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtDikeSide.X, ditchBottomAtDikeSide.Z, CharacteristicPointType.BottomDitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtPolderSide.X, ditchBottomAtPolderSide.Z, CharacteristicPointType.BottomDitchPolderSide); + surfaceLine.EnsurePointOfType(ditchTopAtPolderSide.X, ditchTopAtPolderSide.Z, CharacteristicPointType.DitchPolderSide); + surfaceLine.EnsurePointOfType(apoint.X, apoint.Z, null); + surfaceLine.EnsurePointOfType(apoint2.X, apoint2.Z, null); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location) { SlopeOfNewShoulder = 2 }; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + var expectedPoint = new GeometryPoint(3.5, 1); + var actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); + Assert.IsTrue(expectedPoint.LocationEquals(actualPoint)); + var expectedShoulderTopInside = new GeometryPoint(4.5, 1); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + Assert.IsTrue(expectedShoulderTopInside.LocationEquals(actualPoint)); + var expectedDikeToePolder = new GeometryPoint(6.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); + Assert.IsTrue(expectedDikeToePolder.LocationEquals(actualPoint)); + var expectedDitchDikeSide = new GeometryPoint(7.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide); + Assert.IsTrue(expectedDitchDikeSide.LocationEquals(actualPoint)); + var expectedBottomDitchDikeSide = new GeometryPoint(8.5, -2); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchDikeSide); + Assert.IsTrue(expectedBottomDitchDikeSide.LocationEquals(actualPoint)); + var expectedBottomDitchPolderSide = new GeometryPoint(9.5, -2); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchPolderSide); + Assert.IsTrue(expectedBottomDitchPolderSide.LocationEquals(actualPoint)); + var expectedDitchPolderSide = new GeometryPoint(10.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide); + Assert.IsTrue(expectedDitchPolderSide.LocationEquals(actualPoint)); + Assert.AreEqual(11, surfaceLine.Geometry.Count); + Assert.AreEqual(11, adaptedSurfaceLine.Geometry.Count); + } + + [Test] + public void AdaptedSurfaceLineWithLargeNewMinDistanceFromToe() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 1; + const int shoulderHeight = 1; + location.UseNewMinDistanceDikeToeStartDitch = true; + location.NewMinDistanceDikeToeStartDitch = 31; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 2, Z = 2 }; + var pointAtTopPolder = new GeometryPoint { X = 3, Z = 2 }; + var pointAtToePolder = new GeometryPoint { X = 4, Z = 0 }; + var ditchTopAtDikeSide = new GeometryPoint { X = 5, Z = 0 }; + var ditchBottomAtDikeSide = new GeometryPoint { X = 6, Z = -2 }; + var ditchBottomAtPolderSide = new GeometryPoint { X = 7, Z = -2 }; + var ditchTopAtPolderSide = new GeometryPoint { X = 8, Z = 0 }; + var apoint = new GeometryPoint { X = 9, Z = 0 }; + var apoint2 = new GeometryPoint { X = 10, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(ditchTopAtDikeSide.X, ditchTopAtDikeSide.Z, CharacteristicPointType.DitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtDikeSide.X, ditchBottomAtDikeSide.Z, CharacteristicPointType.BottomDitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtPolderSide.X, ditchBottomAtPolderSide.Z, CharacteristicPointType.BottomDitchPolderSide); + surfaceLine.EnsurePointOfType(ditchTopAtPolderSide.X, ditchTopAtPolderSide.Z, CharacteristicPointType.DitchPolderSide); + surfaceLine.EnsurePointOfType(apoint.X, apoint.Z, null); + surfaceLine.EnsurePointOfType(apoint2.X, apoint2.Z, null); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location) { SlopeOfNewShoulder = 2 }; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + var expectedPoint = new GeometryPoint(3.5, 1); + var actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); + Assert.IsTrue(expectedPoint.LocationEquals(actualPoint)); + var expectedShoulderTopInside = new GeometryPoint(4.5, 1); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + Assert.IsTrue(expectedShoulderTopInside.LocationEquals(actualPoint)); + var expectedDikeToePolder = new GeometryPoint(6.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); + Assert.IsTrue(expectedDikeToePolder.LocationEquals(actualPoint)); + var expectedDitchDikeSide = new GeometryPoint(37.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide); + Assert.IsTrue(expectedDitchDikeSide.LocationEquals(actualPoint)); + var expectedBottomDitchDikeSide = new GeometryPoint(38.5, -2); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchDikeSide); + Assert.IsTrue(expectedBottomDitchDikeSide.LocationEquals(actualPoint)); + var expectedBottomDitchPolderSide = new GeometryPoint(39.5, -2); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchPolderSide); + Assert.IsTrue(expectedBottomDitchPolderSide.LocationEquals(actualPoint)); + var expectedDitchPolderSide = new GeometryPoint(40.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide); + Assert.IsTrue(expectedDitchPolderSide.LocationEquals(actualPoint)); + Assert.AreEqual(11, surfaceLine.Geometry.Count); + Assert.AreEqual(14, adaptedSurfaceLine.Geometry.Count); + } + + [Test] + [ExpectedException(typeof(SurfaceLineAdapterException))] + public void AdaptedSurfaceLineWithTooLargeNewMinDistanceFromToe() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 1; + const int shoulderHeight = 1; + location.UseNewMinDistanceDikeToeStartDitch = true; + location.NewMinDistanceDikeToeStartDitch = 131; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 2, Z = 2 }; + var pointAtTopPolder = new GeometryPoint { X = 3, Z = 2 }; + var pointAtToePolder = new GeometryPoint { X = 4, Z = 0 }; + var ditchTopAtDikeSide = new GeometryPoint { X = 5, Z = 0 }; + var ditchBottomAtDikeSide = new GeometryPoint { X = 6, Z = -2 }; + var ditchBottomAtPolderSide = new GeometryPoint { X = 7, Z = -2 }; + var ditchTopAtPolderSide = new GeometryPoint { X = 8, Z = 0 }; + var apoint = new GeometryPoint { X = 9, Z = 0 }; + var apoint2 = new GeometryPoint { X = 10, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(ditchTopAtDikeSide.X, ditchTopAtDikeSide.Z, CharacteristicPointType.DitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtDikeSide.X, ditchBottomAtDikeSide.Z, CharacteristicPointType.BottomDitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtPolderSide.X, ditchBottomAtPolderSide.Z, CharacteristicPointType.BottomDitchPolderSide); + surfaceLine.EnsurePointOfType(ditchTopAtPolderSide.X, ditchTopAtPolderSide.Z, CharacteristicPointType.DitchPolderSide); + surfaceLine.EnsurePointOfType(apoint.X, apoint.Z, null); + surfaceLine.EnsurePointOfType(apoint2.X, apoint2.Z, null); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location) { SlopeOfNewShoulder = 2 }; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + } + + [Test] + public void AdaptedSurfaceLineWithNewMinDistanceFromToeAndNewDefinition() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 1; + const int shoulderHeight = 1; + location.UseNewMinDistanceDikeToeStartDitch = true; + location.NewMinDistanceDikeToeStartDitch = 1; + location.UseNewDitchDefinition = true; + location.PolderLevel = -0.2; + location.NewSlopeAngleDitch = 1; + location.NewDepthDitch = 1.8; + location.NewWidthDitchBottom = 2; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 2, Z = 2 }; + var pointAtTopPolder = new GeometryPoint { X = 3, Z = 2 }; + var pointAtToePolder = new GeometryPoint { X = 4, Z = 0 }; + var ditchTopAtDikeSide = new GeometryPoint { X = 5, Z = 0 }; + var ditchBottomAtDikeSide = new GeometryPoint { X = 6, Z = -2 }; + var ditchBottomAtPolderSide = new GeometryPoint { X = 7, Z = -2 }; + var ditchTopAtPolderSide = new GeometryPoint { X = 8, Z = 0 }; + var apoint = new GeometryPoint { X = 9, Z = 0 }; + var apoint2 = new GeometryPoint { X = 10, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(ditchTopAtDikeSide.X, ditchTopAtDikeSide.Z, CharacteristicPointType.DitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtDikeSide.X, ditchBottomAtDikeSide.Z, CharacteristicPointType.BottomDitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtPolderSide.X, ditchBottomAtPolderSide.Z, CharacteristicPointType.BottomDitchPolderSide); + surfaceLine.EnsurePointOfType(ditchTopAtPolderSide.X, ditchTopAtPolderSide.Z, CharacteristicPointType.DitchPolderSide); + surfaceLine.EnsurePointOfType(apoint.X, apoint.Z, null); + surfaceLine.EnsurePointOfType(apoint2.X, apoint2.Z, null); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location) { SlopeOfNewShoulder = 2 }; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + var expectedPoint = new GeometryPoint(3.5, 1); + var actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); + Assert.IsTrue(expectedPoint.LocationEquals(actualPoint)); + var expectedShoulderTopInside = new GeometryPoint(4.5, 1); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + Assert.IsTrue(expectedShoulderTopInside.LocationEquals(actualPoint)); + var expectedDikeToePolder = new GeometryPoint(6.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); + Assert.IsTrue(expectedDikeToePolder.LocationEquals(actualPoint)); + var expectedDitchDikeSide = new GeometryPoint(7.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide); + Assert.IsTrue(expectedDitchDikeSide.LocationEquals(actualPoint)); + var expectedBottomDitchDikeSide = new GeometryPoint(9.5, -2); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchDikeSide); + Assert.IsTrue(expectedBottomDitchDikeSide.LocationEquals(actualPoint)); + var expectedBottomDitchPolderSide = new GeometryPoint(11.5, -2); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchPolderSide); + Assert.IsTrue(expectedBottomDitchPolderSide.LocationEquals(actualPoint)); + var expectedDitchPolderSide = new GeometryPoint(13.5, 0); + actualPoint = adaptedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide); + Assert.IsTrue(expectedDitchPolderSide.LocationEquals(actualPoint)); + Assert.AreEqual(11, surfaceLine.Geometry.Count); + Assert.AreEqual(11, adaptedSurfaceLine.Geometry.Count); + } + + [Test] + [ExpectedException(typeof(SurfaceLineAdapterException))] + public void AdaptedSurfaceLineWithNewMinDistanceFromToeAndNewDefinitionFailsBecausePolderLevelIsTooHigh() + { + var surfaceLine = new SurfaceLine2 + { + CharacteristicPoints = + { + GeometryMustContainPoint = true + }, + Geometry = new GeometryPointString() + }; + var location = new Location(); + const int shoulderWidth = 1; + const int shoulderHeight = 1; + location.UseNewMinDistanceDikeToeStartDitch = true; + location.NewMinDistanceDikeToeStartDitch = 1; + location.UseNewDitchDefinition = true; + location.PolderLevel = 20.2; + location.NewSlopeAngleDitch = 1; + location.NewDepthDitch = 1.8; + location.NewWidthDitchBottom = 2; + var pointAtToeRiver = new GeometryPoint { X = 0, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 2, Z = 2 }; + var pointAtTopPolder = new GeometryPoint { X = 3, Z = 2 }; + var pointAtToePolder = new GeometryPoint { X = 4, Z = 0 }; + var ditchTopAtDikeSide = new GeometryPoint { X = 5, Z = 0 }; + var ditchBottomAtDikeSide = new GeometryPoint { X = 6, Z = -2 }; + var ditchBottomAtPolderSide = new GeometryPoint { X = 7, Z = -2 }; + var ditchTopAtPolderSide = new GeometryPoint { X = 8, Z = 0 }; + var apoint = new GeometryPoint { X = 9, Z = 0 }; + var apoint2 = new GeometryPoint { X = 10, Z = 0 }; + var pointAtSurfaceLevelInside = new GeometryPoint { X = 100, Z = 0 }; + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToeRiver.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(ditchTopAtDikeSide.X, ditchTopAtDikeSide.Z, CharacteristicPointType.DitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtDikeSide.X, ditchBottomAtDikeSide.Z, CharacteristicPointType.BottomDitchDikeSide); + surfaceLine.EnsurePointOfType(ditchBottomAtPolderSide.X, ditchBottomAtPolderSide.Z, CharacteristicPointType.BottomDitchPolderSide); + surfaceLine.EnsurePointOfType(ditchTopAtPolderSide.X, ditchTopAtPolderSide.Z, CharacteristicPointType.DitchPolderSide); + surfaceLine.EnsurePointOfType(apoint.X, apoint.Z, null); + surfaceLine.EnsurePointOfType(apoint2.X, apoint2.Z, null); + surfaceLine.EnsurePointOfType(pointAtSurfaceLevelInside.X, pointAtSurfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location) { SlopeOfNewShoulder = 2 }; + var adaptedSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(shoulderWidth, shoulderHeight, false); + } + } +} \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/DikesDesign/SurfaceLineHeightAdapterTest.cs =================================================================== diff -u -r955 -r967 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/DikesDesign/SurfaceLineHeightAdapterTest.cs (.../SurfaceLineHeightAdapterTest.cs) (revision 955) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/DikesDesign/SurfaceLineHeightAdapterTest.cs (.../SurfaceLineHeightAdapterTest.cs) (revision 967) @@ -45,18 +45,14 @@ Geometry = new GeometryPointString() }; var location = new Location(); - { - surfaceLine.EnsurePointOfType(0, 0, CharacteristicPointType.DikeToeAtRiver); - surfaceLine.EnsurePointOfType(1, 1, CharacteristicPointType.DikeTopAtRiver); - surfaceLine.EnsurePointOfType(2, 1, CharacteristicPointType.DikeTopAtPolder); - surfaceLine.EnsurePointOfType(3, 0, CharacteristicPointType.DikeToeAtPolder); - surfaceLine.EnsurePointOfType(100, 0, CharacteristicPointType.SurfaceLevelInside); - var surfaceLineAdapter = new SurfaceLineHeightAdapter(surfaceLine, location); - var constructNewSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(1); - { - Assert.IsNotNull(constructNewSurfaceLine); - } - } + surfaceLine.EnsurePointOfType(0, 0, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(1, 1, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(2, 1, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(3, 0, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(100, 0, CharacteristicPointType.SurfaceLevelInside); + var surfaceLineAdapter = new SurfaceLineHeightAdapter(surfaceLine, location); + var constructNewSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(1); + Assert.IsNotNull(constructNewSurfaceLine); } [Test] @@ -71,26 +67,24 @@ Geometry = new GeometryPointString() }; var location = new Location(); - { - const double newDikeHeight = 6.0; - var pointAtToeRiver = new GeometryPoint { X = 17, Z = 0 }; - var pointAtTopRiver = new GeometryPoint { X = 34.5, Z = 5 }; - var pointAtTopPolder = new GeometryPoint { X = 35, Z = 5 }; - var pointAtToePolder = new GeometryPoint { X = 36, Z = 0 }; + const double newDikeHeight = 6.0; + var pointAtToeRiver = new GeometryPoint { X = 17, Z = 0 }; + var pointAtTopRiver = new GeometryPoint { X = 34.5, Z = 5 }; + var pointAtTopPolder = new GeometryPoint { X = 35, Z = 5 }; + var pointAtToePolder = new GeometryPoint { X = 36, Z = 0 }; - surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtRiver); - surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); - surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); - surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); - surfaceLine.EnsurePointOfType(100, 0, CharacteristicPointType.SurfaceLevelInside); + surfaceLine.EnsurePointOfType(pointAtToeRiver.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopRiver.X, pointAtTopRiver.Z, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(pointAtTopPolder.X, pointAtTopPolder.Z, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(pointAtToePolder.X, pointAtToePolder.Z, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(100, 0, CharacteristicPointType.SurfaceLevelInside); - var surfaceLineAdapter = new SurfaceLineHeightAdapter(surfaceLine, location); - var newSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(newDikeHeight); - { - var newPointAtToeRiver = newSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver); - Assert.IsTrue(newPointAtToeRiver.LocationEquals(pointAtToeRiver)); - Assert.IsTrue(newSurfaceLine.Geometry.Points.Any(p => p.LocationEquals(pointAtToeRiver))); - } + var surfaceLineAdapter = new SurfaceLineHeightAdapter(surfaceLine, location); + var newSurfaceLine = surfaceLineAdapter.ConstructNewSurfaceLine(newDikeHeight); + { + var newPointAtToeRiver = newSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver); + Assert.IsTrue(newPointAtToeRiver.LocationEquals(pointAtToeRiver)); + Assert.IsTrue(newSurfaceLine.Geometry.Points.Any(p => p.LocationEquals(pointAtToeRiver))); } } @@ -997,4 +991,4 @@ Assert.Null(newSurfaceLine); } } -} +} Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/SurfaceLineShoulderAdapter.cs =================================================================== diff -u --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/SurfaceLineShoulderAdapter.cs (revision 0) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/SurfaceLineShoulderAdapter.cs (revision 967) @@ -0,0 +1,265 @@ +// Copyright (C) Stichting Deltares 2018. All rights reserved. +// +// This file is part of the Dam Engine. +// +// The Dam Engine is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero 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 Deltares.DamEngine.Calculators.Dikes_Design; +using Deltares.DamEngine.Data.General; +using Deltares.DamEngine.Data.Geometry; +using Deltares.DamEngine.Data.Geotechnics; +using Deltares.DamEngine.Data.Standard.Language; + +namespace Deltares.DamEngine.Calculators.DikesDesign +{ + public class SurfaceLineShoulderAdapter : SurfaceLineAdapter + { + /// + /// Initializes a new instance of the class. + /// + /// + /// + /// + public SurfaceLineShoulderAdapter(SurfaceLine2 surfaceLine, Location location) : base(surfaceLine, location) + { + if (!surfaceLine.HasAnnotation(CharacteristicPointType.SurfaceLevelInside)) + throw new SurfaceLineAdapterException(); + SlopeOfNewShoulder = 3; // CoTangent i.e. width (dx) : height (dz) = 3 : 1 (= tangent: 1/3) + // It must be possible to define SlopeOfNewShoulder hard in code for certain options (such as Rijnland option) which should not be overriden + // by this use option. So the use option has to be implemented here in the constructor. + if (Location.UseNewShoulderBaseSlope) + { + SlopeOfNewShoulder = 1 / Location.NewShoulderBaseSlope; + } + MaxShoulderLevel = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z; + } + + /// + /// Gets or sets the maximum shoulder level. + /// + /// + /// The maximum shoulder level. + /// + public double MaxShoulderLevel { get; set; } + /// + /// Gets or sets the slope of new shoulder. + /// + /// + /// The slope of new shoulder. + /// + public double SlopeOfNewShoulder { get; set; } + + /// + /// Raise exception if new shoulder is smaller than existing shoulder + /// + /// + /// + /// + private void ValidateNewShoulderSize(double shoulderWidth, double shoulderHeight) + { + if (surfaceLine.HasShoulderInside()) + { + double currentShoulderWidth = surfaceLine.DetermineShoulderLengthForGivenShoulderTopInside(surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside)); + if (currentShoulderWidth > shoulderWidth) + { + throw new SurfaceLineAdapterException(LocalizationManager.GetTranslatedText(this, "SurfaceLineShoulderAdapterNewShoulderWidthError")); + } + double currentShoulderHeight = surfaceLine.DetermineShoulderHeight(); + if (currentShoulderHeight > shoulderHeight) + { + throw new SurfaceLineAdapterException(LocalizationManager.GetTranslatedText(this, "SurfaceLineShoulderAdapterNewShoulderHeightError")); + } + if (shoulderWidth < 0) + { + throw new SurfaceLineAdapterException(LocalizationManager.GetTranslatedText(this, "SurfaceLineShoulderAdapterNewShoulderWidthError")); + } + if (shoulderHeight < 0) + { + throw new SurfaceLineAdapterException(LocalizationManager.GetTranslatedText(this, "SurfaceLineShoulderAdapterNewShoulderHeightZeroError")); + } + } + } + + /// + /// Remove all non characteristic points between DikeTopAtPolder and DikeToeAtPolder + /// + /// The surface line. + private void RemovePointsBetweenCharacteristicPointsDikeTopAtPolderDikeToeAtPolder(SurfaceLine2 surfaceLine2) + { + bool hasShoulderInside = surfaceLine2.HasShoulderInside(); + GeometryPoint dikeTopAtPolder = surfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder); + GeometryPoint dikeToeAtPolder = surfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); + if (hasShoulderInside) + { + GeometryPoint shoulderBaseInside = surfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside); + GeometryPoint shoulderTopInside = surfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside); + surfaceLine2.RemoveSegmentBetween(dikeTopAtPolder.X, shoulderBaseInside.X); + surfaceLine2.RemoveSegmentBetween(shoulderBaseInside.X, shoulderTopInside.X); + surfaceLine2.RemoveSegmentBetween(shoulderTopInside.X, dikeToeAtPolder.X); + } + else + { + surfaceLine2.RemoveSegmentBetween(dikeTopAtPolder.X, dikeToeAtPolder.X); + } + } + + /// + /// ShoulderWidth = horizontal distance between ShoulderTopInside and ShoulderBaseInside + /// ShoulderHeight = vertical distance between ShoulderTopInside and DikeToeAtPolder + /// The default slope of the shoulder will be 1 : 3 + /// The height has a maximum of MaxFractionOfDikeHeightForShoulderHeight (default 2/3) * dike height + /// + /// + /// + /// Ensure that shoulder complies with piping design Demands (shoulder from toe instead of intersection old dike, height gives error + /// + public SurfaceLine2 ConstructNewSurfaceLine(double shoulderWidth, double shoulderHeight, bool designFromDikeToe) + { + var orgMaxX = surfaceLine.Geometry.GetMaxX(); + if (double.IsNaN(orgMaxX)) + { + orgMaxX = double.MaxValue; + } + // Make dike and shoulder straight + RemovePointsBetweenCharacteristicPointsDikeTopAtPolderDikeToeAtPolder(surfaceLine); + // See it there is a ditch, if so store its characteristics. + var ditchDefinition = GetDitchDefinition(); + // Then delete it from the surfaceline + RemoveExistingDitch(ditchDefinition); + ValidateNewShoulderSize(shoulderWidth, shoulderHeight); + GeometryPoint dikeTopAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder); + GeometryPoint dikeToeAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder); + + if (designFromDikeToe) + { + // for piping design, when the required new height is larger than allowed, it is an error! + if ((MaxShoulderLevel - dikeToeAtPolder.Z) < shoulderHeight) + { + throw new SurfaceLineAdapterException(LocalizationManager.GetTranslatedText(this, "SurfaceLineShoulderAdapterNewShoulderHeightTooLargeError")); + } + } + else + { + // Assure new height is less then or equal to the maximum height + shoulderHeight = Math.Min(shoulderHeight, (MaxShoulderLevel - dikeToeAtPolder.Z)); + } + + // Find the intersection point at new shoulder height with the dike, this is where the new shoulder starts + bool hasShoulderInside = surfaceLine.HasShoulderInside(); + double dikeToeZ = dikeToeAtPolder.Z; + GeometryPoint dikeBaseInside = hasShoulderInside ? surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside) : dikeToeAtPolder; + // Determine intersectionpoint with slope for a horizontal shoulder + GeometryPoint intersectionPointAtDike; + intersectionPointAtDike = LineHelper.GetIntersectionPointWithExtrapolation(dikeTopAtPolder, dikeBaseInside, + new GeometryPoint(dikeToeAtPolder.X, shoulderHeight + dikeToeZ), + new GeometryPoint(dikeToeAtPolder.X + 1, shoulderHeight + dikeToeZ)); + var newTopShoulder = new GeometryPoint(intersectionPointAtDike.X + shoulderWidth, shoulderHeight + dikeToeZ); + if (Location.UseNewShoulderTopSlope) + { + // if top slope is not to be horizontal then recalculate the intersection from a point at required slope width + // from the horizontal intersection point. This will result in the actual width of the shoulder being a bit + // larger than the requested size but that can not be helped (classic chicken-egg problem) + var pb = new GeometryPoint(newTopShoulder.X - 100, newTopShoulder.Z + (100*Location.NewShoulderTopSlope)); + intersectionPointAtDike = LineHelper.GetIntersectionPointWithExtrapolation(dikeTopAtPolder, dikeBaseInside, pb, newTopShoulder); + if (intersectionPointAtDike.Z > MaxShoulderLevel) + { + throw new SurfaceLineAdapterException(LocalizationManager.GetTranslatedText(this, "SurfaceLineShoulderAdapterNewShoulderHeightTooLargeTopSlopeError")); + } + } + + // Find the intersection at the surface line from a line starting at the end of the new shoulder sloping down at 1 : SlopeOfNewShoulder + // to get the new point of the toe. Note that for stability the shoulderwidth is applied directly to the intersection point as for piping + // the shoulderwidth is applied from the original diketoe (so for piping the complete shoulder is longer). + var xStart = intersectionPointAtDike.X; + const double offset = 100.0; + if (designFromDikeToe) + { + xStart = dikeToeAtPolder.X; + } + var line = new Line + { + BeginPoint = new Point2D(newTopShoulder.X, newTopShoulder.Z), + EndPoint =new Point2D(newTopShoulder.X + offset, newTopShoulder.Z - offset / SlopeOfNewShoulder) + }; + var intersectionpoints = surfaceLine.Geometry.IntersectionPointsXzWithLineXz(line); + GeometryPoint newToeAtPolder = null; + if (intersectionpoints.Count > 0) + { + var firstIntersectionPoint = intersectionpoints.First(); + newToeAtPolder = new GeometryPoint(firstIntersectionPoint.X, firstIntersectionPoint.Z); + } + if (newToeAtPolder == null) + { + // If the intersection was not found, this could mean that A) the new shoulder intersects the surfaceline at the + // shoulderheight itself or B) that the original surfaceline is not long enough to intersect the new shoulder + // (this happens when the end of the new shoulder falls pratically at the end of the surfaceline in which case + // there is no room to fit the entire shoulder in the original surfaceline). For A) try to find that intersection + // point and use it as new toe. If not, something is very wrong (probably B) and an exception must be raised. + var line1 = new Line + { + BeginPoint = new Point2D(xStart + 0.001, intersectionPointAtDike.Z), + EndPoint = new Point2D(xStart + shoulderWidth, intersectionPointAtDike.Z) + }; + var intersectionpoints2 = surfaceLine.Geometry.IntersectionPointsXzWithLineXz(line1); + if (intersectionpoints2.Count > 0) + { + var firstIntersectionPoint = intersectionpoints2.First(); + newToeAtPolder = new GeometryPoint(firstIntersectionPoint.X, firstIntersectionPoint.Z); + } + if (newToeAtPolder == null) + { + throw new SurfaceLineAdapterException(LocalizationManager.GetTranslatedText(this, + "SurfaceLineShoulderAdapterNewShoulderNoIntersectionError")); + } + } + + if (designFromDikeToe) + { + // for piping design, the new toe must be placed at shoulderWidth from the original toe, not from the new intersection point. + newToeAtPolder.X = dikeToeAtPolder.X + shoulderWidth + shoulderHeight * SlopeOfNewShoulder; + } + + // remove old line (point) segment starting from intersection dike inside to new intersection ground + surfaceLine.RemoveSegmentBetween(intersectionPointAtDike.X, newToeAtPolder.X); + + // insert the new shoulder points + surfaceLine.EnsurePointOfType(intersectionPointAtDike.X, intersectionPointAtDike.Z, CharacteristicPointType.ShoulderBaseInside); + surfaceLine.EnsurePointOfType(newTopShoulder.X, newTopShoulder.Z, CharacteristicPointType.ShoulderTopInside); + + // Place new dike toe + surfaceLine.EnsurePointOfType(newToeAtPolder.X, newToeAtPolder.Z, CharacteristicPointType.DikeToeAtPolder); + + // Check whether the surface line is extended. This is not allowed! + if (surfaceLine.Geometry.GetMaxX() > orgMaxX) + { + throw new SurfaceLineAdapterException(LocalizationManager.GetTranslatedText(this, "SurfaceLineShoulderAdapterNewShoulderWidthTooLargeError")); + } + + // Restore Ditch (if any) + RestoreDitch(ditchDefinition); + + // Restore traffic load + RestoreTrafficLoad(); + surfaceLine.SortPoints(); + + return surfaceLine; + } + } +} \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj =================================================================== diff -u -r963 -r967 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj (.../Deltares.DamEngine.Calculators.csproj) (revision 963) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj (.../Deltares.DamEngine.Calculators.csproj) (revision 967) @@ -60,6 +60,7 @@ + @@ -172,7 +173,7 @@ CalcDlls\MPipingCalc2.dll - DGeoStability.exe + DGeoStability.exe PreserveNewest Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/Deltares.DamEngine.Calculators.Tests.csproj =================================================================== diff -u -r955 -r967 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/Deltares.DamEngine.Calculators.Tests.csproj (.../Deltares.DamEngine.Calculators.Tests.csproj) (revision 955) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/Deltares.DamEngine.Calculators.Tests.csproj (.../Deltares.DamEngine.Calculators.Tests.csproj) (revision 967) @@ -47,6 +47,7 @@ +