// Copyright (C) Stichting Deltares 2025. 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.Collections.Generic; using System.Linq; using Deltares.DamEngine.Calculators.PlLinesCreator; using Deltares.DamEngine.Data.Design; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.General.PlLines; using Deltares.DamEngine.Data.General.Sensors; using Deltares.DamEngine.Data.Geometry; using Deltares.DamEngine.Data.Geotechnics; using NUnit.Framework; namespace Deltares.DamEngine.Calculators.Tests.Sensors; [TestFixture] public class SensorPlLineCreatorTest { [Test] public void CreatePlLine_Pl1NoSensorData_Throws() { // setup var location = new Location("test"); SensorLocation sensorLocation = new SensorFactory().CreateSensorLocation(location); var creator = SensorPlLineCreator.CreateInstance(sensorLocation, new Dictionary()); // call Assert.That(() => creator.CreatePlLine(PlLineType.Pl1), Throws.InstanceOf()); } [Test] // Pl2 is not yet supported public void CreatePlLine_Pl2_ThrowsNotSupported() { // setup var location = new Location("test"); SensorLocation sensorLocation = new SensorFactory().CreateSensorLocation(location); var creator = SensorPlLineCreator.CreateInstance(sensorLocation, new Dictionary()); // call Assert.That(() => creator.CreatePlLine(PlLineType.Pl2), Throws.InstanceOf()); } [Test] public void CreatePlLine_Pl3NoSensorData_Throws() { // setup var location = new Location("test"); location.Scenarios.Add(new DesignScenario()); SensorLocation sensorLocation = new SensorFactory().CreateSensorLocation(location); var creator = SensorPlLineCreator.CreateInstance(sensorLocation, new Dictionary()); // call Assert.That(() => creator.CreatePlLine(PlLineType.Pl3), Throws.InstanceOf()); } [Test] public void CreatePlLine_Pl4NoSensorData_Throws() { // setup var location = new Location("test"); location.Scenarios.Add(new DesignScenario()); SensorLocation sensorLocation = new SensorFactory().CreateSensorLocation(location); var creator = SensorPlLineCreator.CreateInstance(sensorLocation, new Dictionary()); // call Assert.That(() => creator.CreatePlLine(PlLineType.Pl4), Throws.InstanceOf()); } [Test] public void CreatePlLine_AllPlLinesDummyTest_ResultsAreAsExpected() { // setup var surfaceLine = new SurfaceLine2 { CharacteristicPoints = { GeometryMustContainPoint = true }, Geometry = new GeometryPointString() }; Location location = CreateConfiguredLocation("test", 1, 1); location.AddSensorLocation(); location.SensorLocation.SourceTypePl1PlLineOffsetBelowDikeToeAtPolder = DataSourceTypeSensors.LocationData; location.SensorLocation.SourceTypePl1PlLineOffsetBelowDikeTopAtPolder = DataSourceTypeSensors.LocationData; location.SensorLocation.SourceTypePl1PlLineOffsetBelowDikeTopAtRiver = DataSourceTypeSensors.LocationData; location.SensorLocation.SourceTypePl1PlLineOffsetBelowShoulderBaseInside = DataSourceTypeSensors.LocationData; // create dike with ditch surfaceLine.EnsurePointOfType(0.0, 0.0, CharacteristicPointType.SurfaceLevelOutside); surfaceLine.EnsurePointOfType(50.0, 0.0, CharacteristicPointType.DikeToeAtRiver); surfaceLine.EnsurePointOfType(85.0, 8.0, CharacteristicPointType.DikeTopAtRiver); surfaceLine.EnsurePointOfType(95.0, 8.0, CharacteristicPointType.DikeTopAtPolder); surfaceLine.EnsurePointOfType(108.0, 4.0, CharacteristicPointType.ShoulderBaseInside); surfaceLine.EnsurePointOfType(116.0, 3.0, CharacteristicPointType.ShoulderTopInside); surfaceLine.EnsurePointOfType(121.0, 0.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.EnsurePointOfType(190.0, 0.0, CharacteristicPointType.SurfaceLevelInside); location.SurfaceLine = surfaceLine; var sensor1 = new Sensor { ID = 1, Name = "Test1", Depth = 2, RelativeLocation = 50, PlLineMappings = new[] { PlLineType.Pl1 }, SensorType = SensorType.WaterLevel }; var sensor2 = new Sensor { ID = 2, Name = "Test2", Depth = 2, RelativeLocation = 90, PlLineMappings = new[] { PlLineType.Pl1 } }; var sensor3 = new Sensor { ID = 3, Name = "Test3", Depth = 2, RelativeLocation = 104, PlLineMappings = new[] { PlLineType.Pl1 } }; var sensor4 = new Sensor { ID = 4, Name = "Test4", Depth = 2, RelativeLocation = 123.3, PlLineMappings = new[] { PlLineType.Pl1 } }; var sensor5 = new Sensor { ID = 5, Name = "Test5", Depth = 2, RelativeLocation = 90, PlLineMappings = new[] { PlLineType.Pl3, PlLineType.Pl4 } }; var sensor6 = new Sensor { ID = 6, Name = "Test6", Depth = 2, RelativeLocation = 123.3, PlLineMappings = new[] { PlLineType.Pl3, PlLineType.Pl4 } }; var sensor7 = new Sensor { ID = 7, Name = "Test7", Depth = 2, RelativeLocation = 180, PlLineMappings = new[] { PlLineType.Pl3, PlLineType.Pl4 } }; var repository = new SensorRepository(location); repository.Add(sensor1); repository.Add(sensor2); repository.Add(sensor3); repository.Add(sensor4); repository.Add(sensor5); repository.Add(sensor6); repository.Add(sensor7); IDictionary sensorValues = new Dictionary { { sensor1, 1 }, { sensor2, 1 }, { sensor3, 1 }, { sensor4, 1 }, { sensor5, 1 }, { sensor6, 1 }, { sensor7, 1 } }; SensorLocation sensorLocation = location.SensorLocation; var creator = new SensorPlLine1Creator(sensorLocation, sensorValues); // call PlLine actual = creator.CreatePlLine(); // asserts // Number of expected points in line int expectedCount = repository.Sensors.Count(s => s.PlLineMappings.Contains(PlLineType.Pl1)) + 2 + 4; // interection + end + 4 configured characteristic points Assert.That(actual.Points.Count, Is.EqualTo(expectedCount)); // P1 PlLinePoint p1 = actual.Points.First(); Assert.That(p1, Is.Not.Null); double expectedZValueP1 = sensorValues[sensor1]; Assert.That(p1.Z, Is.EqualTo(expectedZValueP1)); // P2 PlLinePoint p2 = actual.Points.FirstOrDefault(p => p.Name == sensor2.Name); Assert.That(p2, Is.Not.Null); Assert.That(p2.X, Is.EqualTo(sensor2.RelativeLocation)); double expectedZValueP2 = sensorValues[sensor2]; Assert.That(p2.Z, Is.EqualTo(expectedZValueP2)); // P3 PlLinePoint p3 = actual.Points.FirstOrDefault(p => p.Name == sensor3.Name); Assert.That(p3, Is.Not.Null); Assert.That(p3.X, Is.EqualTo(sensor3.RelativeLocation)); double expectedZValueP3 = sensorValues[sensor3]; Assert.That(p3.Z, Is.EqualTo(expectedZValueP3)); // P4 PlLinePoint p4 = actual.Points.FirstOrDefault(p => p.Name == sensor4.Name); Assert.That(p4, Is.Not.Null); Assert.That(p4.X, Is.EqualTo(sensor4.RelativeLocation)); double expectedZValueP4 = sensorValues[sensor4]; Assert.That(p4.Z, Is.EqualTo(expectedZValueP4)); } [Test] public void CreatePlLine_NoLocationDataAtPl1DikeToeAtPolderAndNoPolderSensor_HorizontalLineExpectedBetweenLastSensorValueAndSurfaceLevelInside() { // setup var surfaceLine = new SurfaceLine2 { CharacteristicPoints = { GeometryMustContainPoint = true }, Geometry = new GeometryPointString() }; Location location = CreateConfiguredLocation("test", 5, -1); location.AddSensorLocation(); location.SensorLocation.SourceTypePl1PlLineOffsetBelowDikeTopAtRiver = DataSourceTypeSensors.LocationData; location.SensorLocation.SourceTypePl1PlLineOffsetBelowDikeTopAtPolder = DataSourceTypeSensors.LocationData; location.SensorLocation.SourceTypePl1PlLineOffsetBelowShoulderBaseInside = DataSourceTypeSensors.LocationData; location.SensorLocation.SourceTypePl1PlLineOffsetBelowDikeToeAtPolder = DataSourceTypeSensors.Ignore; surfaceLine.EnsurePointOfType(0.0, 0.0, CharacteristicPointType.SurfaceLevelOutside); surfaceLine.EnsurePointOfType(50.0, 0.0, CharacteristicPointType.DikeToeAtRiver); surfaceLine.EnsurePointOfType(85.0, 8.0, CharacteristicPointType.DikeTopAtRiver); surfaceLine.EnsurePointOfType(95.0, 8.0, CharacteristicPointType.DikeTopAtPolder); surfaceLine.EnsurePointOfType(108.0, 4.0, CharacteristicPointType.ShoulderBaseInside); surfaceLine.EnsurePointOfType(116.0, 3.0, CharacteristicPointType.ShoulderTopInside); surfaceLine.EnsurePointOfType(121.0, 0.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.EnsurePointOfType(190.0, 0.0, CharacteristicPointType.SurfaceLevelInside); location.SurfaceLine = surfaceLine; var sensor1 = new Sensor { ID = 1, Name = "Test1", Depth = 2, RelativeLocation = 50, PlLineMappings = new[] { PlLineType.Pl1 }, SensorType = SensorType.WaterLevel }; var sensor2 = new Sensor { ID = 2, Name = "Test2", Depth = 2, RelativeLocation = 90, PlLineMappings = new[] { PlLineType.Pl1 } }; var sensor3 = new Sensor { ID = 3, Name = "Test3", Depth = 2, RelativeLocation = 104, PlLineMappings = new[] { PlLineType.Pl1 } }; var sensor4 = new Sensor { ID = 4, Name = "Test4", Depth = 2, RelativeLocation = 123.3, PlLineMappings = new[] { PlLineType.Pl1 } }; var repository = new SensorRepository(location); repository.Add(sensor1); repository.Add(sensor2); repository.Add(sensor3); repository.Add(sensor4); const double sensor1Value = 1.1; const double sensor2Value = 1.2; const double sensor3Value = 1.3; const double sensor4Value = 1.4; IDictionary sensorValues = new Dictionary { { sensor1, sensor1Value }, { sensor2, sensor2Value }, { sensor3, sensor3Value }, { sensor4, sensor4Value } }; SensorLocation sensorLocation = location.SensorLocation; var creator = new SensorPlLine1Creator(sensorLocation, sensorValues); // call PlLine actual = creator.CreatePlLine(); // asserts PlLinePoint lastPoint = actual.Points.Last(); Assert.That(actual.Points, Has.Count.EqualTo(9)); Assert.Multiple(() => { Assert.That(actual.Points[0].X, Is.EqualTo(0)); Assert.That(actual.Points[0].Z, Is.EqualTo(5)); Assert.That(actual.Points[1].X, Is.EqualTo(71.875)); Assert.That(actual.Points[1].Z, Is.EqualTo(5)); Assert.That(actual.Points[2].X, Is.EqualTo(85)); Assert.That(actual.Points[2].Z, Is.EqualTo(4.5)); Assert.That(actual.Points[3].X, Is.EqualTo(90)); Assert.That(actual.Points[3].Z, Is.EqualTo(sensor2Value)); Assert.That(actual.Points[4].X, Is.EqualTo(95)); Assert.That(actual.Points[4].Z, Is.EqualTo(3.5)); Assert.That(actual.Points[5].X, Is.EqualTo(104)); Assert.That(actual.Points[5].Z, Is.EqualTo(sensor3Value)); Assert.That(actual.Points[6].X, Is.EqualTo(108)); Assert.That(actual.Points[6].Z, Is.EqualTo(3.9)); Assert.That(actual.Points[7].X, Is.EqualTo(123.3)); Assert.That(actual.Points[7].Z, Is.EqualTo(sensor4Value)); Assert.That(actual.Points[8].X, Is.EqualTo(190)); Assert.That(actual.Points[8].Z, Is.EqualTo(sensor4Value)); }); } [Test] public void GetDitchWaterLevelIntersectionAtXDikeSide_PolderLevelIntersectsInDitch_ShouldReturnIntersectionValue() { // setup var surfaceLine = new SurfaceLine2 { CharacteristicPoints = { GeometryMustContainPoint = true }, Geometry = new GeometryPointString() }; var location = new Location(); surfaceLine.EnsurePointOfType(0.0, 0.0, CharacteristicPointType.SurfaceLevelOutside); surfaceLine.EnsurePointOfType(10, 0.0, CharacteristicPointType.DitchDikeSide); surfaceLine.EnsurePointOfType(15, -5, CharacteristicPointType.BottomDitchDikeSide); surfaceLine.EnsurePointOfType(17, -5, CharacteristicPointType.BottomDitchPolderSide); surfaceLine.EnsurePointOfType(20, 0.0, CharacteristicPointType.DitchPolderSide); surfaceLine.EnsurePointOfType(25, 0.0, CharacteristicPointType.SurfaceLevelInside); location.AddSensorLocation(); location.SurfaceLine = surfaceLine; var creator = new SensorPlLine1Creator(location.SensorLocation, new Dictionary()); double? actual = creator.GetDitchWaterLevelIntersectionAtXDikeSide(-2.5); const double expected = 12.5; Assert.That(actual, Is.EqualTo(expected)); } [Test] public void CreatePlLine_Pl1IgnorAllSensors_ResultsAreAsExpected() { // setup var surfaceLine = new SurfaceLine2 { CharacteristicPoints = { GeometryMustContainPoint = true }, Geometry = new GeometryPointString() }; Location location = CreateConfiguredLocation("test", 1, 1); location.AddSensorLocation(); location.SensorLocation.SourceTypePl1PlLineOffsetBelowDikeToeAtPolder = DataSourceTypeSensors.Ignore; location.SensorLocation.SourceTypePl1PlLineOffsetBelowDikeTopAtPolder = DataSourceTypeSensors.Ignore; location.SensorLocation.SourceTypePl1PlLineOffsetBelowDikeTopAtRiver = DataSourceTypeSensors.Ignore; location.SensorLocation.SourceTypePl1PlLineOffsetBelowShoulderBaseInside = DataSourceTypeSensors.Ignore; location.SensorLocation.SourceTypePl1WaterLevelAtRiver = DataSourceTypeSensors.LocationData; location.SensorLocation.SourceTypePl1WaterLevelAtPolder = DataSourceTypeSensors.LocationData; // Assert.IsTrue(location.SensorData.IsValid()); surfaceLine.EnsurePointOfType(0.0, 0.0, CharacteristicPointType.SurfaceLevelOutside); surfaceLine.EnsurePointOfType(50.0, 0.0, CharacteristicPointType.DikeToeAtRiver); surfaceLine.EnsurePointOfType(80.0, 5.0, CharacteristicPointType.DikeTopAtRiver); surfaceLine.EnsurePointOfType(125, 5.0, CharacteristicPointType.DikeTopAtPolder); surfaceLine.EnsurePointOfType(140.0, 0.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.EnsurePointOfType(145.0, 0.0, CharacteristicPointType.ShoulderBaseInside); surfaceLine.EnsurePointOfType(190.0, 0.0, CharacteristicPointType.SurfaceLevelInside); location.SurfaceLine = surfaceLine; var sensor1 = new Sensor { ID = 1, Name = "Test1", Depth = 2, RelativeLocation = 50, PlLineMappings = new[] { PlLineType.Pl1 }, SensorType = SensorType.WaterLevel }; var sensor2 = new Sensor { ID = 2, Name = "Test2", Depth = 2, RelativeLocation = 90, PlLineMappings = new[] { PlLineType.Pl1 } }; var sensor3 = new Sensor { ID = 3, Name = "Test3", Depth = 2, RelativeLocation = 104, PlLineMappings = new[] { PlLineType.Pl1 } }; var sensor4 = new Sensor { ID = 4, Name = "Test4", Depth = 2, RelativeLocation = 123.3, PlLineMappings = new[] { PlLineType.Pl1 } }; var sensor5 = new Sensor { ID = 5, Name = "Test5", Depth = 2, RelativeLocation = 90, PlLineMappings = new[] { PlLineType.Pl3, PlLineType.Pl4 } }; var sensor6 = new Sensor { ID = 6, Name = "Test6", Depth = 2, RelativeLocation = 123.3, PlLineMappings = new[] { PlLineType.Pl3, PlLineType.Pl4 } }; var sensor7 = new Sensor { ID = 7, Name = "Test7", Depth = 2, RelativeLocation = 180, PlLineMappings = new[] { PlLineType.Pl3, PlLineType.Pl4 } }; var repository = new SensorRepository(location); repository.Add(sensor1); repository.Add(sensor2); repository.Add(sensor3); repository.Add(sensor4); repository.Add(sensor5); repository.Add(sensor6); repository.Add(sensor7); IDictionary sensorValues = new Dictionary { { sensor1, 1 }, { sensor2, 1 }, { sensor3, 1 }, { sensor4, 1 }, { sensor5, 1 }, { sensor6, 1 }, { sensor7, 1 } }; SensorLocation sensorLocation = location.SensorLocation; var creator = new SensorPlLine1Creator(sensorLocation, sensorValues); // call PlLine actual = creator.CreatePlLine(); // asserts // Number of expected points in PL 1 const int expectedNumberOfCharacteristicPoints = 1; // Surface line inside int pl1SensorCount = repository.Sensors.Count(s => s.PlLineMappings.Contains(PlLineType.Pl1)) + expectedNumberOfCharacteristicPoints + 1; // plus one for the intersection point Assert.That(actual.Points, Has.Count.EqualTo(pl1SensorCount)); // P2 PlLinePoint p2 = actual.Points.FirstOrDefault(p => p.Name == sensor2.Name); Assert.That(p2, Is.Not.Null); Assert.That(p2.X, Is.EqualTo(sensor2.RelativeLocation)); double expectedZValueP2 = sensorValues[sensor2]; Assert.That(p2.Z, Is.EqualTo(expectedZValueP2)); // P3 PlLinePoint p3 = actual.Points.FirstOrDefault(p => p.Name == sensor3.Name); Assert.That(p3, Is.Not.Null); Assert.That(p3.X, Is.EqualTo(sensor3.RelativeLocation)); double expectedZValueP3 = sensorValues[sensor3]; Assert.That(p3.Z, Is.EqualTo(expectedZValueP3)); // P4 PlLinePoint p4 = actual.Points.FirstOrDefault(p => p.Name == sensor4.Name); Assert.That(p4, Is.Not.Null); Assert.That(p4.X, Is.EqualTo(sensor4.RelativeLocation)); double expectedZValueP4 = sensorValues[sensor4]; Assert.That(p4.Z, Is.EqualTo(expectedZValueP4)); } [Test] public void CreatePlLinePl1_DikeHasDitch_ResultsAreAsExpected() { var surfaceLine = new SurfaceLine2 { CharacteristicPoints = { GeometryMustContainPoint = true }, Geometry = new GeometryPointString() }; Location location = CreateConfiguredLocation("test", 1, 1); #region Setup location.AddSensorLocation(); location.SensorLocation.SourceTypePl1PlLineOffsetBelowDikeToeAtPolder = DataSourceTypeSensors.Ignore; location.SensorLocation.SourceTypePl1PlLineOffsetBelowDikeTopAtPolder = DataSourceTypeSensors.Ignore; location.SensorLocation.SourceTypePl1PlLineOffsetBelowDikeTopAtRiver = DataSourceTypeSensors.Ignore; location.SensorLocation.SourceTypePl1PlLineOffsetBelowShoulderBaseInside = DataSourceTypeSensors.Ignore; location.SensorLocation.SourceTypePl1WaterLevelAtRiver = DataSourceTypeSensors.LocationData; location.SensorLocation.SourceTypePl1WaterLevelAtPolder = DataSourceTypeSensors.LocationData; // Assert.IsTrue(location.SensorData.IsValid()); surfaceLine.EnsurePointOfType(0.0, 0.0, CharacteristicPointType.SurfaceLevelOutside); surfaceLine.EnsurePointOfType(50.0, 0.0, CharacteristicPointType.DikeToeAtRiver); surfaceLine.EnsurePointOfType(80.0, 5.0, CharacteristicPointType.DikeTopAtRiver); surfaceLine.EnsurePointOfType(125, 5.0, CharacteristicPointType.DikeTopAtPolder); surfaceLine.EnsurePointOfType(140.0, 0.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.EnsurePointOfType(148.0, 0.5, CharacteristicPointType.DitchDikeSide); surfaceLine.EnsurePointOfType(150.0, -4.0, CharacteristicPointType.BottomDitchDikeSide); surfaceLine.EnsurePointOfType(154.0, -4.0, CharacteristicPointType.BottomDitchPolderSide); surfaceLine.EnsurePointOfType(158.0, 0.0, CharacteristicPointType.DitchPolderSide); surfaceLine.EnsurePointOfType(190.0, 0.0, CharacteristicPointType.SurfaceLevelInside); location.SurfaceLine = surfaceLine; var sensor1 = new Sensor { ID = 1, Name = "Test1", Depth = 2, RelativeLocation = 50, PlLineMappings = new[] { PlLineType.Pl1 }, SensorType = SensorType.WaterLevel }; var sensor2 = new Sensor { ID = 2, Name = "Test2", Depth = 2, RelativeLocation = 90, PlLineMappings = new[] { PlLineType.Pl1 } }; var sensor3 = new Sensor { ID = 3, Name = "Test3", Depth = 2, RelativeLocation = 104, PlLineMappings = new[] { PlLineType.Pl1 } }; var sensor4 = new Sensor { ID = 4, Name = "Test4", Depth = 2, RelativeLocation = 128, PlLineMappings = new[] { PlLineType.Pl1 } }; var repository = new SensorRepository(location); repository.Add(sensor1); repository.Add(sensor2); repository.Add(sensor3); repository.Add(sensor4); IDictionary sensorValues = new Dictionary { { sensor1, 3 }, { sensor2, 3 }, { sensor3, 3 }, { sensor4, 3 } }; SensorLocation sensorLocation = location.SensorLocation; var creator = new SensorPlLine1Creator(sensorLocation, sensorValues); #endregion // call PlLine actual = creator.CreatePlLine(); // asserts // Number of expected points in line int pl1SensorCount = repository.Sensors.Count(s => s.PlLineMappings.Contains(PlLineType.Pl1)); Assert.That(actual.Points.Count, Is.EqualTo(pl1SensorCount + 2)); // P2 PlLinePoint p2 = actual.Points.FirstOrDefault(p => p.Name == sensor2.Name); Assert.That(p2, Is.Not.Null); Assert.That(p2.X, Is.EqualTo(sensor2.RelativeLocation)); double expectedZValueP2 = sensorValues[sensor2]; Assert.That(p2.Z, Is.EqualTo(expectedZValueP2)); // P3 PlLinePoint p3 = actual.Points.FirstOrDefault(p => p.Name == sensor3.Name); Assert.That(p3, Is.Not.Null); Assert.That(p3.X, Is.EqualTo(sensor3.RelativeLocation)); double expectedZValueP3 = sensorValues[sensor3]; Assert.That(p3.Z, Is.EqualTo(expectedZValueP3)); // P4 PlLinePoint p4 = actual.Points.FirstOrDefault(p => p.Name == sensor4.Name); Assert.That(p4, Is.Not.Null); Assert.That(p4.X, Is.EqualTo(sensor4.RelativeLocation)); double expectedZValueP4 = sensorValues[sensor4]; Assert.That(p4.Z, Is.EqualTo(expectedZValueP4)); } [Test] public void CreatePlLine_DikeHasDitchAndSensor_DichLevelIsHorizontal() { const int polderLevel = 0; const int waterLevel = 1; var surfaceLine = new SurfaceLine2 { CharacteristicPoints = { GeometryMustContainPoint = true }, Geometry = new GeometryPointString() }; Location location = CreateConfiguredLocation("test", 1, polderLevel); #region Setup location.AddSensorLocation(); location.SensorLocation.SourceTypePl1PlLineOffsetBelowDikeToeAtPolder = DataSourceTypeSensors.Ignore; location.SensorLocation.SourceTypePl1PlLineOffsetBelowDikeTopAtPolder = DataSourceTypeSensors.Ignore; location.SensorLocation.SourceTypePl1PlLineOffsetBelowDikeTopAtRiver = DataSourceTypeSensors.Ignore; location.SensorLocation.SourceTypePl1PlLineOffsetBelowShoulderBaseInside = DataSourceTypeSensors.Ignore; location.SensorLocation.SourceTypePl1WaterLevelAtRiver = DataSourceTypeSensors.Sensor; location.SensorLocation.SourceTypePl1WaterLevelAtPolder = DataSourceTypeSensors.Sensor; // Assert.IsTrue(location.SensorData.IsValid()); surfaceLine.EnsurePointOfType(0.0, 0.0, CharacteristicPointType.SurfaceLevelOutside); surfaceLine.EnsurePointOfType(50.0, 0.0, CharacteristicPointType.DikeToeAtRiver); surfaceLine.EnsurePointOfType(80.0, 5.0, CharacteristicPointType.DikeTopAtRiver); surfaceLine.EnsurePointOfType(125, 5.0, CharacteristicPointType.DikeTopAtPolder); surfaceLine.EnsurePointOfType(140.0, 0.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.EnsurePointOfType(148.0, 0.5, CharacteristicPointType.DitchDikeSide); surfaceLine.EnsurePointOfType(150.0, -4.0, CharacteristicPointType.BottomDitchDikeSide); surfaceLine.EnsurePointOfType(154.0, -4.0, CharacteristicPointType.BottomDitchPolderSide); surfaceLine.EnsurePointOfType(158.0, 0.0, CharacteristicPointType.DitchPolderSide); surfaceLine.EnsurePointOfType(190.0, 0.0, CharacteristicPointType.SurfaceLevelInside); location.SurfaceLine = surfaceLine; var sensor1 = new Sensor { ID = 1, Name = "Test1", Depth = 2, RelativeLocation = 50, PlLineMappings = new[] { PlLineType.Pl1 }, SensorType = SensorType.WaterLevel }; var sensor2 = new Sensor { ID = 2, Name = "Test2", Depth = 2, RelativeLocation = 90, PlLineMappings = new[] { PlLineType.Pl1 } }; var sensor3 = new Sensor { ID = 3, Name = "Test3", Depth = 2, RelativeLocation = 104, PlLineMappings = new[] { PlLineType.Pl1 } }; var sensor4 = new Sensor { ID = 4, Name = "Test4", Depth = 2, RelativeLocation = 128, PlLineMappings = new[] { PlLineType.Pl1 } }; var sensor5 = new Sensor { ID = 5, Name = "Test5", Depth = 2, RelativeLocation = 152, PlLineMappings = new[] { PlLineType.Pl1 }, SensorType = SensorType.PolderLevel }; var repository = new SensorRepository(location); repository.Add(sensor1); repository.Add(sensor2); repository.Add(sensor3); repository.Add(sensor4); repository.Add(sensor5); IDictionary sensorValues = new Dictionary { { sensor1, waterLevel }, { sensor2, -1 }, { sensor3, -1 }, { sensor4, -1 }, { sensor5, -1.5 } }; SensorLocation sensorLocation = location.SensorLocation; #endregion // call var creator = new SensorPlLine1Creator(sensorLocation, sensorValues); PlLine actual = creator.CreatePlLine(); // checks double? xDitchDikeSide = creator.GetDitchWaterLevelIntersectionAtXDikeSide(sensorValues[sensor5]); double? xDitchPolderSide = creator.GetDitchWaterLevelIntersectionAtXPolderSide(sensorValues[sensor5]); Assert.That(actual.Points.Any(p => p.X == xDitchDikeSide), Is.True); double zDitchDikeSide = actual.Points.Single(p => p.X == xDitchDikeSide).Z; double zDitchPolderSide = actual.Points.Single(p => p.X == xDitchPolderSide).Z; Assert.That(actual.Points.Any(p => p.X == xDitchPolderSide), Is.True); Assert.That(zDitchPolderSide, Is.EqualTo(zDitchDikeSide)); PlLinePoint endPoint = actual.Points.Last(); // End point should be z of x intersection at dike side in ditch (horizontal) Assert.That(zDitchDikeSide, Is.EqualTo(endPoint.Z)); } [Test] public void CreatePlLine_Pl3and4_FirstSegmentShouldBeHorizontalEqualToLocationData() { // setup const double xDikeToeAtRiver = 50.0; const double waterLevel = 1.0; var surfaceLine = new SurfaceLine2 { CharacteristicPoints = { GeometryMustContainPoint = true }, Geometry = new GeometryPointString() }; Location location = CreateConfiguredLocation("test", waterLevel, waterLevel); { location.AddSensorLocation(); location.SensorLocation.SourceTypePl3 = DataSourceTypeSensors.Sensor; location.SensorLocation.SourceTypePl1WaterLevelAtRiver = DataSourceTypeSensors.LocationData; location.SensorLocation.SourceTypePl1WaterLevelAtPolder = DataSourceTypeSensors.LocationData; // Assert.IsTrue(location.SensorData.IsValid()); surfaceLine.EnsurePointOfType(0.0, 0.0, CharacteristicPointType.SurfaceLevelOutside); surfaceLine.EnsurePointOfType(xDikeToeAtRiver, 0.0, CharacteristicPointType.DikeToeAtRiver); surfaceLine.EnsurePointOfType(80.0, 5.0, CharacteristicPointType.DikeTopAtRiver); surfaceLine.EnsurePointOfType(125, 5.0, CharacteristicPointType.DikeTopAtPolder); surfaceLine.EnsurePointOfType(140.0, 0.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.EnsurePointOfType(145.0, 0.0, CharacteristicPointType.ShoulderBaseInside); surfaceLine.EnsurePointOfType(190.0, 0.0, CharacteristicPointType.SurfaceLevelInside); location.SurfaceLine = surfaceLine; var sensor1 = new Sensor { ID = 1, Name = "Test1", Depth = waterLevel, RelativeLocation = 50, PlLineMappings = new[] { PlLineType.Pl1 }, SensorType = SensorType.WaterLevel }; var sensor5 = new Sensor { ID = 5, Name = "Test5", Depth = -8, RelativeLocation = 90, PlLineMappings = new[] { PlLineType.Pl3 } }; var sensor6 = new Sensor { ID = 6, Name = "Test6", Depth = -8, RelativeLocation = 123.3, PlLineMappings = new[] { PlLineType.Pl3 } }; var sensor7 = new Sensor { ID = 7, Name = "Test7", Depth = -8, RelativeLocation = 180, PlLineMappings = new[] { PlLineType.Pl3 } }; var repository = new SensorRepository(location); repository.Add(sensor1); repository.Add(sensor5); repository.Add(sensor6); repository.Add(sensor7); IDictionary sensorValues = new Dictionary { { sensor1, waterLevel }, { sensor5, waterLevel }, { sensor6, waterLevel }, { sensor7, waterLevel } }; SensorLocation sensorLocation = location.SensorLocation; var creator = new SensorPlLine3Creator(sensorLocation, sensorValues); // call PlLine actual = creator.CreatePlLine(); //checks // start first segment Assert.That(actual.Points[0].X, Is.EqualTo(-0.0)); Assert.That(actual.Points[0].Z, Is.EqualTo(waterLevel)); // end of first segment (ends at DikeToeAtRiver) Assert.That(actual.Points[1].X, Is.EqualTo(xDikeToeAtRiver)); Assert.That(actual.Points[1].Z, Is.EqualTo(waterLevel)); } } [Test] public void CreatePlLine_Pl3and4_FirstSegmentShouldBeHorizontalEqualToWaterLevelSensor() { // setup const double xDikeToeAtRiver = 50.0; const double waterLevel = -0.25; var surfaceLine = new SurfaceLine2 { CharacteristicPoints = { GeometryMustContainPoint = true }, Geometry = new GeometryPointString() }; Location location = CreateConfiguredLocation("test", 1, 1); { location.AddSensorLocation(); location.SensorLocation.SourceTypePl3 = DataSourceTypeSensors.Sensor; location.SensorLocation.SourceTypePl1WaterLevelAtRiver = DataSourceTypeSensors.Sensor; location.SensorLocation.SourceTypePl1WaterLevelAtPolder = DataSourceTypeSensors.Sensor; // Assert.IsTrue(location.SensorData.IsValid()); surfaceLine.EnsurePointOfType(0.0, 0.0, CharacteristicPointType.SurfaceLevelOutside); surfaceLine.EnsurePointOfType(xDikeToeAtRiver, 0.0, CharacteristicPointType.DikeToeAtRiver); surfaceLine.EnsurePointOfType(80.0, 5.0, CharacteristicPointType.DikeTopAtRiver); surfaceLine.EnsurePointOfType(125, 5.0, CharacteristicPointType.DikeTopAtPolder); surfaceLine.EnsurePointOfType(140.0, 0.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.EnsurePointOfType(145.0, 0.0, CharacteristicPointType.ShoulderBaseInside); surfaceLine.EnsurePointOfType(190.0, 0.0, CharacteristicPointType.SurfaceLevelInside); location.SurfaceLine = surfaceLine; var sensor1 = new Sensor { ID = 1, Name = "Test1", Depth = -0.25, RelativeLocation = 50, PlLineMappings = new[] { PlLineType.Pl1 }, SensorType = SensorType.WaterLevel }; var sensor5 = new Sensor { ID = 5, Name = "Test5", Depth = -8, RelativeLocation = 90, PlLineMappings = new[] { PlLineType.Pl3 } }; var sensor6 = new Sensor { ID = 6, Name = "Test6", Depth = -8, RelativeLocation = 123.3, PlLineMappings = new[] { PlLineType.Pl3 } }; var sensor7 = new Sensor { ID = 7, Name = "Test7", Depth = -8, RelativeLocation = 180, PlLineMappings = new[] { PlLineType.Pl3 } }; var repository = new SensorRepository(location); repository.Add(sensor1); repository.Add(sensor5); repository.Add(sensor6); repository.Add(sensor7); IDictionary sensorValues = new Dictionary { { sensor1, waterLevel }, { sensor5, 1 }, { sensor6, 1 }, { sensor7, 1 } }; SensorLocation sensorLocation = location.SensorLocation; var creator = new SensorPlLine3Creator(sensorLocation, sensorValues); // call PlLine actual = creator.CreatePlLine(); //checks // start first segment Assert.That(actual.Points[0].X, Is.EqualTo(-0.0)); Assert.That(actual.Points[0].Z, Is.EqualTo(waterLevel)); // end of first segment (ends at DikeToeAtRiver) Assert.That(actual.Points[1].X, Is.EqualTo(xDikeToeAtRiver)); Assert.That(actual.Points[1].Z, Is.EqualTo(waterLevel)); } } [TestCase(8.001)] [TestCase(10.0)] public void CreatePlLine_Pl1WithRiverLevelHigherThanDikeTopAtRiverSide_Throws(double riverLevel) { // setup SetUpSensorData(riverLevel, out IDictionary sensorValues, out SensorLocation sensorLocation); var creator = new SensorPlLine1Creator(sensorLocation, sensorValues); // call Assert.That(() => creator.CreatePlLine(), Throws.TypeOf(typeof(SurfaceLineException)).With.Message.Contains("should NOT be higher than dike top at river side")); } [TestCase(-0.001)] [TestCase(-10.0)] public void CreatePlLine_Pl1WithRiverLevelBelowDikeToeAtRiver_DoesNotThrow(double riverLevel) { // setup SetUpSensorData(riverLevel, out IDictionary sensorValues, out SensorLocation sensorLocation); var creator = new SensorPlLine1Creator(sensorLocation, sensorValues); // call Assert.DoesNotThrow(() => creator.CreatePlLine()); } private Location CreateConfiguredLocation(string name, double riverLevel, double polderLevel) { var location = new Location(name); var scenario = new DesignScenario { PolderLevel = polderLevel, RiverLevel = riverLevel }; location.Scenarios.Add(scenario); location.CurrentScenario = scenario; return location; } private void SetUpSensorData(double riverLevel, out IDictionary sensorValues, out SensorLocation sensorLocation) { var surfaceLine = new SurfaceLine2 { CharacteristicPoints = { GeometryMustContainPoint = true }, Geometry = new GeometryPointString() }; Location location = CreateConfiguredLocation("test", riverLevel, -1); location.AddSensorLocation(); location.SensorLocation.SourceTypePl1PlLineOffsetBelowDikeToeAtPolder = DataSourceTypeSensors.LocationData; surfaceLine.EnsurePointOfType(0.0, 0.0, CharacteristicPointType.SurfaceLevelOutside); surfaceLine.EnsurePointOfType(50.0, 0.0, CharacteristicPointType.DikeToeAtRiver); surfaceLine.EnsurePointOfType(85.0, 8.0, CharacteristicPointType.DikeTopAtRiver); surfaceLine.EnsurePointOfType(95.0, 8.0, CharacteristicPointType.DikeTopAtPolder); surfaceLine.EnsurePointOfType(108.0, 4.0, CharacteristicPointType.ShoulderBaseInside); surfaceLine.EnsurePointOfType(116.0, 3.0, CharacteristicPointType.ShoulderTopInside); surfaceLine.EnsurePointOfType(121.0, 0.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.EnsurePointOfType(190.0, 0.0, CharacteristicPointType.SurfaceLevelInside); location.SurfaceLine = surfaceLine; var sensor1 = new Sensor { ID = 1, Name = "Test1", Depth = 2, RelativeLocation = 50, PlLineMappings = new[] { PlLineType.Pl1 }, SensorType = SensorType.WaterLevel }; var sensor2 = new Sensor { ID = 2, Name = "Test2", Depth = 2, RelativeLocation = 90, PlLineMappings = new[] { PlLineType.Pl1 } }; var sensor3 = new Sensor { ID = 3, Name = "Test3", Depth = 2, RelativeLocation = 104, PlLineMappings = new[] { PlLineType.Pl1 } }; var sensor4 = new Sensor { ID = 4, Name = "Test4", Depth = 2, RelativeLocation = 123.3, PlLineMappings = new[] { PlLineType.Pl1 } }; var repository = new SensorRepository(location); repository.Add(sensor1); repository.Add(sensor2); repository.Add(sensor3); repository.Add(sensor4); sensorValues = new Dictionary { { sensor1, 1 }, { sensor2, 1 }, { sensor3, 1 }, { sensor4, 1 } }; sensorLocation = location.SensorLocation; } #region Setup [SetUp] public void FixtureSetup() {} [TearDown] public void FixtureTearDown() {} [SetUp] public void TestSetup() {} [TearDown] public void TestTearDown() {} #endregion }