Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/OrSpecification.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/OrSpecification.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/OrSpecification.cs (revision 1581)
@@ -0,0 +1,55 @@
+// 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.
+
+namespace Deltares.DamEngine.Data.General.Specifications
+{
+ public class OrSpecification : CompositeSpecification
+ {
+ private readonly ISpecification one;
+ private readonly ISpecification other;
+
+ public OrSpecification(ISpecification one, ISpecification other)
+ {
+ this.one = one;
+ this.other = other;
+ }
+
+ ///
+ /// Determines whether the candidate satisfies the specification.
+ ///
+ /// The candidate to test.
+ ///
+ /// true if the candidate satisfies the specification otherwise, false.
+ ///
+ public override bool IsSatisfiedBy(TCandidate candidate)
+ {
+ bool otherIsSatisfiedBy = other.IsSatisfiedBy(candidate);
+ bool thisIsSatisfiedBy = one.IsSatisfiedBy(candidate);
+
+ bool isSatisfied = (thisIsSatisfiedBy || otherIsSatisfiedBy);
+ if (!isSatisfied)
+ {
+ Description = "This " + one.Description + " AND " + other.Description + " are not satisfied";
+ }
+ return isSatisfied;
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/UniqueNameProvider.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/UniqueNameProvider.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/UniqueNameProvider.cs (revision 1581)
@@ -0,0 +1,128 @@
+// 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.Collections;
+using System.Collections.Generic;
+
+namespace Deltares.DamEngine.Data.Standard
+{
+ public class UniqueNameProvider
+ {
+ private static List collections = new List();
+
+ static UniqueNameProvider()
+ {
+ }
+
+ public static void Clear()
+ {
+ UniqueNameProvider.collections.Clear();
+ }
+
+ public static void Register(params IList[] lists)
+ {
+ foreach (IList list in lists)
+ {
+ if (!UniqueNameProvider.collections.Contains(list))
+ UniqueNameProvider.collections.Add(list);
+ }
+ }
+
+ public static void ProvideUniqueName(IList collection, IName item, Func translator = null)
+ {
+ if (string.IsNullOrEmpty(item.Name))
+ {
+ Type type = collection.GetType().GetGenericArgumentsFromFirstGenericSuperClass()[0];
+ item.Name = translator == null ? type.Name : translator(type.Name);
+ }
+ int indexer;
+ if (UniqueNameProvider.NameContainsIndexer(item.Name, out indexer))
+ {
+ string newName = item.Name;
+ while (UniqueNameProvider.NameExists(collection, item, newName))
+ newName = newName.Replace(string.Format("({0})", (object)indexer), string.Format("({0})", (object)++indexer));
+ item.Name = newName;
+ }
+ else
+ {
+ if (!string.IsNullOrWhiteSpace(item.Name) && !UniqueNameProvider.NameExists(collection, item, item.Name))
+ return;
+ string pattern = string.IsNullOrWhiteSpace(item.Name) ? "{0}" : item.Name + " ({0})";
+ int index = 1;
+ while (UniqueNameProvider.NameExists(collection, item, string.Format(pattern, (object)index)))
+ ++index;
+ item.Name = string.Format(pattern, (object)index);
+ }
+ }
+
+ private static bool NameContainsIndexer(string originalName, out int indexer)
+ {
+ indexer = -1;
+ if (string.IsNullOrEmpty(originalName))
+ return false;
+ string str = originalName.TrimEnd();
+ int num1 = str.LastIndexOf("(", StringComparison.Ordinal);
+ int num2 = str.LastIndexOf(")", StringComparison.Ordinal);
+ if (num1 < 0 || num2 < 0 || num1 > num2)
+ return false;
+ int startIndex = num1 + 1;
+ return int.TryParse(str.Substring(startIndex, num2 - startIndex), out indexer);
+ }
+
+ public static string ProvideNewUniqueName(IList collection, string item, Func translator = null)
+ {
+ if (string.IsNullOrEmpty(item))
+ {
+ Type type = collection.GetType().GetGenericArgumentsFromFirstGenericSuperClass()[0];
+ item = translator == null ? type.Name : translator(type.Name);
+ }
+ if (string.IsNullOrWhiteSpace(item) || UniqueNameProvider.NameExists(collection, item))
+ {
+ string format = string.IsNullOrWhiteSpace(item) ? "{0}" : item + " ({0})";
+ int num = 0;
+ for (item = string.Format(format, (object)num); UniqueNameProvider.NameExists(collection, item); item = string.Format(format, (object)num))
+ ++num;
+ }
+ return item;
+ }
+
+ private static bool NameExists(IList list, IName excludedItem, string newName)
+ {
+ foreach (IName name in (IEnumerable)list)
+ {
+ if (name != excludedItem && name.Name == newName)
+ return true;
+ }
+ return false;
+ }
+
+ private static bool NameExists(IList list, string excludedItem)
+ {
+ foreach (IName name in (IEnumerable)list)
+ {
+ if (name.Name == excludedItem)
+ return true;
+ }
+ return false;
+ }
+ }
+}
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLineCreator.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLineCreator.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLineCreator.cs (revision 1581)
@@ -0,0 +1,147 @@
+// 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.Collections.Generic;
+using System.Linq;
+using Deltares.DamEngine.Data.General;
+using Deltares.DamEngine.Data.General.PlLines;
+using Deltares.DamEngine.Data.General.Sensors;
+
+namespace Deltares.DamEngine.Calculators.PlLinesCreator
+{
+ internal class SensorPlLineCreator
+ {
+ ///
+ /// Creates an instance of a SensorPlLineCreator for Pl1. Pl3, Pl4.
+ ///
+ /// The sensor location.
+ /// The sensor values.
+ ///
+ public static SensorPlLineCreator CreateInstance(SensorLocation sensorLocation, IDictionary sensorValues)
+ {
+ return CreateInstance(sensorLocation, sensorValues, new[] {PlLineType.Pl1, PlLineType.Pl3, PlLineType.Pl4,});
+ }
+
+ ///
+ /// Creates an instance of a SensorPlLineCreator.
+ ///
+ /// The sensor location.
+ /// The sensor values.
+ ///
+ ///
+ public static SensorPlLineCreator CreateInstance(SensorLocation sensorLocation, IDictionary sensorValues, IEnumerable lineTypes)
+ {
+ IPlLineCreator c1 = new SensorPlLine1Creator(sensorLocation, sensorValues);
+ IPlLineCreator c3 = new SensorPlLine3Creator(sensorLocation, sensorValues);
+ IPlLineCreator c4 = new SensorPlLine4Creator(sensorLocation, sensorValues);
+
+ var tuples = new List>();
+ foreach (var lineType in lineTypes)
+ {
+ switch(lineType)
+ {
+ case PlLineType.Pl1:
+ tuples.Add(new Tuple(lineType, c1));
+ break;
+ case PlLineType.Pl2:
+ // ignore
+ break;
+ case PlLineType.Pl3:
+ tuples.Add(new Tuple(lineType, c3));
+ break;
+ case PlLineType.Pl4:
+ tuples.Add(new Tuple(lineType, c4));
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ if (!lineTypes.Contains(PlLineType.Pl3) && sensorLocation.Pl3 == DataSourceTypeSensors.LocationData)
+ {
+ tuples.Add(new Tuple(PlLineType.Pl3, c3));
+ }
+
+ if (!lineTypes.Contains(PlLineType.Pl4) && sensorLocation.Pl4 == DataSourceTypeSensors.LocationData)
+ {
+ tuples.Add(new Tuple(PlLineType.Pl4, c4));
+ }
+
+ return new SensorPlLineCreator(tuples);
+ }
+
+ private readonly IDictionary creators = new Dictionary();
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The 'concrete' creator.
+ /// The type.
+ public SensorPlLineCreator(IPlLineCreator creator, PlLineType type)
+ {
+ this.creators.Add(type, creator);
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The 'concrete' creators.
+ public SensorPlLineCreator(IEnumerable> creators)
+ {
+ foreach (var creator in creators)
+ {
+ this.creators.Add(creator.Item1, creator.Item2);
+ }
+ }
+
+ ///
+ /// Creates all PL lines.
+ ///
+ /// A PlLines set
+ public PlLines CreateAllPlLines()
+ {
+ var lines = new PlLines();
+ foreach (var item in creators)
+ {
+ IPlLineCreator creator = item.Value;
+ PlLine PlLine = creator.CreatePlLine();
+ lines.Lines[PlLine.PlLineType] = PlLine;
+ }
+
+ return lines;
+ }
+
+ ///
+ /// Creates a PL line of the given type.
+ ///
+ /// The type of the PL line.
+ /// A PlLine instance
+ public PlLine CreatePlLine(PlLineType type)
+ {
+ if (!creators.ContainsKey(type) || creators[type] == null)
+ throw new NotSupportedException("Creation of type " + type + " currently not supported");
+
+ return creators[type].CreatePlLine();
+ }
+ }
+
+}
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/Specifications/DitchWaterLevelSensorSpecification.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/Specifications/DitchWaterLevelSensorSpecification.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/Specifications/DitchWaterLevelSensorSpecification.cs (revision 1581)
@@ -0,0 +1,46 @@
+// 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 Deltares.DamEngine.Data.General.Specifications;
+
+namespace Deltares.DamEngine.Data.General.Sensors.Specifications
+{
+ public class DitchWaterLevelSensorSpecification : PredicateSpecification
+ {
+ private readonly double xDitchDikeSide;
+ private readonly double xDitchPolderSide;
+
+ public DitchWaterLevelSensorSpecification(double xDitchDikeSide, double xDitchPolderSide) :
+ base(s => s.Type == SensorType.PolderLevel)
+ {
+ this.xDitchDikeSide = xDitchDikeSide;
+ this.xDitchPolderSide = xDitchPolderSide;
+ }
+
+ public override bool IsSatisfiedBy(Sensor candidate)
+ {
+ if (base.IsSatisfiedBy(candidate))
+ return true;
+
+ return candidate.RelativeLocation > xDitchDikeSide && candidate.RelativeLocation < xDitchPolderSide;
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/Deltares.DamEngine.Calculators.Tests.csproj
===================================================================
diff -u -r1497 -r1581
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/Deltares.DamEngine.Calculators.Tests.csproj (.../Deltares.DamEngine.Calculators.Tests.csproj) (revision 1497)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/Deltares.DamEngine.Calculators.Tests.csproj (.../Deltares.DamEngine.Calculators.Tests.csproj) (revision 1581)
@@ -70,6 +70,9 @@
+
+
+
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/CompositeSpecification.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/CompositeSpecification.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/CompositeSpecification.cs (revision 1581)
@@ -0,0 +1,117 @@
+// 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.
+
+
+namespace Deltares.DamEngine.Data.General.Specifications
+{
+ public abstract class CompositeSpecification : SpecificationBase
+ {
+ #region Operator overloads
+
+ ///
+ /// Implements the operator true.
+ ///
+ /// The specification.
+ ///
+ /// The result of the operator.
+ ///
+ public static bool operator true(CompositeSpecification specification)
+ {
+ return false;
+ }
+
+ ///
+ /// Implements the operator false.
+ ///
+ /// The specification.
+ ///
+ /// The result of the operator.
+ ///
+ public static bool operator false(CompositeSpecification specification)
+ {
+ return false;
+ }
+
+ ///
+ /// Implements the operator &.
+ ///
+ /// The left.
+ /// The right.
+ ///
+ /// The result of the operator.
+ ///
+ public static CompositeSpecification operator &(CompositeSpecification left, CompositeSpecification right)
+ {
+ return new AndSpecification(left, right);
+ }
+
+ ///
+ /// Ands the specified other.
+ ///
+ /// The other.
+ ///
+ public CompositeSpecification And(ISpecification other)
+ {
+ return new AndSpecification(this, other);
+ }
+
+ ///
+ /// Implements the operator |.
+ ///
+ /// The left.
+ /// The right.
+ ///
+ /// The result of the operator.
+ ///
+ public static CompositeSpecification operator |(CompositeSpecification left, CompositeSpecification right)
+ {
+ return new AndSpecification(left, right);
+ }
+
+ public OrSpecification Or(ISpecification other)
+ {
+ return new OrSpecification(this, other);
+ }
+
+ ///
+ /// Implements the operator !.
+ ///
+ /// The specification.
+ ///
+ /// The result of the operator.
+ ///
+ public static CompositeSpecification operator !(CompositeSpecification specification)
+ {
+ return new NotSpecification(specification);
+ }
+
+ ///
+ /// Nots this instance.
+ ///
+ ///
+ public NotSpecification Not()
+ {
+ return new NotSpecification(this);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLine1Creator.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLine1Creator.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLine1Creator.cs (revision 1581)
@@ -0,0 +1,375 @@
+// 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.Collections.Generic;
+using System.Linq;
+using Deltares.DamEngine.Data.General;
+using Deltares.DamEngine.Data.General.PlLines;
+using Deltares.DamEngine.Data.General.Sensors;
+using Deltares.DamEngine.Data.General.Sensors.Specifications;
+using Deltares.DamEngine.Data.General.Specifications.Extensions;
+using Deltares.DamEngine.Data.Geometry;
+using Deltares.DamEngine.Data.Geotechnics;
+
+namespace Deltares.DamEngine.Calculators.PlLinesCreator
+{
+ internal class SensorPlLine1Creator : SensorPlLineCreatorBase
+ {
+ public SensorPlLine1Creator(SensorLocation sensorLocation, IDictionary sensorValues)
+ : base(sensorLocation, PlLineType.Pl1, sensorValues)
+ {
+ }
+
+ ///
+ /// Creates the PL line.
+ ///
+ ///
+ public override PlLine CreatePlLine()
+ {
+ var lineConstructor = new PlLineConstructor();
+
+ double waterLevel = 0;
+ try
+ {
+ waterLevel = WaterLevelAtRiver;
+ }
+ catch (Exception e)
+ {
+ throw new PlLinesCreatorException("There was an error trying to read the water level", e);
+ }
+
+ // Make sure there is an intersection with the surfaceline
+ waterLevel = this.SensorLocation.SurfaceLine.EnsureWaterLevelIsAboveRiverBottom(waterLevel).Value;
+
+ // Add begin boundary
+ lineConstructor.Insert(new PlLinePoint(XBeginBoundary, waterLevel));
+
+
+ // add all sensors to the pl line
+ var sortedSensors = SensorsSortedAlongProfile.ToList();
+ double lastZ = waterLevel;
+ double lastX = XBeginBoundary;
+ foreach (Sensor sensor in sortedSensors)
+ {
+ var x = lastX = GetSensorXValue(sensor);
+ var z = lastZ = GetSensorZValue(sensor);
+
+ var point = new PlLinePoint(x, z) { Name = sensor.Name };
+ lineConstructor.Insert(point);
+ }
+
+ // insert intersection point (at dike river side)
+ var xIntersection = IntersectionXAtRiverWaterLevel(waterLevel);
+ lineConstructor.Insert(new PlLinePoint(xIntersection, waterLevel) { Name = "Intersection point dike river side" });
+
+ // insert offset below dike top at river point?
+ var useLocationAsDataSource = new UseLocationAsDataSource();
+ if (useLocationAsDataSource.IsSatisfiedBy(SensorLocation.Pl1PlLineOffsetBelowDikeTopAtRiver))
+ {
+ double offset = waterLevel - SensorLocation.PlLineOffsetBelowDikeTopAtRiver;
+ lineConstructor.Insert(new PlLinePoint(XDikeTopAtRiver, offset));
+ }
+
+ // insert offset below dike top at polder point?
+ if (useLocationAsDataSource.IsSatisfiedBy(SensorLocation.Pl1PlLineOffsetBelowDikeTopAtPolder))
+ {
+ double offset = waterLevel - SensorLocation.PlLineOffsetBelowDikeTopAtPolder;
+ var x = XDikeTopAtPolder;
+ lineConstructor.Insert(new PlLinePoint(x, offset));
+ }
+
+ // insert offset below shoulder base inside?
+ if (useLocationAsDataSource.IsSatisfiedBy(SensorLocation.Pl1PlLineOffsetBelowShoulderBaseInside))
+ {
+ double offset = lastZ = ZShouldeBaseInside - SensorLocation.PlLineOffsetDryBelowShoulderBaseInside;
+ lineConstructor.Insert(new PlLinePoint(XShoulderBaseInside, offset));
+ }
+
+ // insert offset below dike toe at river?
+ if (useLocationAsDataSource.IsSatisfiedBy(SensorLocation.Pl1PlLineOffsetBelowDikeToeAtPolder))
+ {
+ double offset = lastZ = ZDikeToeAtPolder - SensorLocation.PlLineOffsetBelowDikeToeAtPolder;
+ var x = XDikeToeAtPolder;
+ lineConstructor.Insert(new PlLinePoint(x, offset));
+
+ if (lastX < x) lastX = x;
+ }
+
+ if (DikeHasDitch)
+ {
+ var ditchWaterLevelSensor = SensorLocation.Sensors
+ .GetBySpecification(new DitchWaterLevelSensorSpecification(SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide).X, SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide).X))
+ .FirstOrDefault();
+
+ var polderLevel = ditchWaterLevelSensor != null ? SensorValues[ditchWaterLevelSensor] : PolderLevel;
+
+ double? intersection = GetDitchWaterLevelIntersectionAtXDikeSide(polderLevel);
+ if (intersection != null)
+ {
+ lineConstructor.Insert(new PlLinePoint(intersection.Value, polderLevel));
+ double? intersectionPolderSide = GetDitchWaterLevelIntersectionAtXPolderSide(polderLevel);
+ if (intersectionPolderSide != null)
+ lineConstructor.Insert(new PlLinePoint(intersectionPolderSide.Value, polderLevel));
+ }
+
+ lineConstructor.Insert(new PlLinePoint(XEndBoundary, polderLevel));
+ }
+ else
+ {
+ double depth = lastZ;
+ double xLocation = XDikeToeAtPolder;
+ if (useLocationAsDataSource.IsSatisfiedBy(SensorLocation.Pl1PlLineOffsetBelowDikeToeAtPolder))
+ {
+ depth = ZDikeToeAtPolder - SensorLocation.PlLineOffsetBelowDikeToeAtPolder;
+
+ }
+ else
+ {
+ var sensor = PolderLevelSensor;
+ if (sensor != null)
+ {
+ xLocation = sensor.RelativeLocation;
+ depth = PolderLevel;
+ }
+ }
+ lineConstructor.Insert(new PlLinePoint(xLocation, depth));
+
+ // always continue horiontal to end
+ lineConstructor.Insert(new PlLinePoint(XEndBoundary, depth));
+
+ /*
+ * TODO: verify with Kin Sun
+ else if (lastZ <= PolderLevel)
+ {
+ lineConstructor.Insert(new PlLinePoint(XEndBoundary, lastZ));
+ }
+ else
+ {
+
+ // add tail of surface line
+ foreach (GeometryPoint geometryPoint in SensorLocation.SurfaceLine.GetSurfaceLineTailExcluding(lastX))
+ {
+ lineConstructor.Insert(new PlLinePoint(geometryPoint.X, geometryPoint.Z) { Name = geometryPoint.Name });
+ }
+ }
+ */
+ }
+
+ return lineConstructor.CreatePlLine(PlLineType);
+ }
+
+ ///
+ /// Gets the Polders the level intersection at X dike side.
+ ///
+ /// The polder level.
+ ///
+ public double? GetDitchWaterLevelIntersectionAtXDikeSide(double level)
+ {
+ var ditchDikeSide = SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide);
+ if (ditchDikeSide == null)
+ throw new PlLinesCreatorException("Ditch at dike side is not defined in surface line, but was expected");
+
+ var ditchPolderSide = SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide);
+ if (ditchPolderSide == null)
+ throw new PlLinesCreatorException("Ditch at polder side is not defined in surface line, but was expected");
+
+ var ditchBottomDikeSide = SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchDikeSide);
+ if (ditchBottomDikeSide == null)
+ throw new PlLinesCreatorException("Ditch at bottom polder side is not defined in surface line, but was expected");
+
+ var waterlevelLine = new Line();
+
+ double startX = SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelOutside).X;
+ double endX = SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside).X;
+ var waterLevelBeginPoint = new Point2D(startX, level);
+ var waterLevelEndPoint = new Point2D(endX, level);
+ waterlevelLine.SetBeginAndEndPoints(waterLevelBeginPoint, waterLevelEndPoint);
+
+ var surfaceLineSegment = new Line();
+ var beginPoint = new Point2D(ditchDikeSide.X, ditchDikeSide.Z);
+ var endPoint = new Point2D(ditchBottomDikeSide.X, ditchBottomDikeSide.Z);
+ surfaceLineSegment.SetBeginAndEndPoints(beginPoint, endPoint);
+
+ Point2D intersectPoint = surfaceLineSegment.GetIntersectPointXz(waterlevelLine);
+ if (intersectPoint != null)
+ {
+ return intersectPoint.X;
+ }
+
+ return null;
+ }
+
+ public double? GetDitchWaterLevelIntersectionAtXPolderSide(double level)
+ {
+ var ditchDikeSide = SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide);
+ if (ditchDikeSide == null)
+ throw new PlLinesCreatorException("Ditch at dike side is not defined in surface line, but was expected");
+
+ var ditchPolderSide = SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide);
+ if (ditchPolderSide == null)
+ throw new PlLinesCreatorException("Ditch at polder side is not defined in surface line, but was expected");
+
+ var ditchBottomPolderSide = SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchPolderSide);
+ if (ditchBottomPolderSide == null)
+ throw new PlLinesCreatorException("Ditch at bottom polder side is not defined in surface line, but was expected");
+
+ var waterlevelLine = new Line();
+
+ double startX = SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelOutside).X;
+ double endX = SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside).X;
+ var waterLevelBeginPoint = new Point2D(startX, level);
+ var waterLevelEndPoint = new Point2D(endX, level);
+ waterlevelLine.SetBeginAndEndPoints(waterLevelBeginPoint, waterLevelEndPoint);
+
+ var surfaceLineSegment = new Line();
+ var beginPoint = new Point2D(ditchPolderSide.X, ditchPolderSide.Z);
+ var endPoint = new Point2D(ditchBottomPolderSide.X, ditchBottomPolderSide.Z);
+ surfaceLineSegment.SetBeginAndEndPoints(beginPoint, endPoint);
+
+ Point2D intersectPoint = surfaceLineSegment.GetIntersectPointXz(waterlevelLine);
+ if (intersectPoint != null)
+ {
+ return intersectPoint.X;
+ }
+
+ return null;
+ }
+
+ ///
+ /// Gets the water level at river.
+ ///
+ protected double WaterLevelAtRiver
+ {
+ get
+ {
+ Sensor sensor = null;
+ try
+ {
+ // use single, because there should be exactly one waterlevel sensor
+ sensor = WaterLevelSensor;
+ }
+ catch (Exception e)
+ {
+ throw new PlLinesCreatorException("There are multiple or no water level sensors defined.", e);
+ }
+
+ var value = SensorLocation.GetValue(x => x.Pl1WaterLevelAtRiver, SensorValues, sensor);
+ if (value.HasValue)
+ return value.Value;
+
+ var message = string.Format("Water level at river for the location '{0}' was not set or initialized", SensorLocation.LocationName);
+ throw new PlLinesCreatorException(message);
+ }
+ }
+
+ ///
+ /// Gets the polder level.
+ ///
+ public double PolderLevel
+ {
+ get
+ {
+ var sensor = PolderLevelSensor;
+ if (sensor != null)
+ {
+ var value = SensorLocation.GetValue(x => x.Pl1WaterLevelAtPolder, SensorValues, sensor);
+ if (value.HasValue)
+ return value.Value;
+
+ var message = string.Format("Polder level at river for the location '{0}' was not set or initialized", SensorLocation.LocationName);
+ throw new PlLinesCreatorException(message);
+ }
+ else
+ {
+ return SensorLocation.PolderLevel;
+ }
+ }
+ }
+
+ ///
+ /// Gets the X dike top at river.
+ ///
+ public double XDikeTopAtRiver
+ {
+ get { return SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).X; }
+ }
+
+ ///
+ /// Gets the X dike top at polder.
+ ///
+ public double XDikeTopAtPolder
+ {
+ get { return SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X; }
+ }
+
+ ///
+ /// Gets the X dike toe at polder.
+ ///
+ public double XDikeToeAtPolder
+ {
+ get { return SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X; }
+ }
+
+ ///
+ /// Gets the X shoulder base inside.
+ ///
+ public double XShoulderBaseInside
+ {
+ get { return SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside).X; }
+ }
+
+ ///
+ /// Gets the Z shoulde base inside.
+ ///
+ public double ZShouldeBaseInside
+ {
+ get { return SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside).Z; }
+ }
+
+ ///
+ /// Gets the Z dike toe at polder.
+ ///
+ public double ZDikeToeAtPolder
+ {
+ get { return SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; }
+ }
+
+ ///
+ /// Gets the index of the insert position for a given value x in the line of points
+ ///
+ /// The line.
+ /// The x value.
+ ///
+ private int GetIndexOf(PlLine line, double xValue)
+ {
+ int index = 0;
+ foreach (var point in line.Points)
+ {
+ if (xValue > point.X)
+ index++;
+ else
+ break;
+ }
+ return index;
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/PlLinesCreator/PlLinesCreatorTest.cs
===================================================================
diff -u -r1122 -r1581
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/PlLinesCreator/PlLinesCreatorTest.cs (.../PlLinesCreatorTest.cs) (revision 1122)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/PlLinesCreator/PlLinesCreatorTest.cs (.../PlLinesCreatorTest.cs) (revision 1581)
@@ -386,7 +386,7 @@
}
};
{
- Calculators.PlLinesCreator.PlLinesCreator plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator{SurfaceLine = surfaceLine};
+ Calculators.PlLinesCreator.PlLinesCreator plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SurfaceLine = surfaceLine };
Assert.IsNotNull(plLineCreator);
plLineCreator.SoilProfile = FactoryForSoilProfiles.CreateComplexProfile();
plLineCreator.WaterLevelRiverHigh = 4.0;
@@ -979,7 +979,7 @@
}
};
{
- Calculators.PlLinesCreator.PlLinesCreator plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator{SurfaceLine = surfaceLine};
+ Calculators.PlLinesCreator.PlLinesCreator plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SurfaceLine = surfaceLine };
plLineCreator.SoilProfile = FactoryForSoilProfiles.CreateClaySandProfile();
plLineCreator.SurfaceLine.AddCharacteristicPoint(new GeometryPoint(1.0, 2.0));
plLineCreator.SurfaceLine.AddCharacteristicPoint(new GeometryPoint(10.0, 2.0));
@@ -1022,7 +1022,7 @@
}
};
{
- Calculators.PlLinesCreator.PlLinesCreator plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator{SurfaceLine = surfaceLine};
+ Calculators.PlLinesCreator.PlLinesCreator plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SurfaceLine = surfaceLine };
plLineCreator.SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile();
plLineCreator.SurfaceLine.AddCharacteristicPoint(new GeometryPoint(1.0, 2.0));
plLineCreator.SurfaceLine.AddCharacteristicPoint(new GeometryPoint(10.0, 2.0));
@@ -1055,7 +1055,7 @@
}
};
{
- Calculators.PlLinesCreator.PlLinesCreator plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator{SurfaceLine = surfaceLine};
+ Calculators.PlLinesCreator.PlLinesCreator plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SurfaceLine = surfaceLine };
plLineCreator.SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile();
plLineCreator.SurfaceLine.AddCharacteristicPoint(new GeometryPoint(1.0, 2.0));
plLineCreator.SurfaceLine.AddCharacteristicPoint(new GeometryPoint(10.0, 2.0));
@@ -1663,7 +1663,7 @@
{
location
};
- var gauges = new List
+ var gauges = new List
{
new Gauge { Name = "G1", Location = locations[0], LocalX = 3.2 },
new Gauge { Name = "G2", Location = locations[0], LocalX = 12.4 }
@@ -1703,7 +1703,7 @@
{
location
};
- var gauges = new List
+ var gauges = new List
{
new Gauge { Name = "G1", Location = locations[0], LocalX = 15, Value = 4 },
new Gauge { Name = "G2", Location = locations[0], LocalX = 45, Value = 1 }
@@ -1764,7 +1764,7 @@
{
location
};
- var gauges = new List
+ var gauges = new List
{
new Gauge { Name = "G1", Location = locations[0], LocalX = 15, Value = 4 },
new Gauge { Name = "G2", Location = locations[0], LocalX = 20, Value = 2 },
@@ -1826,7 +1826,7 @@
{
location
};
- var gauges = new List
+ var gauges = new List
{
new Gauge { Name = "G1", Location = locations[0], LocalX = 15, Value = 6 },
new Gauge { Name = "G2", Location = locations[0], LocalX = 20, Value = 2 },
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Properties/AssemblyInfo.cs
===================================================================
diff -u -r1578 -r1581
--- DamEngine/trunk/src/Deltares.DamEngine.Data/Properties/AssemblyInfo.cs (.../AssemblyInfo.cs) (revision 1578)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/Properties/AssemblyInfo.cs (.../AssemblyInfo.cs) (revision 1581)
@@ -30,3 +30,4 @@
[assembly: InternalsVisibleTo("Deltares.DamEngine.Interface")]
[assembly: InternalsVisibleTo("Deltares.DamEngine.Interface.Tests")]
+[assembly: InternalsVisibleTo("Deltares.DamEngine.Calculators.Tests")]
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/SpecificationBaseAttribute.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/SpecificationBaseAttribute.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/SpecificationBaseAttribute.cs (revision 1581)
@@ -0,0 +1,93 @@
+// 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 Deltares.DamEngine.Data.Standard;
+
+namespace Deltares.DamEngine.Data.General.Specifications
+{
+ ///
+ /// Defines the abstract base class for the specification attributes
+ /// to derive more specific types from
+ ///
+ [AttributeUsage(AttributeTargets.Property | AttributeTargets.Property, Inherited = true, AllowMultiple = true)]
+ public abstract class SpecificationBaseAttribute : Attribute
+ {
+ private readonly ISpecification specification;
+
+ protected SpecificationBaseAttribute(Type specification, params object[] args)
+ {
+ if (args == null && !specification.HasDefaultConstructor())
+ throw new ArgumentException("The specification type should have a default constructor or supply ");
+
+ if (!typeof(ISpecification).IsAssignableFrom(specification))
+ throw new ArgumentException("The specification type should implement interface ISpecification");
+
+ this.specification = Activator.CreateInstance(specification, args) as ISpecification;
+ }
+
+ protected SpecificationBaseAttribute(Type specification) : this(specification, null)
+ {
+ }
+
+ ///
+ /// Gets or sets the name of the specification.
+ ///
+ /// If this property is not set, the name of the specification (when available) will be used
+ ///
+ /// The name.
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// Gets or sets the text in case the specification is not satisfied
+ ///
+ /// If this property is not set, the description of the specification (when available) will be used
+ ///
+ /// The not satisfied text.
+ ///
+ public string NotSatisfiedText { get; set; }
+
+
+ public string GroupName { get; set; }
+
+
+ // This is a positional argument
+
+ public ISpecification Specification
+ {
+ get { return this.specification; }
+ }
+ }
+
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
+ public sealed class SpecificationAttribute : SpecificationBaseAttribute
+ {
+ public SpecificationAttribute(Type specification, params object[] args)
+ : base(specification, args)
+ {
+ }
+
+ public SpecificationAttribute(Type specification) : base(specification)
+ {
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/Specifications/WaterLevelSensorSpecification.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/Specifications/WaterLevelSensorSpecification.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/Specifications/WaterLevelSensorSpecification.cs (revision 1581)
@@ -0,0 +1,34 @@
+// 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 Deltares.DamEngine.Data.General.Specifications;
+
+namespace Deltares.DamEngine.Data.General.Sensors.Specifications
+{
+ public class WaterLevelSensorSpecification : PredicateSpecification
+ {
+ public WaterLevelSensorSpecification() :
+ base(s => s.Type == SensorType.WaterLevel)
+ {
+ }
+ }
+
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/PlLinesCreator.cs
===================================================================
diff -u -r1289 -r1581
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/PlLinesCreator.cs (.../PlLinesCreator.cs) (revision 1289)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/PlLinesCreator.cs (.../PlLinesCreator.cs) (revision 1581)
@@ -22,7 +22,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Runtime.Serialization;
using Deltares.DamEngine.Calculators.General;
using Deltares.DamEngine.Calculators.Uplift;
using Deltares.DamEngine.Data.General;
@@ -258,7 +257,7 @@
///
private PlLine CreatePlLine2ByExpertKnowledge(double penetrationLength, double? headInPlLine2)
{
- PlLine plLine = null;
+ PlLine PlLine = null;
if (penetrationLength < 0.0)
{
@@ -267,7 +266,7 @@
if ((penetrationLength.AlmostEquals(0.0)) || (headInPlLine2 == null))
{
// No penetration, or no Head Pl2 defined, so empty pl-line will be returned
- plLine = new PlLine();
+ PlLine = new PlLine();
}
else
{
@@ -278,16 +277,16 @@
switch (SoilProfileType)
{
case SoilProfileType.ProfileType1D:
- plLine = CreatePlLine2ByExpertKnowledgeFor1DGeometry(penetrationLength, headInPlLine2);
+ PlLine = CreatePlLine2ByExpertKnowledgeFor1DGeometry(penetrationLength, headInPlLine2);
break;
case SoilProfileType.ProfileType2D:
case SoilProfileType.ProfileTypeStiFile:
- plLine = CreatePlLine2ByExpertKnowledgeFor2DGeometry(penetrationLength, headInPlLine2);
+ PlLine = CreatePlLine2ByExpertKnowledgeFor2DGeometry(penetrationLength, headInPlLine2);
break;
}
}
- return plLine;
+ return PlLine;
}
///
@@ -303,10 +302,10 @@
{
throw new PlLinesCreatorException("Head PL2 not defined");
}
- PlLine plLine = new PlLine();
- plLine.Points.Add(new PlLinePoint(this.surfaceLine.Geometry.Points.First().X, headInPlLine2.Value));
- plLine.Points.Add(new PlLinePoint(this.surfaceLine.Geometry.Points.Last().X, headInPlLine2.Value));
- return plLine;
+ PlLine PlLine = new PlLine();
+ PlLine.Points.Add(new PlLinePoint(this.surfaceLine.Geometry.Points.First().X, headInPlLine2.Value));
+ PlLine.Points.Add(new PlLinePoint(this.surfaceLine.Geometry.Points.Last().X, headInPlLine2.Value));
+ return PlLine;
}
///
@@ -321,7 +320,7 @@
{
throw new PlLinesCreatorException("Head PL2 not defined");
}
- PlLine plLine = new PlLine();
+ PlLine PlLine = new PlLine();
if (SoilProfile != null)
{
IList aquiferLayers = this.SoilProfile.GetAquiferLayers();
@@ -343,8 +342,8 @@
if (separationLevel <= infiltrationLayers.First().TopLevel)
{
- plLine.Points.Add(new PlLinePoint(this.surfaceLine.Geometry.Points.First().X, headInPlLine2.Value));
- plLine.Points.Add(new PlLinePoint(this.surfaceLine.Geometry.Points.Last().X, headInPlLine2.Value));
+ PlLine.Points.Add(new PlLinePoint(this.surfaceLine.Geometry.Points.First().X, headInPlLine2.Value));
+ PlLine.Points.Add(new PlLinePoint(this.surfaceLine.Geometry.Points.Last().X, headInPlLine2.Value));
SoilLayer1D separationLayer = (from SoilLayer1D layer in infiltrationLayers
where layer.TopLevel >= separationLevel
@@ -365,7 +364,7 @@
this.SoilProfile.DetermineInfiltrationLayer(penetrationLength);
}
}
- return plLine;
+ return PlLine;
}
///
@@ -408,12 +407,12 @@
return CreatePlLine3Or4ByExpertKnowledge(headValue, dampingFactor, PlLineType.Pl4, slopeGradient);
}
- private PlLine CreatePlLine3Or4ByExpertKnowledge(double headValue, double dampingFactor, PlLineType plLineType, double slopeGradient)
+ private PlLine CreatePlLine3Or4ByExpertKnowledge(double headValue, double dampingFactor, PlLineType PlLineType, double slopeGradient)
{
// Offset to solve issue MWDAM-557
const double offset = 0.01;
- PlLine plLine = new PlLine();
+ PlLine PlLine = new PlLine();
ThrowIfInsufficientSoilGeometryData();
ThrowIfNoSurfaceLine();
@@ -432,51 +431,51 @@
throw new PlLinesCreatorException("Damping factor < 0.0");
}
- var relevantAquiferLayer = GetRelevantAquiferLayer(plLineType, actualSoilProfile);
+ var relevantAquiferLayer = GetRelevantAquiferLayer(PlLineType, actualSoilProfile);
if (relevantAquiferLayer != null)
{
double referenceLevel = (this.HeadInPlLine2 != null) ? this.HeadInPlLine2.Value : this.waterLevelPolder;
double headAtPolderDikeToe = headValue - Math.Max(0, dampingFactor * (headValue - referenceLevel));
- plLine.Points.Add(new PlLinePoint(this.surfaceLine.Geometry.Points.First().X, headValue));
- plLine.Points.Add(new PlLinePoint(this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).X, headValue));
- plLine.Points.Add(new PlLinePoint(this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X, headAtPolderDikeToe));
+ PlLine.Points.Add(new PlLinePoint(this.surfaceLine.Geometry.Points.First().X, headValue));
+ PlLine.Points.Add(new PlLinePoint(this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).X, headValue));
+ PlLine.Points.Add(new PlLinePoint(this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X, headAtPolderDikeToe));
- // Now continue PLline to the end with a slope of slopegradient
- AddTailOfPl3OrPl4WithSlopeGradient(slopeGradient, plLine);
+ // Now continue PlLine to the end with a slope of slopegradient
+ AddTailOfPl3OrPl4WithSlopeGradient(slopeGradient, PlLine);
if (isAdjustPl3AndPl4SoNoUpliftWillOccurEnabled)
{
- AdjustLineAccordingToTRWUplift(plLine, plLineType, slopeGradient);
+ AdjustLineAccordingToTRWUplift(PlLine, PlLineType, slopeGradient);
}
- EnsureDescendingLine(plLine);
+ EnsureDescendingLine(PlLine);
- RemoveRedundantPoints(plLine);
+ RemoveRedundantPoints(PlLine);
}
- return plLine;
+ return PlLine;
}
///
- /// Continue PLline to the end with a slope of slopegradient
+ /// Continue PlLine to the end with a slope of slopegradient
/// If PlLine is lower then polderlevel, continue with polderlevel
///
/// The slope gradient.
- /// The pl line.
- private void AddTailOfPl3OrPl4WithSlopeGradient(double slopeGradient, PlLine plLine)
+ /// The pl line.
+ private void AddTailOfPl3OrPl4WithSlopeGradient(double slopeGradient, PlLine PlLine)
{
- if (plLine.Points.Last().Z <= this.WaterLevelPolder)
+ if (PlLine.Points.Last().Z <= this.WaterLevelPolder)
{
// the PL line is already at WaterLevelPolder, so countinue it horizontally
- plLine.Points.Add(new PlLinePoint(this.surfaceLine.Geometry.Points.Last().X, this.WaterLevelPolder));
+ PlLine.Points.Add(new PlLinePoint(this.surfaceLine.Geometry.Points.Last().X, this.WaterLevelPolder));
}
else
{
- double lengthFromLastPlPointToEnd = Math.Abs(this.surfaceLine.Geometry.Points.Last().X - plLine.Points.Last().X);
- double headAtLastPlPoint = plLine.Points.Last().Z;
- double headAtEnd = plLine.Points.Last().Z - slopeGradient * lengthFromLastPlPointToEnd;
+ double lengthFromLastPlPointToEnd = Math.Abs(this.surfaceLine.Geometry.Points.Last().X - PlLine.Points.Last().X);
+ double headAtLastPlPoint = PlLine.Points.Last().Z;
+ double headAtEnd = PlLine.Points.Last().Z - slopeGradient * lengthFromLastPlPointToEnd;
Line waterLevelPolderLine =
new Line(new Point2D(this.surfaceLine.Geometry.Points.First().X, this.WaterLevelPolder),
@@ -489,12 +488,12 @@
if (waterLevelPolderLine.IntersectsZ(slopeLine, out intersectionPoint))
{
- plLine.Points.Add(new PlLinePoint(intersectionPoint.X, this.WaterLevelPolder));
- plLine.Points.Add(new PlLinePoint(this.surfaceLine.Geometry.Points.Last().X, this.WaterLevelPolder));
+ PlLine.Points.Add(new PlLinePoint(intersectionPoint.X, this.WaterLevelPolder));
+ PlLine.Points.Add(new PlLinePoint(this.surfaceLine.Geometry.Points.Last().X, this.WaterLevelPolder));
}
else
{
- plLine.Points.Add(new PlLinePoint(this.surfaceLine.Geometry.Points.Last().X, headAtEnd));
+ PlLine.Points.Add(new PlLinePoint(this.surfaceLine.Geometry.Points.Last().X, headAtEnd));
}
}
@@ -535,30 +534,30 @@
/// Remove redundant points (i.e. lying on a line between its both neighbours)
///
///
- ///
- private static void RemoveRedundantPoints(PlLine plLine)
+ ///
+ private static void RemoveRedundantPoints(PlLine PlLine)
{
const double Tolerance = 0.001;
- for (int pointIndex = plLine.Points.Count - 2; pointIndex > 0; pointIndex--)
+ for (int pointIndex = PlLine.Points.Count - 2; pointIndex > 0; pointIndex--)
{
- PlLinePoint plPointPrev = plLine.Points[pointIndex - 1];
- PlLinePoint plPoint = plLine.Points[pointIndex];
- PlLinePoint plPointNext = plLine.Points[pointIndex + 1];
+ PlLinePoint plPointPrev = PlLine.Points[pointIndex - 1];
+ PlLinePoint plPoint = PlLine.Points[pointIndex];
+ PlLinePoint plPointNext = PlLine.Points[pointIndex + 1];
if (Math.Abs((plPoint.Z - plPointPrev.Z) / (plPoint.X - plPointPrev.X) - (plPointNext.Z - plPoint.Z) / (plPointNext.X - plPoint.X)) < Tolerance)
{
- plLine.Points.Remove(plPoint);
+ PlLine.Points.Remove(plPoint);
}
}
}
///
/// All points should have descending z from dike to polder
///
- ///
- private static void EnsureDescendingLine(PlLine plLine)
+ ///
+ private static void EnsureDescendingLine(PlLine PlLine)
{
PlLinePoint plPointPrevious = null;
- foreach (PlLinePoint plPoint in plLine.Points)
+ foreach (PlLinePoint plPoint in PlLine.Points)
{
if (plPointPrevious != null && plPoint.Z > plPointPrevious.Z)
plPoint.Z = plPointPrevious.Z;
@@ -569,10 +568,10 @@
///
/// Clear outputvalues for PL3 or PL4
///
- ///
- private void ClearOutputValuesForPl3_4(PlLineType plLineType)
+ ///
+ private void ClearOutputValuesForPl3_4(PlLineType PlLineType)
{
- switch (plLineType)
+ switch (PlLineType)
{
case PlLineType.Pl3:
pl3MinUplift = Double.MaxValue;
@@ -590,13 +589,13 @@
///
/// Determine outputvalues for PL3 or PL4 for minimal upliftfactor
///
- /// Type of the pl line.
+ /// Type of the pl line.
/// The x coordinate.
/// The uplift factor.
/// The head value.
- private void UpdateOutputValuesForPl3_4(PlLineType plLineType, double xCoordinate, double upliftFactor, double headValue)
+ private void UpdateOutputValuesForPl3_4(PlLineType PlLineType, double xCoordinate, double upliftFactor, double headValue)
{
- switch (plLineType)
+ switch (PlLineType)
{
case PlLineType.Pl3:
if (upliftFactor < pl3MinUplift)
@@ -621,14 +620,14 @@
///
/// Finds the index of point with X coordinate.
///
- /// The pl line.
+ /// The pl line.
/// The x coordinate.
///
- private int FindIndexOfPointInPlLineWithXCoordinate(PlLine plLine, double x)
+ private int FindIndexOfPointInPlLineWithXCoordinate(PlLine PlLine, double x)
{
- for (int pointIndex = plLine.Points.Count - 1; pointIndex > 0; pointIndex--)
+ for (int pointIndex = PlLine.Points.Count - 1; pointIndex > 0; pointIndex--)
{
- PlLinePoint plPoint = plLine.Points[pointIndex];
+ PlLinePoint plPoint = PlLine.Points[pointIndex];
if (plPoint.X.AlmostEquals(x, GeometryPoint.Precision))
{
return pointIndex;
@@ -641,13 +640,13 @@
///
/// Removes the index of all points of pl line after the start index.
///
- /// The pl line.
+ /// The pl line.
/// The start index (this point will not be removed).
- private void RemoveAllPointsOfPlLineAfterIndex(PlLine plLine, int startIndex)
+ private void RemoveAllPointsOfPlLineAfterIndex(PlLine PlLine, int startIndex)
{
- for (int pointIndex = plLine.Points.Count - 1; pointIndex > startIndex; pointIndex--)
+ for (int pointIndex = PlLine.Points.Count - 1; pointIndex > startIndex; pointIndex--)
{
- plLine.Points.RemoveAt(pointIndex);
+ PlLine.Points.RemoveAt(pointIndex);
}
}
@@ -702,7 +701,7 @@
/// Make sure PL3 is always descending from left to right.
///
/// A better implementation (not implemented yet) would be:
- /// Correct plline 3 or 4 for uplift according to
+ /// Correct PlLine 3 or 4 for uplift according to
/// TRW (Technisch Rapport Waterspanningen bij dijken) par. b1.3.4 "Stijghoogte in het eerste watervoerende pakket"
/// - Adjust PL3/4 for all surface points from end of profile to toe of dike, so no uplift will occur in that surface point
/// - From the point, closest to the dike, (firstAdjustedPLPoint) where this correction has been made the following has to be done
@@ -713,13 +712,13 @@
/// \
/// \__________
///
- ///
- ///
+ ///
+ ///
///
- private void AdjustLineAccordingToTRWUplift(PlLine plLine, PlLineType plLineType, double slopeGradient)
+ private void AdjustLineAccordingToTRWUplift(PlLine PlLine, PlLineType PlLineType, double slopeGradient)
{
const double cTolerancePoint = 0.0001;
- ClearOutputValuesForPl3_4(plLineType);
+ ClearOutputValuesForPl3_4(PlLineType);
var upliftCalculator = new UpliftCalculator
{
@@ -728,7 +727,7 @@
};
GeometryPoint startSurfacePoint = this.surfaceLine.GetDikeToeInward();
- int indexOfFixedPlPoint = FindIndexOfPointInPlLineWithXCoordinate(plLine, this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).X);
+ int indexOfFixedPlPoint = FindIndexOfPointInPlLineWithXCoordinate(PlLine, this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).X);
if (indexOfFixedPlPoint < 0)
{
throw new PlLinesCreatorException("Could not find fixed point for PlLine");
@@ -754,14 +753,14 @@
{
continue;
}
- ConfigureUpliftCalculator(plLineType, upliftCalculator, surfacePoint);
- SoilLayer1D relevantSandLayer = GetRelevantAquiferLayer(plLineType, upliftCalculator.SoilProfile);
- // When plLineType is PL4 it is possible that no relevant aquifer layer is found, then the adjustment is not necessary
+ ConfigureUpliftCalculator(PlLineType, upliftCalculator, surfacePoint);
+ SoilLayer1D relevantSandLayer = GetRelevantAquiferLayer(PlLineType, upliftCalculator.SoilProfile);
+ // When PlLineType is PL4 it is possible that no relevant aquifer layer is found, then the adjustment is not necessary
if (relevantSandLayer != null)
{
double aquiferTopLayer = Math.Min(surfacePoint.Z, relevantSandLayer.TopLevel);
upliftCalculator.TopOfLayerToBeEvaluated = aquiferTopLayer;
- double headOfPlLine = plLine.ZFromX(surfacePoint.X);
+ double headOfPlLine = PlLine.ZFromX(surfacePoint.X);
double upliftFactor = upliftCalculator.CalculateUpliftFactor(headOfPlLine);
if (upliftFactor <= cUpliftFactorEquilibrium)
{
@@ -780,18 +779,18 @@
{
var plPoint = new PlLinePoint(surfacePoint.X, headOfPlLine);
// Remove all points of PlLine after fixed point
- RemoveAllPointsOfPlLineAfterIndex(plLine, indexOfFixedPlPoint);
- plLine.Points.Add(plPoint);
+ RemoveAllPointsOfPlLineAfterIndex(PlLine, indexOfFixedPlPoint);
+ PlLine.Points.Add(plPoint);
if (!isRemoveAllPlPointsBackToDikeToeAtRiver)
{
// To make sure that not all points of the PL-line back to the toe of the dike at riverside are to be removed
- indexOfFixedPlPoint = plLine.Points.Count - 1;
+ indexOfFixedPlPoint = PlLine.Points.Count - 1;
}
- AddTailOfPl3OrPl4WithSlopeGradient(slopeGradient, plLine);
+ AddTailOfPl3OrPl4WithSlopeGradient(slopeGradient, PlLine);
lastAdjustedHeadOfPlLine = headOfPlLine;
}
}
- UpdateOutputValuesForPl3_4(plLineType, surfacePoint.X, upliftFactor, headOfPlLine);
+ UpdateOutputValuesForPl3_4(PlLineType, surfacePoint.X, upliftFactor, headOfPlLine);
}
}
@@ -807,27 +806,27 @@
foreach (GeometryPoint surfacePoint in recheckSurfacePointsList)
{
- ConfigureUpliftCalculator(plLineType, upliftCalculator, surfacePoint);
- SoilLayer1D relevantSandLayer = GetRelevantAquiferLayer(plLineType, upliftCalculator.SoilProfile);
- // When plLineType is PL4 it is possible that no relevant aquifer layer is found, then the adjustment is not necessary
+ ConfigureUpliftCalculator(PlLineType, upliftCalculator, surfacePoint);
+ SoilLayer1D relevantSandLayer = GetRelevantAquiferLayer(PlLineType, upliftCalculator.SoilProfile);
+ // When PlLineType is PL4 it is possible that no relevant aquifer layer is found, then the adjustment is not necessary
if (relevantSandLayer != null)
{
double aquiferTopLayer = Math.Min(surfacePoint.Z, relevantSandLayer.TopLevel);
upliftCalculator.TopOfLayerToBeEvaluated = aquiferTopLayer;
- double headOfPlLine = plLine.ZFromX(surfacePoint.X);
+ double headOfPlLine = PlLine.ZFromX(surfacePoint.X);
double upliftFactor = upliftCalculator.CalculateUpliftFactor(headOfPlLine);
if (upliftFactor <= cUpliftFactorEquilibrium)
{
// Adjust headOfPlLine so there is equilibrium
headOfPlLine = Math.Max(upliftCalculator.CalculateHeadOfPlLine(cUpliftFactorEquilibrium), this.waterLevelPolder);
- double currentHead = plLine.ZFromX(surfacePoint.X);
+ double currentHead = PlLine.ZFromX(surfacePoint.X);
if (headOfPlLine < currentHead)
{
- PlLinePoint plPoint = plLine.EnsurePointAtX(surfacePoint.X, cTolerancePoint);
+ PlLinePoint plPoint = PlLine.EnsurePointAtX(surfacePoint.X, cTolerancePoint);
plPoint.Z = headOfPlLine;
}
}
- UpdateOutputValuesForPl3_4(plLineType, surfacePoint.X, upliftFactor, headOfPlLine);
+ UpdateOutputValuesForPl3_4(PlLineType, surfacePoint.X, upliftFactor, headOfPlLine);
}
}
}
@@ -836,10 +835,10 @@
///
/// Configures the uplift calculator.
///
- /// Type of the pl line.
+ /// Type of the pl line.
/// The uplift calculator.
/// The surface point.
- private void ConfigureUpliftCalculator(PlLineType plLineType, UpliftCalculator upliftCalculator, GeometryPoint surfacePoint)
+ private void ConfigureUpliftCalculator(PlLineType PlLineType, UpliftCalculator upliftCalculator, GeometryPoint surfacePoint)
{
// Offset to solve issue MWDAM-764
const double offset = 0.01;
@@ -919,14 +918,14 @@
///
///
///
- ///
+ ///
///
- void CopyPointsInPlLine(ref PlLine plLine, GeometryPointString genericLine)
+ void CopyPointsInPlLine(ref PlLine PlLine, GeometryPointString genericLine)
{
- plLine.Points.Clear();
+ PlLine.Points.Clear();
foreach (GeometryPoint point in genericLine.Points)
{
- plLine.Points.Add(new PlLinePoint(point.X, point.Z));
+ PlLine.Points.Add(new PlLinePoint(point.X, point.Z));
}
}
@@ -937,41 +936,41 @@
///
private PlLines CreateAllPlLinesWithExpertKnowledge(Location location)
{
- PlLines plLines = new PlLines();
- foreach (PlLineType plLineType in Enum.GetValues(typeof(PlLineType)))
+ PlLines PlLines = new PlLines();
+ foreach (PlLineType PlLineType in Enum.GetValues(typeof(PlLineType)))
{
bool isPL1LineDefinedForLocation = (location != null) && (location.LocalXzpl1Line != null) && (location.LocalXzpl1Line.Points.Count > 1);
- if ((plLineType == PlLineType.Pl1) && isPL1LineDefinedForLocation)
+ if ((PlLineType == PlLineType.Pl1) && isPL1LineDefinedForLocation)
{
- PlLine plLine = plLines.Lines[plLineType];
- CopyPointsInPlLine(ref plLine, location.LocalXzpl1Line);
+ PlLine PlLine = PlLines.Lines[PlLineType];
+ CopyPointsInPlLine(ref PlLine, location.LocalXzpl1Line);
}
else
{
- plLines.Lines[plLineType] = CreatePlLineByExpertKnowledge(plLineType, location.DamType, location.SlopeDampingPiezometricHeightPolderSide);
+ PlLines.Lines[PlLineType] = CreatePlLineByExpertKnowledge(PlLineType, location.DamType, location.SlopeDampingPiezometricHeightPolderSide);
}
// currentPL1Line is needed when calculating uplift reduction for PL3 and Pl4
- if (plLineType == PlLineType.Pl1)
+ if (PlLineType == PlLineType.Pl1)
{
- // var plLine = plLines.Lines[plLineType];
- // AdaptPL1ForNonWaterRetainingObject(ref plLine);
- // plLines.Lines[plLineType] = plLine;
- currentPL1Line = plLines.Lines[plLineType];
+ // var PlLine = PlLines.Lines[PlLineType];
+ // AdaptPL1ForNonWaterRetainingObject(ref PlLine);
+ // PlLines.Lines[PlLineType] = PlLine;
+ currentPL1Line = PlLines.Lines[PlLineType];
}
}
- return plLines;
+ return PlLines;
}
-// private IEnumerable FindAllPlLinePointsAtNWOLocation(PLLine pl1Line)
+// private IEnumerable FindAllPlLinePointsAtNWOLocation(PlLine pl1Line)
// {
-// IEnumerable results = pl1Line.GetPointSegmentBetween(this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint1).X - cOffsetPhreaticLineBelowSurface,
+// IEnumerable results = pl1Line.GetPointSegmentBetween(this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint1).X - cOffsetPhreaticLineBelowSurface,
// this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint4).X + cOffsetPhreaticLineBelowSurface);
//
// return results;
// }
-// private void AdaptPL1ForNonWaterRetainingObject(ref PLLine pl1Line)
+// private void AdaptPL1ForNonWaterRetainingObject(ref PlLine pl1Line)
// {
// // check if nwo points are available as CharacteristicPoints
// var nwo1 = this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint1);
@@ -982,52 +981,52 @@
// {
//
// // Find all points in the Pl line that (might) coincide with the NWO
-// IEnumerable plPointsToBeMoved = FindAllPlLinePointsAtNWOLocation(pl1Line);
+// IEnumerable plPointsToBeMoved = FindAllPlLinePointsAtNWOLocation(pl1Line);
//
-// PLLinePoint nwo1Pl = null;
-// PLLinePoint nwo2Pl = null;
-// PLLinePoint nwo3Pl = null;
-// PLLinePoint nwo4Pl = null;
+// PlLinePoint nwo1Pl = null;
+// PlLinePoint nwo2Pl = null;
+// PlLinePoint nwo3Pl = null;
+// PlLinePoint nwo4Pl = null;
//
// // For NWO point, determine whether a pl point has to be added
-// if (pl1Line.PositionXzOfPointRelatedToPLLine(nwo1) != PLLinePointPositionXzType.AbovePLLine)
+// if (pl1Line.PositionXzOfPointRelatedToPlLine(nwo1) != PlLinePointPositionXzType.AbovePlLine)
// {
-// nwo1Pl = new PLLinePoint(nwo1.X, nwo1.Z - cOffsetPhreaticLineBelowSurface);
+// nwo1Pl = new PlLinePoint(nwo1.X, nwo1.Z - cOffsetPhreaticLineBelowSurface);
// }
-// if (pl1Line.PositionXzOfPointRelatedToPLLine(nwo2) != PLLinePointPositionXzType.AbovePLLine)
+// if (pl1Line.PositionXzOfPointRelatedToPlLine(nwo2) != PlLinePointPositionXzType.AbovePlLine)
// {
-// nwo2Pl = new PLLinePoint(nwo2.X, nwo2.Z - cOffsetPhreaticLineBelowSurface);
+// nwo2Pl = new PlLinePoint(nwo2.X, nwo2.Z - cOffsetPhreaticLineBelowSurface);
// }
-// if (pl1Line.PositionXzOfPointRelatedToPLLine(nwo3) != PLLinePointPositionXzType.AbovePLLine)
+// if (pl1Line.PositionXzOfPointRelatedToPlLine(nwo3) != PlLinePointPositionXzType.AbovePlLine)
// {
-// nwo3Pl = new PLLinePoint(nwo3.X, nwo3.Z - cOffsetPhreaticLineBelowSurface);
+// nwo3Pl = new PlLinePoint(nwo3.X, nwo3.Z - cOffsetPhreaticLineBelowSurface);
// }
-// if (pl1Line.PositionXzOfPointRelatedToPLLine(nwo4) != PLLinePointPositionXzType.AbovePLLine)
+// if (pl1Line.PositionXzOfPointRelatedToPlLine(nwo4) != PlLinePointPositionXzType.AbovePlLine)
// {
-// nwo4Pl = new PLLinePoint(nwo4.X, nwo4.Z - cOffsetPhreaticLineBelowSurface);
+// nwo4Pl = new PlLinePoint(nwo4.X, nwo4.Z - cOffsetPhreaticLineBelowSurface);
// }
//
// // Find the intersections of pl line and NWO and handle these
-// // Intersection between nwo point1 and nwo point2 only when nwo point1 is above pl line and nwo point2 is below plLine
-// PLLinePoint intersection1 = null;
+// // Intersection between nwo point1 and nwo point2 only when nwo point1 is above pl line and nwo point2 is below PlLine
+// PlLinePoint intersection1 = null;
// if ((nwo1Pl == null) && (nwo2Pl != null))
// {
// var lineNWO = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo1.X, 0, nwo1.Z), EndPoint = new GeometryPoint(nwo2.X, 0, nwo2.Z) };
// var ips = pl1Line.IntersectionPointsXzWithLineXz(lineNWO);
// if (ips.Count > 0)
// {
-// intersection1 = new PLLinePoint(ips.First().X, ips.First().Z);
+// intersection1 = new PlLinePoint(ips.First().X, ips.First().Z);
// }
// }
-// // Intersection between nwo point3 and nwo point4 only when nwo point3 is below pl line and nwo point4 is above plLine
-// PLLinePoint intersection2 = null;
+// // Intersection between nwo point3 and nwo point4 only when nwo point3 is below pl line and nwo point4 is above PlLine
+// PlLinePoint intersection2 = null;
// if ((nwo3Pl != null) && (nwo4Pl == null))
// {
// var lineNWO = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo3.X, 0, nwo3.Z), EndPoint = new GeometryPoint(nwo4.X, 0, nwo4.Z) };
// var ips = pl1Line.IntersectionPointsXzWithLineXz(lineNWO);
// if (ips.Count > 0)
// {
-// intersection2 = new PLLinePoint(ips.Last().X, ips.Last().Z);
+// intersection2 = new PlLinePoint(ips.Last().X, ips.Last().Z);
// }
// }
//
@@ -1083,17 +1082,17 @@
// }
//
// // Move all the points in the pl line itself that need to be moved to the horizontal proper level.
-// foreach (var plLinePoint in plPointsToBeMoved)
+// foreach (var PlLinePoint in plPointsToBeMoved)
// {
-// plLinePoint.Z = requiredWaterLevel;
+// PlLinePoint.Z = requiredWaterLevel;
// }
// pl1Line.DeleteCoinsidingPoints(GeometryPoint.Precision);
// }
// }
// }
// }
-// private void MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection2And1(GeometryPoint nwo1, GeometryPoint nwo2, GeometryPoint nwo3, PLLine pl1Line, PLLinePoint nwo2Pl, PLLinePoint intersection1, PLLinePoint intersection2)
+// private void MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection2And1(GeometryPoint nwo1, GeometryPoint nwo2, GeometryPoint nwo3, PlLine pl1Line, PlLinePoint nwo2Pl, PlLinePoint intersection1, PlLinePoint intersection2)
// {
// var lineNWO = new Line { BeginPoint = new Point2D(nwo1.X, nwo1.Z), EndPoint = new Point2D(nwo2.X, nwo2.Z) };
// var linePL = new Line { BeginPoint = new Point2D(nwo1.X, intersection2.Z), EndPoint = new Point2D(intersection2.X, intersection2.Z) };
@@ -1127,12 +1126,12 @@
// }
// else
// {
-// throw new PLLinesCreatorException("Could not create the intersectionsection points between NWO and Phreatic line to create horizontal level.");
+// throw new PlLinesCreatorException("Could not create the intersectionsection points between NWO and Phreatic line to create horizontal level.");
// }
// }
// }
-// private void MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection1And2(GeometryPoint nwo2, GeometryPoint nwo3, GeometryPoint nwo4, PLLine pl1Line, PLLinePoint nwo3Pl, PLLinePoint intersection1, PLLinePoint intersection2)
+// private void MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection1And2(GeometryPoint nwo2, GeometryPoint nwo3, GeometryPoint nwo4, PlLine pl1Line, PlLinePoint nwo3Pl, PlLinePoint intersection1, PlLinePoint intersection2)
// {
// var lineNWO = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo3.X, 0, nwo3.Z), EndPoint = new GeometryPoint(nwo4.X, 0, nwo4.Z) };
// var linePL = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(intersection1.X, 0, intersection1.Z), EndPoint = new GeometryPoint(nwo4.X, 0, intersection1.Z) };
@@ -1165,18 +1164,18 @@
// }
// else
// {
-// throw new PLLinesCreatorException("Could not create the intersectionsection points between NWO and Phreatic line to create horizontal level.");
+// throw new PlLinesCreatorException("Could not create the intersectionsection points between NWO and Phreatic line to create horizontal level.");
// }
// }
// }
-// private void RemoveAllWaterFromNonWaterRetainingObject(GeometryPoint nwo1, PLLine pl1Line, PLLinePoint nwo1Pl, PLLinePoint nwo2Pl, PLLinePoint nwo3Pl, PLLinePoint nwo4Pl, PLLinePoint intersection1, PLLinePoint intersection2, IEnumerable plPointsToBeMoved)
+// private void RemoveAllWaterFromNonWaterRetainingObject(GeometryPoint nwo1, PlLine pl1Line, PlLinePoint nwo1Pl, PlLinePoint nwo2Pl, PlLinePoint nwo3Pl, PlLinePoint nwo4Pl, PlLinePoint intersection1, PlLinePoint intersection2, IEnumerable plPointsToBeMoved)
// {
// if ((nwo1.X >= this.surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X) ||
// ((intersection1 != null) && (intersection2 != null)))
// {
// // Move all the points in the pl line itself that need to be moved to below the surfaceline.
-// MoveSelectedPLLinePointsBelowSurfaceLine(plPointsToBeMoved);
+// MoveSelectedPlLinePointsBelowSurfaceLine(plPointsToBeMoved);
//
// // now add all extra points to the pl line
// if (nwo1Pl != null)
@@ -1214,7 +1213,7 @@
// }
// }
-// private void MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection2(GeometryPoint nwo1, GeometryPoint nwo2, GeometryPoint nwo3, PLLine pl1Line, PLLinePoint nwo1Pl, PLLinePoint nwo2Pl, PLLinePoint nwo3Pl, PLLinePoint intersection2)
+// private void MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection2(GeometryPoint nwo1, GeometryPoint nwo2, GeometryPoint nwo3, PlLine pl1Line, PlLinePoint nwo1Pl, PlLinePoint nwo2Pl, PlLinePoint nwo3Pl, PlLinePoint intersection2)
// {
// var lineNWO = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo1.X, 0, nwo1.Z), EndPoint = new GeometryPoint(nwo2.X, 0, nwo2.Z) };
// var linePL = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo1.X, 0, intersection2.Z), EndPoint = new GeometryPoint(intersection2.X, 0, intersection2.Z) };
@@ -1253,12 +1252,12 @@
// }
// else
// {
-// throw new PLLinesCreatorException("Could not create the intersectionsection points between NWO and Phreatic line to create horizontal level.");
+// throw new PlLinesCreatorException("Could not create the intersectionsection points between NWO and Phreatic line to create horizontal level.");
// }
// }
// }
-// private void MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection1(GeometryPoint nwo2, GeometryPoint nwo3, GeometryPoint nwo4, PLLine pl1Line, PLLinePoint nwo3Pl, PLLinePoint nwo4Pl, PLLinePoint intersection1)
+// private void MakeWaterLevelHorizontalInNWOAtRiverSideUsingInterSection1(GeometryPoint nwo2, GeometryPoint nwo3, GeometryPoint nwo4, PlLine pl1Line, PlLinePoint nwo3Pl, PlLinePoint nwo4Pl, PlLinePoint intersection1)
// {
// var lineNWO = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(nwo3.X, 0, nwo3.Z), EndPoint = new GeometryPoint(nwo4.X, 0, nwo4.Z) };
// var linePL = new Deltares.Geometry.Line { BeginPoint = new GeometryPoint(intersection1.X, 0, intersection1.Z), EndPoint = new GeometryPoint(nwo4.X, 0, intersection1.Z) };
@@ -1297,20 +1296,20 @@
// }
// else
// {
-// throw new PLLinesCreatorException("Could not create the intersectionsection points between NWO and Phreatic line to create horizontal level.");
+// throw new PlLinesCreatorException("Could not create the intersectionsection points between NWO and Phreatic line to create horizontal level.");
// }
// }
// }
-// private void MoveSelectedPLLinePointsBelowSurfaceLine(IEnumerable plPointsToBeMoved)
+// private void MoveSelectedPlLinePointsBelowSurfaceLine(IEnumerable plPointsToBeMoved)
// {
-// foreach (var plLinePoint in plPointsToBeMoved)
+// foreach (var PlLinePoint in plPointsToBeMoved)
// {
// // Determine which of these points must be moved and move them
-// if (this.surfaceLine.Geometry.PositionXzOfPointRelatedToExtrapolatedLine(plLinePoint) !=
+// if (this.surfaceLine.Geometry.PositionXzOfPointRelatedToExtrapolatedLine(PlLinePoint) !=
// RelativeXzPosition.BelowGeometricLine)
// {
-// plLinePoint.Z = this.surfaceLine.Geometry.GetZatX(plLinePoint.X) - cOffsetPhreaticLineBelowSurface;
+// PlLinePoint.Z = this.surfaceLine.Geometry.GetZatX(PlLinePoint.X) - cOffsetPhreaticLineBelowSurface;
// }
// }
// }
@@ -1322,26 +1321,26 @@
///
private PlLines CreateAllPlLinesWithGaugesWithFallbackToExpertKnowledgeRrd(Location location)
{
- var plLines = new PlLines();
+ var PlLines = new PlLines();
- foreach (PlLineType plLineType in Enum.GetValues(typeof(PlLineType)))
+ foreach (PlLineType PlLineType in Enum.GetValues(typeof(PlLineType)))
{
- GaugePlLine gaugePlLine = (this.GaugePlLines != null) ? (this.GaugePlLines.FirstOrDefault(x => x.PlLineType == plLineType)) : null;
+ GaugePlLine gaugePlLine = (this.GaugePlLines != null) ? (this.GaugePlLines.FirstOrDefault(x => x.PlLineType == PlLineType)) : null;
if (gaugePlLine != null && location != null)
{
- Boolean isUseWaterLevel = ((plLineType == PlLineType.Pl1) || (plLineType == PlLineType.Pl2));
- plLines.Lines[plLineType] = CreatePlLineFromGauges(gaugePlLine, this.Gauges, location, isUseWaterLevel);
+ Boolean isUseWaterLevel = ((PlLineType == PlLineType.Pl1) || (PlLineType == PlLineType.Pl2));
+ PlLines.Lines[PlLineType] = CreatePlLineFromGauges(gaugePlLine, this.Gauges, location, isUseWaterLevel);
}
else
- plLines.Lines[plLineType] = CreatePlLineByExpertKnowledge(plLineType, location.DamType, location.SlopeDampingPiezometricHeightPolderSide);
+ PlLines.Lines[PlLineType] = CreatePlLineByExpertKnowledge(PlLineType, location.DamType, location.SlopeDampingPiezometricHeightPolderSide);
// currentPL1Line is needed when calculating uplift reduction for PL3 and Pl4
- if (plLineType == PlLineType.Pl1)
+ if (PlLineType == PlLineType.Pl1)
{
- currentPL1Line = plLines.Lines[plLineType];
+ currentPL1Line = PlLines.Lines[PlLineType];
}
}
- return plLines;
+ return PlLines;
}
///
@@ -1351,70 +1350,63 @@
public PlLines CreateAllPlLines(Location location)
{
- PlLines plLines = new PlLines();
+ PlLines PlLines = new PlLines();
switch (modelParametersForPlLines.PlLineCreationMethod)
{
case PlLineCreationMethod.ExpertKnowledgeLinearInDike:
- case PlLineCreationMethod.ExpertKnowledgeRRD: plLines = CreateAllPlLinesWithExpertKnowledge(location);
+ case PlLineCreationMethod.ExpertKnowledgeRRD: PlLines = CreateAllPlLinesWithExpertKnowledge(location);
break;
- case PlLineCreationMethod.GaugesWithFallbackToExpertKnowledgeRRD: plLines = CreateAllPlLinesWithGaugesWithFallbackToExpertKnowledgeRrd(location);
+ case PlLineCreationMethod.GaugesWithFallbackToExpertKnowledgeRRD: PlLines = CreateAllPlLinesWithGaugesWithFallbackToExpertKnowledgeRrd(location);
break;
}
// If PL Line2 does not exists, make it equal to PL line 4
- if (!plLines.Lines[PlLineType.Pl2].Exists())
+ if (!PlLines.Lines[PlLineType.Pl2].Exists())
{
- plLines.Lines[PlLineType.Pl2] = plLines.Lines[PlLineType.Pl4].Clone();
+ PlLines.Lines[PlLineType.Pl2] = PlLines.Lines[PlLineType.Pl4].Clone();
}
- if (!plLines.Lines[PlLineType.Pl1].IsXAscending())
+ if (!PlLines.Lines[PlLineType.Pl1].IsXAscending())
{
throw new PlLinesCreatorException("PlLine 1 not an X-ascending polyline");
}
- return plLines;
+ return PlLines;
}
///
///
///
- ///
+ ///
///
- public PlLine CreatePlLineByExpertKnowledge(PlLineType plLineType, DamType damType, double slopeGradient)
+ public PlLine CreatePlLineByExpertKnowledge(PlLineType PlLineType, DamType damType, double slopeGradient)
{
- PlLine plLine = null;
+ PlLine PlLine = null;
- switch (plLineType)
+ switch (PlLineType)
{
case PlLineType.Pl1:
- plLine = this.CreatePlLine1ByExpertKnowledge();
+ PlLine = this.CreatePlLine1ByExpertKnowledge();
break;
case PlLineType.Pl2:
- plLine = this.CreatePlLine2ByExpertKnowledge(this.ModelParametersForPlLines.PenetrationLength, this.HeadInPlLine2);
+ PlLine = this.CreatePlLine2ByExpertKnowledge(this.ModelParametersForPlLines.PenetrationLength, this.HeadInPlLine2);
break;
case PlLineType.Pl3:
- plLine = this.CreatePlLine3ByExpertKnowledge(HeadPL3TakingInAccountHydraulicShortcut, this.ModelParametersForPlLines.DampingFactorPl3, slopeGradient);
+ PlLine = this.CreatePlLine3ByExpertKnowledge(HeadPL3TakingInAccountHydraulicShortcut, this.ModelParametersForPlLines.DampingFactorPl3, slopeGradient);
break;
case PlLineType.Pl4:
- plLine = this.CreatePlLine4ByExpertKnowledge(GetHeadPL4TakingInAccountHydraulicShortcut(damType), this.ModelParametersForPlLines.DampingFactorPl4, slopeGradient);
+ PlLine = this.CreatePlLine4ByExpertKnowledge(GetHeadPL4TakingInAccountHydraulicShortcut(damType), this.ModelParametersForPlLines.DampingFactorPl4, slopeGradient);
break;
}
- if (plLine != null)
+ if (PlLine != null)
{
- plLine.DeleteCoinsidingPoints();
+ PlLine.DeleteCoinsidingPoints();
}
- return plLine;
+ return PlLine;
}
- /*
- private PLLine CreatePLLineFromSensorGroup(PLLineType pLLineType, SensorLocation sensorLocation)
- {
- var creator = SensorPLLineCreator.CreateInstance(sensorLocation);
- return creator.CreatePLLine(pLLineType);
- }
- */
///
///
@@ -1425,7 +1417,7 @@
///
private PlLine CreatePlLineFromGauges(GaugePlLine gaugePlLine, IEnumerable gauges, Location location, Boolean useWaterLevel)
{
- PlLine plLine = new PlLine();
+ PlLine PlLine = new PlLine();
double? gaugeWaterLevelRiver = null;
double? leftMostXAtRiverLevel = null;
@@ -1476,7 +1468,7 @@
{
if (!leftMostXAtRiverLevel.HasValue || localX > leftMostXAtRiverLevel)
{
- plLine.Points.Add(new PlLinePoint(localX.Value, localZ.Value));
+ PlLine.Points.Add(new PlLinePoint(localX.Value, localZ.Value));
if (useWaterLevel)
{
// Have to account for waterlevel
@@ -1489,19 +1481,19 @@
{
// this is where the waterlevel intersects with the dike
leftMostXAtRiverLevel = intersectionsAtX.First();
- plLine.Points.Add(new PlLinePoint(leftMostXAtRiverLevel.Value, gaugeWaterLevelRiver.Value));
+ PlLine.Points.Add(new PlLinePoint(leftMostXAtRiverLevel.Value, gaugeWaterLevelRiver.Value));
}
else
{
// No intersection with dike; polder is flooded
leftMostXAtRiverLevel = this.surfaceLine.Geometry.Points.Last().X;
- plLine.Points.Add(new PlLinePoint(this.surfaceLine.Geometry.Points.Last().X, gaugeWaterLevelRiver.Value));
+ PlLine.Points.Add(new PlLinePoint(this.surfaceLine.Geometry.Points.Last().X, gaugeWaterLevelRiver.Value));
}
}
}
else
{
- // In this case no intersection for this Plline with the dike will be considered
+ // In this case no intersection for this PlLine with the dike will be considered
leftMostXAtRiverLevel = this.surfaceLine.Geometry.Points.First().X;
}
}
@@ -1510,13 +1502,13 @@
pointIndex++;
}
- if (plLine.Points.Count() > 0)
+ if (PlLine.Points.Count() > 0)
{
- plLine.Points.First().X = this.surfaceLine.Geometry.Points.First().X;
- plLine.Points.Last().X = this.surfaceLine.Geometry.Points.Last().X;
+ PlLine.Points.First().X = this.surfaceLine.Geometry.Points.First().X;
+ PlLine.Points.Last().X = this.surfaceLine.Geometry.Points.Last().X;
}
- return plLine;
+ return PlLine;
}
///
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLineCreatorException.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLineCreatorException.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLineCreatorException.cs (revision 1581)
@@ -0,0 +1,48 @@
+// 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.Runtime.Serialization;
+
+namespace Deltares.DamEngine.Calculators.PlLinesCreator
+{
+ [Serializable]
+ public class SensorPlLineCreatorException : Exception
+ {
+ public SensorPlLineCreatorException()
+ {
+ }
+
+ public SensorPlLineCreatorException(string message) : base(message)
+ {
+ }
+
+ public SensorPlLineCreatorException(string message, Exception inner) : base(message, inner)
+ {
+ }
+
+ protected SensorPlLineCreatorException(
+ SerializationInfo info,
+ StreamingContext context) : base(info, context)
+ {
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Extensions.cs
===================================================================
diff -u -r1363 -r1581
--- DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Extensions.cs (.../SurfaceLine2Extensions.cs) (revision 1363)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Extensions.cs (.../SurfaceLine2Extensions.cs) (revision 1581)
@@ -476,6 +476,35 @@
}
///
+ /// Determines the intersection of a horizontal line with the surfaceline, starting
+ /// from to .
+ ///
+ /// The surfaceline being evaluated.
+ /// The height of the horizontal line.
+ /// The GeometryPoint at the intersection, or null if no intersection can
+ /// be found.
+ ///
+ /// Requires that the following characteristic points are defined:
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// This method draws the horizontal line starting from the X coordinate of
+ /// to .
+ ///
+ /// When greater than
+ /// the height of the characteristic point .
+ ///
+ public static GeometryPoint DetermineIntersectionBetweenTaludRiverSideAndWaterLevel(this SurfaceLine2 line, double level)
+ {
+ double startXCoordinate = line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelOutside).X;
+ var waterlevelLine = GetWaterlevelLineStartingFrom(line, level, startXCoordinate);
+
+ return DetermineIntersectionWithHorizontalLevel(line, waterlevelLine);
+ }
+
+ ///
/// Determines the shoulder length for given shoulder top inside.
///
/// The line.
@@ -613,14 +642,14 @@
/// Throw an in case the given height level is
/// higher than the characteristic point .
///
- private static void ThrowWhenLevelAboveDike(SurfaceLine2 line, double Level)
+ private static void ThrowWhenLevelAboveDike(SurfaceLine2 line, double level)
{
var dikeTopAtRiver = line.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver);
- if (Level > dikeTopAtRiver.Z)
+ if (level > dikeTopAtRiver.Z)
{
throw new SurfaceLineException(String.Format(
"Level ({0:F2} m) should NOT be higher than surface line ({1:F2}))",
- Level, dikeTopAtRiver.Z));
+ level, dikeTopAtRiver.Z));
}
}
#endregion Private methods
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLineCreatorBase.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLineCreatorBase.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLineCreatorBase.cs (revision 1581)
@@ -0,0 +1,236 @@
+// 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.Collections.Generic;
+using System.Linq;
+using Deltares.DamEngine.Data.General;
+using Deltares.DamEngine.Data.General.PlLines;
+using Deltares.DamEngine.Data.General.Sensors;
+using Deltares.DamEngine.Data.General.Sensors.Specifications;
+using Deltares.DamEngine.Data.General.Specifications.Extensions;
+using Deltares.DamEngine.Data.Geometry;
+using Deltares.DamEngine.Data.Geotechnics;
+
+namespace Deltares.DamEngine.Calculators.PlLinesCreator
+{
+ internal abstract class SensorPlLineCreatorBase : IPlLineCreator
+ {
+// internal readonly static LogHelper Logger = LogHelper.Create();
+
+ protected SensorLocation SensorLocation;
+ protected readonly IDictionary SensorValues;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The sensor location.
+ /// The type.
+ /// The sensor values.
+ protected SensorPlLineCreatorBase(SensorLocation sensorLocation, PlLineType type, IDictionary sensorValues)
+ {
+ SensorLocation = sensorLocation;
+ SensorValues = sensorValues;
+ PlLineType = type;
+ }
+
+ ///
+ /// Gets the water level sensor.
+ ///
+ public Sensor WaterLevelSensor
+ {
+ get
+ {
+ try
+ {
+ return SensorLocation.Sensors
+ .GetBySpecification(new WaterLevelSensorSpecification())
+ .Single();
+ }
+ catch (Exception e)
+ {
+ throw new PlLinesCreatorException("There was an error getting the water level sensor. Maybe because there was no water level sensor defined", e);
+ }
+ }
+ }
+
+ ///
+ /// Gets the water level sensor.
+ ///
+ public Sensor PolderLevelSensor
+ {
+ get
+ {
+ var sensors = SensorLocation.Sensors.GetBySpecification(new PolderLevelSensorSpecification()).ToList();
+ if (sensors.Count() == 1)
+ {
+ return sensors.First();
+ }
+ if (!sensors.Any())
+ {
+ return null;
+ }
+ throw new PlLinesCreatorException("There are multiple polder level sensors defined.");
+ }
+ }
+
+ ///
+ /// Gets the PiezometricHead type sensors sorted along profile.
+ ///
+ ///
+ /// Water level and polder level sensors should not be in this collection
+ ///
+ protected IEnumerable SensorsSortedAlongProfile
+ {
+ get
+ {
+ return SensorLocation.GetSensorsSortedByRelativeLocationAlongProfile(PlLineType).Select(s => s.Value);
+ }
+ }
+
+ ///
+ /// Gets the X begin boundary.
+ ///
+ protected double XBeginBoundary
+ {
+ get
+ {
+ return SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelOutside).X;
+ }
+ }
+
+ ///
+ /// Gets the X end boundary.
+ ///
+ protected double XEndBoundary
+ {
+ get
+ {
+ return SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside).X;
+ }
+ }
+
+ protected bool DikeHasDitch
+ {
+ get { return SensorLocation.SurfaceLine.HasDitch(); }
+ }
+
+ protected bool DikeHasShoulder
+ {
+ get { return SensorLocation.SurfaceLine.HasShoulderInside(); }
+ }
+
+
+ ///
+ /// Gets the Y value at the end boundary.
+ ///
+ protected double YEndBoundary
+ {
+ get
+ {
+ return SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside).Y;
+ }
+ }
+
+ protected double XDikeToeAtRiver
+ {
+ get { return SensorLocation.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).X; }
+ }
+
+ ///
+ /// Intersection of line at river with a given Z value.
+ ///
+ ///
+ protected double IntersectionXAtRiverWaterLevel(double waterLevel)
+ {
+ GeometryPoint point = SensorLocation.SurfaceLine.DetermineIntersectionBetweenTaludRiverSideAndWaterLevel(waterLevel);
+ if (point == null)
+ {
+ throw new PlLinesCreatorException("No intersection point found with water level at dike river side");
+ }
+ return point.X;
+ }
+
+ ///
+ /// Intersection of line at polder with a given Z value.
+ ///
+ ///
+ protected double IntersectionXAtPolderZ(double z)
+ {
+ var intersectionsXatZ = SensorLocation.SurfaceLine.Geometry.IntersectionsXAtZ(z).ToList();
+ var hasIntersections = intersectionsXatZ.Count() == 2;
+ return hasIntersections ? intersectionsXatZ.Last() : double.NaN;
+ }
+
+ ///
+ /// Gets the sensor X value.
+ ///
+ /// The sensor.
+ ///
+ protected double GetSensorXValue(Sensor sensor)
+ {
+ return sensor.RelativeLocation;
+ }
+
+ ///
+ /// Gets the sensor Z value.
+ ///
+ /// The sensor.
+ ///
+ protected double GetSensorZValue(Sensor sensor)
+ {
+ return SensorValues[sensor];
+ }
+
+ ///
+ /// Gets the water level at polder.
+ ///
+ protected double WaterLevelAtPolder
+ {
+ get
+ {
+ throw new NotImplementedException();
+// var sensor = SensorLocation.GetSensorsSortedByRelativeLocationAlongProfile(PlLineType).Last().Value;
+// var value = SensorLocation.GetValue(x => x.PL1WaterLevelAtPolder, SensorValues, sensor);
+// if (value.HasValue)
+// return value.Value;
+//
+// var message = string.Format("Water level at polder for the location '{0}' was not set or initialized", SensorLocation.LocationName);
+// throw new InvalidOperationException(message);
+
+ }
+ }
+
+ ///
+ /// Gets the type of the PL line.
+ ///
+ ///
+ /// The type of the PL line.
+ ///
+ public PlLineType PlLineType { get; private set; }
+
+ ///
+ /// Creates the PL line.
+ ///
+ ///
+ public abstract PlLine CreatePlLine();
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/Sensors/SensorPLLineCreatorTest.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/Sensors/SensorPLLineCreatorTest.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/Sensors/SensorPLLineCreatorTest.cs (revision 1581)
@@ -0,0 +1,824 @@
+// 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.Collections.Generic;
+using System.Linq;
+using Deltares.DamEngine.Calculators.PlLinesCreator;
+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
+ {
+ #region Setup
+
+ [TestFixtureSetUp]
+ public void FixtureSetup()
+ {
+ }
+
+ [TestFixtureTearDown]
+ public void FixtureTearDown()
+ {
+ }
+
+ [SetUp]
+ public void TestSetup()
+ {
+
+ }
+
+ [TearDown]
+ public void TestTearDown()
+ {
+
+ }
+
+ #endregion
+
+ [Test]
+ [ExpectedException(typeof(PlLinesCreatorException))]
+ 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
+ creator.CreatePlLine(PlLineType.Pl1);
+ }
+
+ [Test] // Pl2 is not yet supported
+ [ExpectedException(typeof(NotSupportedException))]
+ 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
+ creator.CreatePlLine(PlLineType.Pl2);
+ }
+
+ [Test]
+ [ExpectedException(typeof(PlLinesCreatorException))]
+ public void CreatePlLine_Pl3NoSensorData_Throws()
+ {
+ // setup
+ var location = new Location("test");
+ SensorLocation sensorLocation = new SensorFactory().CreateSensorLocation(location);
+ var creator = SensorPlLineCreator.CreateInstance(sensorLocation, new Dictionary());
+
+ // call
+ creator.CreatePlLine(PlLineType.Pl3);
+ }
+
+ [Test]
+ [ExpectedException(typeof(PlLinesCreatorException))]
+ public void CreatePlLine_Pl4NoSensorData_Throws()
+ {
+ // setup
+ var location = new Location("test");
+ SensorLocation sensorLocation = new SensorFactory().CreateSensorLocation(location);
+ var creator = SensorPlLineCreator.CreateInstance(sensorLocation, new Dictionary());
+
+ // call
+ creator.CreatePlLine(PlLineType.Pl4);
+ }
+
+ [Test]
+ public void CreatePlLine_AllPlLinesDummyTest_ResultsAreAsExpected()
+ {
+ // setup
+ var surfaceLine = new SurfaceLine2
+ {
+ CharacteristicPoints = { GeometryMustContainPoint = true },
+ Geometry = new GeometryPointString()
+ };
+ var location = new Location("test")
+ {
+ RiverLevel = 1,
+ PolderLevel = 1
+ };
+ location.AddNewSensorData();
+ location.SensorData.Pl1PlLineOffsetBelowDikeToeAtPolder = DataSourceTypeSensors.LocationData;
+ location.SensorData.Pl1PlLineOffsetBelowDikeTopAtPolder = DataSourceTypeSensors.LocationData;
+ location.SensorData.Pl1PlLineOffsetBelowDikeTopAtRiver = DataSourceTypeSensors.LocationData;
+ location.SensorData.Pl1PlLineOffsetBelowShoulderBaseInside = 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 }, Type = 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},
+ };
+
+ var sensorLocation = location.SensorData;
+
+ var creator = new SensorPlLine1Creator(sensorLocation, sensorValues);
+
+ // call
+ PlLine actual = creator.CreatePlLine();
+
+ // asserts
+
+ // Number of expected points in line
+ var expectedCount = repository.Sensors.Count(s => s.PlLineMappings.Contains(PlLineType.Pl1)) + 2 + 4; // interection + end + 4 configured characteristic points
+ Assert.AreEqual(expectedCount, actual.Points.Count);
+
+ // P1
+ var p1 = actual.Points.First();
+ Assert.IsNotNull(p1);
+ var expectedZValueP1 = sensorValues[sensor1];
+ Assert.AreEqual(expectedZValueP1, p1.Z);
+
+ // P2
+ var p2 = actual.Points.FirstOrDefault(p => p.Name == sensor2.Name);
+ Assert.IsNotNull(p2);
+ Assert.AreEqual(sensor2.RelativeLocation, p2.X);
+ var expectedZValueP2 = sensorValues[sensor2];
+ Assert.AreEqual(expectedZValueP2, p2.Z);
+
+ // P3
+ var p3 = actual.Points.FirstOrDefault(p => p.Name == sensor3.Name);
+ Assert.IsNotNull(p3);
+ Assert.AreEqual(sensor3.RelativeLocation, p3.X);
+ var expectedZValueP3 = sensorValues[sensor3];
+ Assert.AreEqual(expectedZValueP3, p3.Z);
+
+ // P4
+ var p4 = actual.Points.FirstOrDefault(p => p.Name == sensor4.Name);
+ Assert.IsNotNull(p4);
+ Assert.AreEqual(sensor4.RelativeLocation, p4.X);
+ var expectedZValueP4 = sensorValues[sensor4];
+ Assert.AreEqual(expectedZValueP4, p4.Z);
+ }
+
+ [Test]
+ public void CreatePlLine_Pl1DikeToeAtPolderToSurfaceLevelInside_ZValueShouldBePolderLevel()
+ {
+ // setup
+ const double polderLevel = -0.5;
+ const double expectedEndPoint = -0.1; // Is not polderlevel, but level under toe of dike inward
+ var surfaceLine = new SurfaceLine2
+ {
+ CharacteristicPoints =
+ {
+ GeometryMustContainPoint = true
+ },
+ Geometry = new GeometryPointString()
+ };
+ var location = new Location("test")
+ {
+ RiverLevel = 5,
+ PolderLevel = polderLevel
+ };
+ location.AddNewSensorData();
+ location.SensorData.Pl1PlLineOffsetBelowDikeToeAtPolder = DataSourceTypeSensors.LocationData;
+ location.SensorData.Pl1PlLineOffsetBelowDikeTopAtPolder = DataSourceTypeSensors.LocationData;
+ location.SensorData.Pl1PlLineOffsetBelowDikeTopAtRiver = DataSourceTypeSensors.LocationData;
+ location.SensorData.Pl1PlLineOffsetBelowShoulderBaseInside = 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 }, Type = 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);
+
+ IDictionary sensorValues = new Dictionary()
+ {
+ {sensor1, 1},
+ {sensor2, 1},
+ {sensor3, 1},
+ {sensor4, 1},
+ };
+
+ var sensorLocation = location.SensorData;
+
+ var creator = new SensorPlLine1Creator(sensorLocation, sensorValues);
+
+ // call
+ PlLine actual = creator.CreatePlLine();
+
+ // asserts
+ var lastPoint = actual.Points.Last();
+ Assert.AreEqual(expectedEndPoint, lastPoint.Z);
+ }
+
+ [Test, Ignore("Test must be reviewed.")]
+ public void CreatePlLine_Pl1DikeToeAtPolderToSurfaceLevelInsideAndNoLocationData_ZValueShouldBeSurfaceLevel()
+ {
+ // setup
+ const int expectedValue = 1;
+ var surfaceLine = new SurfaceLine2
+ {
+ CharacteristicPoints = { GeometryMustContainPoint = true },
+ Geometry = new GeometryPointString()
+ };
+ var location = new Location("test")
+ {
+ RiverLevel = 5,
+ PolderLevel = -1
+ };
+ location.AddNewSensorData();
+ location.SensorData.Pl1PlLineOffsetBelowDikeTopAtRiver = DataSourceTypeSensors.LocationData;
+ location.SensorData.Pl1PlLineOffsetBelowDikeTopAtPolder = DataSourceTypeSensors.LocationData;
+ location.SensorData.Pl1PlLineOffsetBelowShoulderBaseInside = DataSourceTypeSensors.LocationData;
+ location.SensorData.Pl1PlLineOffsetBelowDikeToeAtPolder = DataSourceTypeSensors.Sensor;
+
+ 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, expectedValue, CharacteristicPointType.SurfaceLevelInside);
+
+ location.SurfaceLine = surfaceLine;
+
+ var sensor1 = new Sensor { ID = 1, Name = "Test1", Depth = 2, RelativeLocation = 50, PlLineMappings = new[] { PlLineType.Pl1 }, Type = 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);
+
+ IDictionary sensorValues = new Dictionary()
+ {
+ {sensor1, 1},
+ {sensor2, 1},
+ {sensor3, 1},
+ {sensor4, 1},
+ };
+
+ var sensorLocation = location.SensorData;
+
+ var creator = new SensorPlLine1Creator(sensorLocation, sensorValues);
+
+ // call
+ PlLine actual = creator.CreatePlLine();
+
+ // asserts
+ var lastPoint = actual.Points.Last();
+ Assert.AreEqual(expectedValue, lastPoint.Z);
+ }
+
+ [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.AddNewSensorData();
+ location.SurfaceLine = surfaceLine;
+
+ var creator = new SensorPlLine1Creator(location.SensorData, new Dictionary());
+ var actual = creator.GetDitchWaterLevelIntersectionAtXDikeSide(-2.5);
+ const double expected = 12.5;
+ Assert.AreEqual(expected, actual);
+ }
+
+ [Test]
+ public void CreatePlLine_Pl1IgnorAllSensors_ResultsAreAsExpected()
+ {
+ // setup
+ var surfaceLine = new SurfaceLine2
+ {
+ CharacteristicPoints =
+ {
+ GeometryMustContainPoint = true
+ },
+ Geometry = new GeometryPointString()
+ };
+ var location = new Location("test")
+ {
+ RiverLevel = 1,
+ PolderLevel = 1
+ };
+ location.AddNewSensorData();
+ location.SensorData.Pl1PlLineOffsetBelowDikeToeAtPolder = DataSourceTypeSensors.Ignore;
+ location.SensorData.Pl1PlLineOffsetBelowDikeTopAtPolder = DataSourceTypeSensors.Ignore;
+ location.SensorData.Pl1PlLineOffsetBelowDikeTopAtRiver = DataSourceTypeSensors.Ignore;
+ location.SensorData.Pl1PlLineOffsetBelowShoulderBaseInside = DataSourceTypeSensors.Ignore;
+ location.SensorData.Pl1WaterLevelAtRiver = DataSourceTypeSensors.LocationData;
+ location.SensorData.Pl1WaterLevelAtPolder = 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 }, Type = 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},
+ };
+
+ var sensorLocation = location.SensorData;
+ var creator = new SensorPlLine1Creator(sensorLocation, sensorValues);
+
+ // call
+ PlLine actual = creator.CreatePlLine();
+
+ // asserts
+
+ // Number of expected points in line
+ const int expectedNumberOfCharacteristicPoints = 2;
+ var pl1SensorCount = repository.Sensors.Count(s => s.PlLineMappings.Contains(PlLineType.Pl1)) +
+ expectedNumberOfCharacteristicPoints + 1; // plus one for the intersection point + one for point below toe of dike
+ Assert.AreEqual(pl1SensorCount, actual.Points.Count);
+
+ // P2
+ var p2 = actual.Points.FirstOrDefault(p => p.Name == sensor2.Name);
+ Assert.IsNotNull(p2);
+ Assert.AreEqual(sensor2.RelativeLocation, p2.X);
+ var expectedZValueP2 = sensorValues[sensor2];
+ Assert.AreEqual(expectedZValueP2, p2.Z);
+
+ // P3
+ var p3 = actual.Points.FirstOrDefault(p => p.Name == sensor3.Name);
+ Assert.IsNotNull(p3);
+ Assert.AreEqual(sensor3.RelativeLocation, p3.X);
+ var expectedZValueP3 = sensorValues[sensor3];
+ Assert.AreEqual(expectedZValueP3, p3.Z);
+
+ // P4
+ var p4 = actual.Points.FirstOrDefault(p => p.Name == sensor4.Name);
+ Assert.IsNotNull(p4);
+ Assert.AreEqual(sensor4.RelativeLocation, p4.X);
+ var expectedZValueP4 = sensorValues[sensor4];
+ Assert.AreEqual(expectedZValueP4, p4.Z);
+ }
+
+ [Test]
+ public void CreatePlLinePl1_DikeHasDitch_ResultsAreAsExpected()
+ {
+ var surfaceLine = new SurfaceLine2
+ {
+ CharacteristicPoints =
+ {
+ GeometryMustContainPoint = true
+ },
+ Geometry = new GeometryPointString()
+ };
+ var location = new Location("test")
+ {
+ RiverLevel = 1, PolderLevel = 1
+ };
+ #region Setup
+
+ location.AddNewSensorData();
+ location.SensorData.Pl1PlLineOffsetBelowDikeToeAtPolder = DataSourceTypeSensors.Ignore;
+ location.SensorData.Pl1PlLineOffsetBelowDikeTopAtPolder = DataSourceTypeSensors.Ignore;
+ location.SensorData.Pl1PlLineOffsetBelowDikeTopAtRiver = DataSourceTypeSensors.Ignore;
+ location.SensorData.Pl1PlLineOffsetBelowShoulderBaseInside = DataSourceTypeSensors.Ignore;
+ location.SensorData.Pl1WaterLevelAtRiver = DataSourceTypeSensors.LocationData;
+ location.SensorData.Pl1WaterLevelAtPolder = 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 }, Type = 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},
+ };
+
+ var sensorLocation = location.SensorData;
+ var creator = new SensorPlLine1Creator(sensorLocation, sensorValues);
+
+ #endregion
+
+ // call
+ PlLine actual = creator.CreatePlLine();
+
+ // asserts
+
+ // Number of expected points in line
+ var pl1SensorCount = repository.Sensors.Count(s => s.PlLineMappings.Contains(PlLineType.Pl1));
+ Assert.AreEqual(pl1SensorCount + 2 /* intersection points */, actual.Points.Count);
+
+ // P2
+ var p2 = actual.Points.FirstOrDefault(p => p.Name == sensor2.Name);
+ Assert.IsNotNull(p2);
+ Assert.AreEqual(sensor2.RelativeLocation, p2.X);
+ var expectedZValueP2 = sensorValues[sensor2];
+ Assert.AreEqual(expectedZValueP2, p2.Z);
+
+ // P3
+ var p3 = actual.Points.FirstOrDefault(p => p.Name == sensor3.Name);
+ Assert.IsNotNull(p3);
+ Assert.AreEqual(sensor3.RelativeLocation, p3.X);
+ var expectedZValueP3 = sensorValues[sensor3];
+ Assert.AreEqual(expectedZValueP3, p3.Z);
+
+ // P4
+ var p4 = actual.Points.FirstOrDefault(p => p.Name == sensor4.Name);
+ Assert.IsNotNull(p4);
+ Assert.AreEqual(sensor4.RelativeLocation, p4.X);
+ var expectedZValueP4 = sensorValues[sensor4];
+ Assert.AreEqual(expectedZValueP4, p4.Z);
+ }
+
+ [Test]
+ public void CreatePlLine_DikeHasDitchAndSensor_DichLevelIsHorizontal()
+ {
+ const int polderLevel = 0;
+ const int waterLevel = 1;
+ var surfaceLine = new SurfaceLine2
+ {
+ CharacteristicPoints =
+ {
+ GeometryMustContainPoint = true
+ },
+ Geometry = new GeometryPointString()
+ };
+ var location = new Location("test")
+ {
+ RiverLevel = waterLevel, PolderLevel = polderLevel
+ };
+ #region Setup
+
+ location.AddNewSensorData();
+ location.SensorData.Pl1PlLineOffsetBelowDikeToeAtPolder = DataSourceTypeSensors.Ignore;
+ location.SensorData.Pl1PlLineOffsetBelowDikeTopAtPolder = DataSourceTypeSensors.Ignore;
+ location.SensorData.Pl1PlLineOffsetBelowDikeTopAtRiver = DataSourceTypeSensors.Ignore;
+ location.SensorData.Pl1PlLineOffsetBelowShoulderBaseInside = DataSourceTypeSensors.Ignore;
+
+ location.SensorData.Pl1WaterLevelAtRiver = DataSourceTypeSensors.Sensor;
+ location.SensorData.Pl1WaterLevelAtPolder = 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 }, Type = 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 }, Type = 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}
+ };
+
+ var sensorLocation = location.SensorData;
+
+ #endregion
+
+ // call
+ var creator = new SensorPlLine1Creator(sensorLocation, sensorValues);
+ PlLine actual = creator.CreatePlLine();
+
+ // checks
+ var xDitchDikeSide = creator.GetDitchWaterLevelIntersectionAtXDikeSide(sensorValues[sensor5]);
+ var xDitchPolderSide = creator.GetDitchWaterLevelIntersectionAtXPolderSide(sensorValues[sensor5]);
+ Assert.IsTrue(actual.Points.Any(p => p.X == xDitchDikeSide));
+
+ var zDitchDikeSide = actual.Points.Single(p => p.X == xDitchDikeSide).Z;
+ var zDitchPolderSide = actual.Points.Single(p => p.X == xDitchPolderSide).Z;
+
+ Assert.IsTrue(actual.Points.Any(p => p.X == xDitchPolderSide));
+ Assert.AreEqual(zDitchDikeSide, zDitchPolderSide);
+
+ var endPoint = actual.Points.Last();
+
+ // End point should be z of x intersection at dike side in ditch (horizontal)
+ Assert.AreEqual(endPoint.Z, zDitchDikeSide);
+ }
+
+ [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()
+ };
+ var location = new Location("test")
+ {
+ RiverLevel = waterLevel, PolderLevel = waterLevel
+ };
+ {
+ location.AddNewSensorData();
+ location.SensorData.Pl3 = DataSourceTypeSensors.Sensor;
+ location.SensorData.Pl1WaterLevelAtRiver = DataSourceTypeSensors.LocationData;
+ location.SensorData.Pl1WaterLevelAtPolder = 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 }, Type = 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},
+ };
+
+ var sensorLocation = location.SensorData;
+ var creator = new SensorPlLine3Creator(sensorLocation, sensorValues);
+
+ // call
+ PlLine actual = creator.CreatePlLine();
+
+ //checks
+
+ // start first segment
+ Assert.AreEqual(-0.0, actual.Points[0].X);
+ Assert.AreEqual(waterLevel, actual.Points[0].Z);
+
+ // end of first segment (ends at DikeToeAtRiver)
+ Assert.AreEqual(xDikeToeAtRiver, actual.Points[1].X);
+ Assert.AreEqual(waterLevel, actual.Points[1].Z);
+ }
+ }
+
+ [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()
+ };
+ var location = new Location("test")
+ {
+ RiverLevel = 1.0, PolderLevel = 1.0
+ };
+ {
+ location.AddNewSensorData();
+ location.SensorData.Pl3 = DataSourceTypeSensors.Sensor;
+ location.SensorData.Pl1WaterLevelAtRiver = DataSourceTypeSensors.Sensor;
+ location.SensorData.Pl1WaterLevelAtPolder = 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 }, Type = 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},
+ };
+
+ var sensorLocation = location.SensorData;
+ var creator = new SensorPlLine3Creator(sensorLocation, sensorValues);
+
+ // call
+ PlLine actual = creator.CreatePlLine();
+
+ //checks
+
+ // start first segment
+ Assert.AreEqual(-0.0, actual.Points[0].X);
+ Assert.AreEqual(waterLevel, actual.Points[0].Z);
+
+ // end of first segment (ends at DikeToeAtRiver)
+ Assert.AreEqual(xDikeToeAtRiver, actual.Points[1].X);
+ Assert.AreEqual(waterLevel, actual.Points[1].Z);
+ }
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/SpecificationBase.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/SpecificationBase.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/SpecificationBase.cs (revision 1581)
@@ -0,0 +1,72 @@
+// 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.
+
+namespace Deltares.DamEngine.Data.General.Specifications
+{
+ ///
+ /// Abstract specification class that implements base properties
+ ///
+ /// The type of the candidate.
+ public abstract class SpecificationBase : ISpecification
+ {
+ protected SpecificationBase()
+ {
+ Name = this.GetType().Name;
+ }
+
+ ///
+ /// Gets or sets the name of the specification. (Short description)
+ ///
+ ///
+ /// The name string value should be a required property for each specification.
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// Gets or sets the description of the specification. (Long description)
+ ///
+ ///
+ /// The description string value.
+ ///
+ public string Description { get; set; }
+
+ ///
+ /// Determines whether the candidate satisfies the specification.
+ ///
+ /// The candidate to test.
+ ///
+ /// true if the candidate satisfies the specification otherwise, false.
+ ///
+ bool ISpecification.IsSatisfiedBy(object candidate)
+ {
+ return IsSatisfiedBy((TCandidate)candidate);
+ }
+
+ ///
+ /// Determines whether the candidate satisfies the specification.
+ ///
+ /// The candidate to test.
+ ///
+ /// true if the candidate satisfies the specification otherwise, false.
+ ///
+ public abstract bool IsSatisfiedBy(TCandidate candidate);
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/Specifications/PolderLevelSensorSpecification.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/Specifications/PolderLevelSensorSpecification.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/Specifications/PolderLevelSensorSpecification.cs (revision 1581)
@@ -0,0 +1,33 @@
+// 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 Deltares.DamEngine.Data.General.Specifications;
+
+namespace Deltares.DamEngine.Data.General.Sensors.Specifications
+{
+ public class PolderLevelSensorSpecification : PredicateSpecification
+ {
+ public PolderLevelSensorSpecification() :
+ base(s => s.Type == SensorType.PolderLevel)
+ {
+ }
+ }
+}
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/SensorLocation.cs
===================================================================
diff -u -r1263 -r1581
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/SensorLocation.cs (.../SensorLocation.cs) (revision 1263)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/SensorLocation.cs (.../SensorLocation.cs) (revision 1581)
@@ -24,6 +24,8 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
+using Deltares.DamEngine.Data.General.Sensors.Specifications;
+using Deltares.DamEngine.Data.General.Specifications.Extensions;
using Deltares.DamEngine.Data.Geotechnics;
using Deltares.DamEngine.Data.Standard;
@@ -181,22 +183,22 @@
}
///
- /// Gets or sets the PL3 data source type.
+ /// Gets or sets the Pl3 data source type.
///
///
- /// The PL3.
+ /// The Pl3.
///
// [Specification(typeof(SensorOrLocationData))]
- public DataSourceTypeSensors PL3 { get; set; }
+ public DataSourceTypeSensors Pl3 { get; set; }
///
- /// Gets or sets the PL4 data source type.
+ /// Gets or sets the Pl4 data source type.
///
///
- /// The PL4.
+ /// The Pl4.
///
// [Specification(typeof(SensorOrLocationData))]
- public DataSourceTypeSensors PL4 { get; set; }
+ public DataSourceTypeSensors Pl4 { get; set; }
///
@@ -209,46 +211,46 @@
public DataSourceTypeSensors Pl1WaterLevelAtRiver { get; set; }
///
- /// Gets or sets the PL1 PL line offset below dike top at river data source type.
+ /// Gets or sets the Pl1 PL line offset below dike top at river data source type.
///
///
- /// Data source type for PL1 PLLine offset below dike top at river.
+ /// Data source type for Pl1 PLLine offset below dike top at river.
///
// [Specification(typeof(IgnoreOrLocationData))]
public DataSourceTypeSensors Pl1PlLineOffsetBelowDikeTopAtRiver { get; set; }
///
- /// Gets or sets the PL1 PL line offset below dike top at polder data source type
+ /// Gets or sets the Pl1 PL line offset below dike top at polder data source type
///
///
- /// The PL1 PL line offset below dike top at polder.
+ /// The Pl1 PL line offset below dike top at polder.
///
// [Specification(typeof(IgnoreOrLocationData))]
public DataSourceTypeSensors Pl1PlLineOffsetBelowDikeTopAtPolder { get; set; }
///
- /// Gets or sets the PL1 PL line offset below shoulder base inside data source type
+ /// Gets or sets the Pl1 PL line offset below shoulder base inside data source type
///
///
- /// The PL1 PL line offset below shoulder base inside.
+ /// The Pl1 PL line offset below shoulder base inside.
///
// [Specification(typeof(IgnoreOrLocationData))]
public DataSourceTypeSensors Pl1PlLineOffsetBelowShoulderBaseInside { get; set; }
///
- /// Gets or sets the PL1 PL line offset below dike toe at polder data source type.
+ /// Gets or sets the Pl1 PL line offset below dike toe at polder data source type.
///
///
- /// The PL1 PL line offset below dike toe at polder.
+ /// The Pl1 PL line offset below dike toe at polder.
///
//[Specification(typeof(IgnoreOrLocationData))]
public DataSourceTypeSensors Pl1PlLineOffsetBelowDikeToeAtPolder { get; set; }
///
- /// Gets or sets the PL1 polder level data source type.
+ /// Gets or sets the Pl1 polder level data source type.
///
///
- /// The PL1 polder level.
+ /// The Pl1 polder level.
///
//[Specification(typeof(SensorOrLocationData))]
public DataSourceTypeSensors Pl1WaterLevelAtPolder { get; set; }
@@ -308,35 +310,35 @@
///
/// Type of the pl line.
///
-// internal SortedDictionary GetSensorsSortedByRelativeLocationAlongProfile(PLLineType plLineType)
-// {
-// var calculatedRelativeLocations = BuildRelativeLocationTable();
-//
-// var table = new SortedDictionary();
-//
-// // leave out the water level and polder level sensors
-// var candidateSensors =
-// Sensors.GetBySpecification(new PiezometricHeadSensorSpecification());
-//
-// foreach (var sensor in candidateSensors)
-// {
-// if (sensor.PLLineMappings.Contains(plLineType))
-// {
-// double relativeLocation = sensor.RelativeLocationSpecified ?
-// sensor.RelativeLocation : calculatedRelativeLocations[sensor];
-//
-// if (table.ContainsKey(relativeLocation))
-// {
-// throw new InvalidOperationException(
-// "Error creating lookup table with sensors sorted by relative location along profile. The x-location " + relativeLocation + " already exists. Sensor " + sensor);
-// }
-//
-// table.Add(relativeLocation, sensor);
-// }
-// }
-// return table;
-// } ##Bka
+ public SortedDictionary GetSensorsSortedByRelativeLocationAlongProfile(PlLineType plLineType)
+ {
+ var calculatedRelativeLocations = BuildRelativeLocationTable();
+ var table = new SortedDictionary();
+
+ // leave out the water level and polder level sensors
+ var candidateSensors =
+ Sensors.GetBySpecification(new PiezometricHeadSensorSpecification());
+
+ foreach (var sensor in candidateSensors)
+ {
+ if (sensor.PlLineMappings.Contains(plLineType))
+ {
+ double relativeLocation = sensor.RelativeLocationSpecified ?
+ sensor.RelativeLocation : calculatedRelativeLocations[sensor];
+
+ if (table.ContainsKey(relativeLocation))
+ {
+ throw new InvalidOperationException(
+ "Error creating lookup table with sensors sorted by relative location along profile. The x-location " + relativeLocation + " already exists. Sensor " + sensor);
+ }
+
+ table.Add(relativeLocation, sensor);
+ }
+ }
+ return table;
+ }
+
///
/// Builds the relative location table.
///
@@ -366,8 +368,8 @@
internal static readonly string OffsetBelowShoulderBaseInside = StaticReflection.GetMemberName(x => x.Pl1PlLineOffsetBelowShoulderBaseInside);
internal static readonly string WaterLevelAtRiver = StaticReflection.GetMemberName(x => x.Pl1WaterLevelAtRiver);
internal static readonly string PolderLevel = StaticReflection.GetMemberName(x => x.Pl1WaterLevelAtPolder);
- internal static readonly string PL3 = StaticReflection.GetMemberName(x => x.PL3);
- internal static readonly string PL4 = StaticReflection.GetMemberName(x => x.PL4);
+ internal static readonly string Pl3 = StaticReflection.GetMemberName(x => x.Pl3);
+ internal static readonly string Pl4 = StaticReflection.GetMemberName(x => x.Pl4);
}
public double? GetValue(Expression> expression, IDictionary sensorValues, Sensor sensor)
@@ -422,21 +424,21 @@
return sensorValues[sensor];
}
- if (memberName == MemberNames.PL3)
+ if (memberName == MemberNames.Pl3)
{
- if (PL3 == DataSourceTypeSensors.LocationData)
+ if (Pl3 == DataSourceTypeSensors.LocationData)
return Location.HeadPl3;
- if (PL3 == DataSourceTypeSensors.Sensor)
+ if (Pl3 == DataSourceTypeSensors.Sensor)
return sensorValues[sensor];
}
- if (memberName == MemberNames.PL4)
+ if (memberName == MemberNames.Pl4)
{
- if (PL4 == DataSourceTypeSensors.LocationData)
+ if (Pl4 == DataSourceTypeSensors.LocationData)
return Location.HeadPl4;
- if (PL4 == DataSourceTypeSensors.Sensor)
+ if (Pl4 == DataSourceTypeSensors.Sensor)
return sensorValues[sensor];
}
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/MinimumAttribute.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/MinimumAttribute.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/MinimumAttribute.cs (revision 1581)
@@ -0,0 +1,41 @@
+// 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;
+
+namespace Deltares.DamEngine.Data.General.Specifications
+{
+ [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = true)]
+ public sealed class MinimumAttribute : Attribute
+ {
+ private readonly double attributeValue;
+
+ public MinimumAttribute(double minValue)
+ {
+ this.attributeValue = minValue;
+ }
+
+ public double AttributeValue
+ {
+ get { return this.attributeValue; }
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLine2Creator.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLine2Creator.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLine2Creator.cs (revision 1581)
@@ -0,0 +1,41 @@
+// 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.Collections.Generic;
+using Deltares.DamEngine.Data.General;
+using Deltares.DamEngine.Data.General.PlLines;
+using Deltares.DamEngine.Data.General.Sensors;
+
+namespace Deltares.DamEngine.Calculators.PlLinesCreator
+{
+ internal class SensorPlLine2Creator : SensorPlLineCreatorBase
+ {
+ public SensorPlLine2Creator(SensorLocation sensorLocation, IDictionary sensorValues) : base(sensorLocation, PlLineType.Pl2, sensorValues)
+ {
+ }
+
+ public override PlLine CreatePlLine()
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/Specifications/PiezometricHeadSensorSpecification.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/Specifications/PiezometricHeadSensorSpecification.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/Specifications/PiezometricHeadSensorSpecification.cs (revision 1581)
@@ -0,0 +1,33 @@
+// 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 Deltares.DamEngine.Data.General.Specifications;
+
+namespace Deltares.DamEngine.Data.General.Sensors.Specifications
+{
+ internal class PiezometricHeadSensorSpecification : PredicateSpecification
+ {
+ public PiezometricHeadSensorSpecification() :
+ base(s => s.Type == SensorType.PiezometricHead)
+ {
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/GreaterThanOrEqualToSpecification.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/GreaterThanOrEqualToSpecification.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/GreaterThanOrEqualToSpecification.cs (revision 1581)
@@ -0,0 +1,56 @@
+// 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;
+
+namespace Deltares.DamEngine.Data.General.Specifications
+{
+ ///
+ /// Defines a greater then of equal to specification
+ ///
+ /// The type of the candidate.
+ /// The type of the value.
+ public class GreaterThanOrEqualToSpecification : ValueBoundSpecification where TValue : IComparable
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Name of the attribute.
+ /// The attribute value.
+ public GreaterThanOrEqualToSpecification(string attributeName, TValue attributeValue)
+ : base(attributeName, attributeValue)
+ {
+ }
+
+ ///
+ /// Determines whether the candidate satisfies the specification.
+ ///
+ /// The candidate to test.
+ ///
+ /// true if the candidate satisfies the specification otherwise, false.
+ ///
+ public override bool IsSatisfiedBy(TCandidate candidate)
+ {
+ var actual = this.GetCandidateTValue(candidate) as IComparable;
+ return (actual.CompareTo(this.AttributeValue) >= 0);
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/PLLineConstructor.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/PLLineConstructor.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/PLLineConstructor.cs (revision 1581)
@@ -0,0 +1,74 @@
+// 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.Collections.Generic;
+using Deltares.DamEngine.Data.General;
+using Deltares.DamEngine.Data.General.PlLines;
+
+namespace Deltares.DamEngine.Calculators.PlLinesCreator
+{
+ ///
+ /// This class is responsible for creating a PL line where the coordinates are sorted on x.
+ /// No logic will be applied on how the PL is constructed. Just a simple data structure with an
+ /// insert method to insert new points.
+ ///
+ internal class PlLineConstructor
+ {
+ readonly IDictionary line = new SortedDictionary();
+
+ ///
+ /// Inserts the specified point.
+ ///
+ /// The point will be inserted in the line based on the X value
+ /// The point.
+ public void Insert(PlLinePoint point)
+ {
+ if (line.ContainsKey(point.X))
+ line[point.X] = point;
+ else
+ line.Add(point.X, point);
+ }
+
+ ///
+ /// Inserts the specified point.
+ ///
+ /// The point will be inserted in the line based on the X value
+ /// The x.
+ /// The z.
+ public void Insert(double x, double z)
+ {
+ Insert(new PlLinePoint(x, z));
+ }
+
+ ///
+ /// Gets the PL line from the internal constructed line.
+ ///
+ public PlLine CreatePlLine(PlLineType type)
+ {
+ var plLine = new PlLine() { PlLineType = type };
+ foreach (var kvp in line)
+ {
+ plLine.Points.Add(kvp.Value);
+ }
+ return plLine;
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/Specifications/UseLocationAsDataSource.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/Specifications/UseLocationAsDataSource.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/Specifications/UseLocationAsDataSource.cs (revision 1581)
@@ -0,0 +1,33 @@
+// 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 Deltares.DamEngine.Data.General.Specifications;
+
+namespace Deltares.DamEngine.Data.General.Sensors.Specifications
+{
+ public class UseLocationAsDataSource : PredicateSpecification
+ {
+ public UseLocationAsDataSource() :
+ base(x => x == DataSourceTypeSensors.LocationData)
+ {
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/Extensions/SpecificationExtensions.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/Extensions/SpecificationExtensions.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/Extensions/SpecificationExtensions.cs (revision 1581)
@@ -0,0 +1,142 @@
+// 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.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using Deltares.DamEngine.Data.Standard.Validation;
+
+namespace Deltares.DamEngine.Data.General.Specifications.Extensions
+{
+ public static class SpecificationExtensions
+ {
+ public static IEnumerable GetBySpecification(this IEnumerable collection, ISpecification specification)
+ {
+ return collection.Where(specification.IsSatisfiedBy);
+ }
+
+ public static bool IsSatisfiedBySpecification(this T source, ISpecification specification)
+ {
+ return specification.IsSatisfiedBy(source);
+ }
+
+ public static bool IsNotSatisfiedBySpecification(this T source, ISpecification specification)
+ {
+ return !IsSatisfiedBySpecification(source, specification);
+ }
+
+ public static IEnumerable Validate(this T source, string groupName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public static IEnumerable Validate(this T source)
+ {
+ var validationResults = new List();
+
+ foreach (var attribute in source.GetType().GetCustomAttributes(false))
+ {
+ var specAttr = attribute as SpecificationBaseAttribute;
+ if (specAttr != null)
+ {
+ if (IsNotSatisfiedBySpecification(source, (ISpecification)specAttr.Specification))
+ AddValidationResult(source, validationResults, specAttr);
+ }
+ }
+
+ foreach (PropertyInfo property in source.GetType().GetProperties())
+ {
+ foreach (object attribute in property.GetCustomAttributes(true))
+ {
+ var specAttr = attribute as SpecificationBaseAttribute;
+ if (specAttr != null)
+ {
+ object candidateValue = property.GetValue(source, null);
+ if (!specAttr.Specification.IsSatisfiedBy(candidateValue))
+ AddValidationResult(property, validationResults, specAttr);
+ }
+ else
+ {
+ var minAttr = attribute as MinimumAttribute;
+ if (minAttr != null)
+ {
+ var gte =
+ new GreaterThanOrEqualToSpecification(property.Name, minAttr.AttributeValue);
+ if (!gte.IsSatisfiedBy(source))
+ {
+ validationResults.Add(new ValidationResult()
+ {
+ Subject = property,
+ MessageType = ValidationResultType.Error,
+ Text = string.Format("The property or field {0} has the value {1} which is less then the specification {2}",
+ property.Name, gte.CandidateValue, minAttr.AttributeValue)
+ });
+ }
+ }
+ else
+ {
+ var maxAttr = attribute as MaximumAttribute;
+ if (maxAttr != null)
+ {
+ var lte =
+ new LessThanOrEqualToSpecification(property.Name, maxAttr.AttributeValue);
+ if (!lte.IsSatisfiedBy(source))
+ {
+ validationResults.Add(new ValidationResult()
+ {
+ Subject = property,
+ MessageType = ValidationResultType.Error,
+ Text = string.Format("The property or field {0} has the value {1} which is greater then the specification {2}",
+ property.Name, lte.CandidateValue, maxAttr.AttributeValue)
+ });
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return validationResults;
+ }
+
+ private static void AddValidationResult(object subject, ICollection validationResults, SpecificationBaseAttribute specAttr)
+ {
+ string message = specAttr.NotSatisfiedText;
+
+ if (string.IsNullOrWhiteSpace(message))
+ message = specAttr.Specification.Description;
+
+ if (string.IsNullOrWhiteSpace(message))
+ message = specAttr.Specification.Name;
+
+ if (string.IsNullOrWhiteSpace(message))
+ message = specAttr.Specification.ToString();
+
+ validationResults.Add(new ValidationResult()
+ {
+ Subject = subject,
+ MessageType = ValidationResultType.Error,
+ Text = message
+ });
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/MaximumAttribute.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/MaximumAttribute.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/MaximumAttribute.cs (revision 1581)
@@ -0,0 +1,41 @@
+// 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;
+
+namespace Deltares.DamEngine.Data.General.Specifications
+{
+ [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = true)]
+ public sealed class MaximumAttribute : Attribute
+ {
+ private readonly double attribteValue;
+
+ public MaximumAttribute(double maxValue)
+ {
+ this.attribteValue = maxValue;
+ }
+
+ public double AttributeValue
+ {
+ get { return this.attribteValue; }
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/PredicateSpecification.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/PredicateSpecification.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/PredicateSpecification.cs (revision 1581)
@@ -0,0 +1,54 @@
+// 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;
+
+namespace Deltares.DamEngine.Data.General.Specifications
+{
+ public class PredicateSpecification : CompositeSpecification
+ {
+ private readonly Predicate predicate;
+
+ public PredicateSpecification(Predicate predicate)
+ {
+ if (predicate == default(Predicate))
+ throw new ArgumentNullException("predicate");
+
+ this.predicate = predicate;
+ }
+
+ #region ISpecification Members
+
+ ///
+ /// Determines whether the candidate satisfies the specification.
+ ///
+ /// The candidate.
+ ///
+ /// true if the candidate satisfies the specification otherwise, false.
+ ///
+ public override bool IsSatisfiedBy(T candidate)
+ {
+ return this.predicate(candidate);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLine3Or4CreatorBase.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLine3Or4CreatorBase.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLine3Or4CreatorBase.cs (revision 1581)
@@ -0,0 +1,125 @@
+// 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.Collections.Generic;
+using System.Linq;
+using Deltares.DamEngine.Data.General;
+using Deltares.DamEngine.Data.General.PlLines;
+using Deltares.DamEngine.Data.General.Sensors;
+
+namespace Deltares.DamEngine.Calculators.PlLinesCreator
+{
+ internal abstract class SensorPlLine3Or4CreatorBase : SensorPlLineCreatorBase
+ {
+ protected SensorPlLine3Or4CreatorBase(SensorLocation sensorLocation, IDictionary sensorValues, PlLineType PlLineType)
+ : base(sensorLocation, PlLineType, sensorValues)
+ {
+ }
+
+ ///
+ /// Gets the start z level of the PL line
+ ///
+ ///
+ /// The start level is based on the PL3 or PL4 configuration (locationdata or sensor)
+ /// and the position of the first sensor
+ ///
+ ///
+ public override PlLine CreatePlLine()
+ {
+ var lineConstructor = new PlLineConstructor();
+
+ double currentLevel = 0;
+
+ currentLevel = GetStartLevel();
+
+ // Add begin boundary
+ lineConstructor.Insert(new PlLinePoint(XBeginBoundary, currentLevel));
+
+ // Add point toe at river
+ lineConstructor.Insert(new PlLinePoint(XDikeToeAtRiver, currentLevel));
+
+ var firstSensor = SensorsSortedAlongProfile.FirstOrDefault();
+ if (firstSensor != null)
+ {
+ bool skipFirstSensor = WaterLevelSensor.RelativeLocation > firstSensor.RelativeLocation;
+
+ IEnumerable sensorsSortedAlongProfile = skipFirstSensor
+ ? SensorsSortedAlongProfile.Skip(1)
+ : SensorsSortedAlongProfile;
+
+ foreach (var sensor in sensorsSortedAlongProfile)
+ {
+ var x = GetSensorXValue(sensor);
+ var z = currentLevel = GetSensorZValue(sensor);
+
+ var point = new PlLinePoint(x, z) { Name = sensor.Name };
+
+ //Logger.LogDebug(string.Format("Point '{0}' added to PL Line", sensor.Name));
+
+ lineConstructor.Insert(point);
+ }
+ }
+
+ // Add end boundary
+ lineConstructor.Insert(new PlLinePoint(XEndBoundary, currentLevel));
+
+ return lineConstructor.CreatePlLine(PlLineType);
+ }
+
+ ///
+ /// Gets the water level at river.
+ ///
+ ///
+ /// If the position of the water level sensor is after the position of the
+ /// first sensor then the value of the latter is used
+ ///
+ public double WaterLevelAtRiver
+ {
+ get
+ {
+ var firstSensor = SensorsSortedAlongProfile.First();
+ double level = SensorValues[firstSensor];
+
+ if (WaterLevelSensor.RelativeLocation < firstSensor.RelativeLocation)
+ level = SensorValues[WaterLevelSensor];
+
+ level = level - Correction;
+
+ return level;
+ }
+ }
+
+ ///
+ /// Gets or sets the (stijghoogtedemping) correction value.
+ ///
+ ///
+ /// The correction.
+ ///
+ protected double Correction { get; set; }
+
+
+ ///
+ /// Gets the start level.
+ ///
+ ///
+ abstract protected double GetStartLevel();
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/LessThanOrEqualToSpecification.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/LessThanOrEqualToSpecification.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/LessThanOrEqualToSpecification.cs (revision 1581)
@@ -0,0 +1,39 @@
+// 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;
+
+namespace Deltares.DamEngine.Data.General.Specifications
+{
+ public class LessThanOrEqualToSpecification : ValueBoundSpecification where TValue : IComparable
+ {
+ public LessThanOrEqualToSpecification(string attributeName, TValue attributeValue)
+ : base(attributeName, attributeValue)
+ {
+ }
+
+ public override bool IsSatisfiedBy(TCandidate candidate)
+ {
+ var actual = this.GetCandidateTValue(candidate) as IComparable;
+ return (actual.CompareTo(this.AttributeValue) <= 0);
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Location.cs
===================================================================
diff -u -r1289 -r1581
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Location.cs (.../Location.cs) (revision 1289)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Location.cs (.../Location.cs) (revision 1581)
@@ -1594,6 +1594,14 @@
public override string ToString()
{
return Name;
- }
+ }
+ ///
+ /// Adds new sensor data.
+ ///
+ public void AddNewSensorData()
+ {
+ var factory = new SensorFactory();
+ SensorData = factory.CreateSensorLocation(this);
+ }
}
}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/TypeHelper.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/TypeHelper.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/TypeHelper.cs (revision 1581)
@@ -0,0 +1,48 @@
+// 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.Collections.Generic;
+using System.Linq;
+
+namespace Deltares.DamEngine.Data.Standard
+{
+ public static class TypeHelper
+ {
+ public static Type[] GetGenericArgumentsFromFirstGenericSuperClass(this Type type)
+ {
+ if (type.IsGenericType)
+ return type.GetGenericArguments();
+ Type type1 = ((IEnumerable)type.GetInterfaces()).FirstOrDefault((Func)(i =>
+ {
+ if (i.IsGenericType)
+ return i.GetGenericTypeDefinition() == typeof(IList<>);
+ return false;
+ }));
+ if (type1 != (Type)null)
+ return type1.GetGenericArguments();
+ Type baseType = type.BaseType;
+ if (!(baseType == (Type)null))
+ return baseType.GetGenericArgumentsFromFirstGenericSuperClass();
+ return new Type[0];
+ }
+ }
+}
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/ValidationException.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/ValidationException.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/ValidationException.cs (revision 1581)
@@ -0,0 +1,48 @@
+// 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.Runtime.Serialization;
+
+namespace Deltares.DamEngine.Data.General.Specifications
+{
+ [Serializable]
+ public class ValidationException : Exception
+ {
+ public ValidationException()
+ {
+ }
+
+ public ValidationException(string message) : base(message)
+ {
+ }
+
+ public ValidationException(string message, Exception inner) : base(message, inner)
+ {
+ }
+
+ protected ValidationException(
+ SerializationInfo info,
+ StreamingContext context) : base(info, context)
+ {
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/NotSpecification.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/NotSpecification.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/NotSpecification.cs (revision 1581)
@@ -0,0 +1,50 @@
+// 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.
+
+namespace Deltares.DamEngine.Data.General.Specifications
+{
+ public class NotSpecification : CompositeSpecification
+ {
+ private readonly ISpecification specification;
+
+ public NotSpecification(ISpecification specification)
+ {
+ this.specification = specification;
+ }
+
+ ///
+ /// Determines whether the candidate satisfies the specification.
+ ///
+ /// The candidate to test.
+ ///
+ /// true if the candidate satisfies the specification otherwise, false.
+ ///
+ public override bool IsSatisfiedBy(TCandidate candidate)
+ {
+ bool satisfied = !(this.specification.IsSatisfiedBy(candidate));
+ if (!satisfied)
+ {
+ base.Description = this.specification.Description;
+ }
+ return satisfied;
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj
===================================================================
diff -u -r1497 -r1581
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj (.../Deltares.DamEngine.Calculators.csproj) (revision 1497)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj (.../Deltares.DamEngine.Calculators.csproj) (revision 1581)
@@ -66,7 +66,17 @@
+
+
+
+
+
+
+
+
+
+
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLine4Creator.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLine4Creator.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLine4Creator.cs (revision 1581)
@@ -0,0 +1,72 @@
+// 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.Collections.Generic;
+using Deltares.DamEngine.Data.General;
+using Deltares.DamEngine.Data.General.Sensors;
+using Deltares.DamEngine.Data.General.Sensors.Specifications;
+
+namespace Deltares.DamEngine.Calculators.PlLinesCreator
+{
+ internal class SensorPlLine4Creator : SensorPlLine3Or4CreatorBase
+ {
+ public SensorPlLine4Creator(SensorLocation sensorLocation, IDictionary sensorValues)
+ : base(sensorLocation, sensorValues, PlLineType.Pl4)
+ {
+ }
+
+ ///
+ /// Gets the start z level of the PL line
+ ///
+ ///
+ /// The start level is based on the Pl4 configuration (locationdata or sensor)
+ /// and the position of the first sensor
+ ///
+ ///
+ protected override double GetStartLevel()
+ {
+ var locationAsDataSource = new UseLocationAsDataSource();
+ bool useLocationAsDataSource = locationAsDataSource.IsSatisfiedBy(SensorLocation.Pl4);
+ if (useLocationAsDataSource)
+ {
+ if (!SensorLocation.HeadPl4.HasValue)
+ throw new PlLinesCreatorException("Pl4 head has no value defined on this location");
+
+ return SensorLocation.HeadPl4.Value;
+ }
+
+ double level;
+
+ try
+ {
+ level = WaterLevelAtRiver;
+ }
+ catch (Exception e)
+ {
+ throw new PlLinesCreatorException("There was an error trying to read the water level", e);
+ }
+
+ return level;
+ }
+
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/AndSpecification.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/AndSpecification.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/AndSpecification.cs (revision 1581)
@@ -0,0 +1,56 @@
+// 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.
+
+namespace Deltares.DamEngine.Data.General.Specifications
+{
+ ///
+ /// The and specification is a compositable one.
+ ///
+ /// The type of the candidate.
+ public class AndSpecification : CompositeSpecification
+ {
+ private readonly ISpecification one;
+ private readonly ISpecification other;
+
+ public AndSpecification(ISpecification one, ISpecification other)
+ {
+ this.one = one;
+ this.other = other;
+ }
+
+ ///
+ /// Determines whether this candidate satisfies the specification AND the other.
+ ///
+ /// The candidate.
+ ///
+ /// true if the candidate satisfies the specification otherwise, false.
+ ///
+ public override bool IsSatisfiedBy(TCandidate candidate)
+ {
+ bool satisfied = (this.one.IsSatisfiedBy(candidate) && this.other.IsSatisfiedBy(candidate));
+ if (!satisfied)
+ {
+ base.Description = this.Description;
+ }
+ return satisfied;
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/Sensors/SensorLocationTests.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/Sensors/SensorLocationTests.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/Sensors/SensorLocationTests.cs (revision 1581)
@@ -0,0 +1,522 @@
+// 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.Collections.Generic;
+using Deltares.DamEngine.Data.General;
+using Deltares.DamEngine.Data.General.Sensors;
+using NUnit.Framework;
+
+namespace Deltares.DamEngine.Calculators.Tests.Sensors
+{
+ [TestFixture]
+ public class SensorLocationTest
+ {
+ readonly Location location = new Location();
+
+ #region Setup
+
+ [TestFixtureSetUp]
+ public void FixtureSetup()
+ {
+ }
+
+ [TestFixtureTearDown]
+ public void FixtureTearDown()
+ {
+ }
+
+ [SetUp]
+ public void TestSetup()
+ {
+ }
+
+ [TearDown]
+ public void TestTearDown()
+ {
+ }
+
+ #endregion
+
+
+ #region Sensor Or Location Data Value Tests
+
+ [Test]
+ public void GetValue_Pl1PlLineOffsetBelowDikeToeAtPolderAndDataSourceTypeIgnore_ShouldReturnNull()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double sensorValue = 1.1;
+ var sensorValues = new Dictionary { {sensor, sensorValue}};
+ var sensorLocation = CreateValidSensorLocation();
+
+ sensorLocation.Pl1PlLineOffsetBelowDikeToeAtPolder = DataSourceTypeSensors.Ignore;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl1PlLineOffsetBelowDikeToeAtPolder, sensorValues, sensor);
+
+ // assert
+ Assert.IsNull(actualValue);
+ }
+
+ [Test]
+ public void GetValue_Pl1PlLineOffsetBelowDikeToeAtPolderAndDataSourceTypeLocationData_ShouldReturnValue()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double testValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, testValue } };
+ var sensorLocation = CreateValidSensorLocation();
+ location.PlLineOffsetBelowDikeToeAtPolder = testValue;
+
+ sensorLocation.Pl1PlLineOffsetBelowDikeToeAtPolder = DataSourceTypeSensors.LocationData;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl1PlLineOffsetBelowDikeToeAtPolder, sensorValues, sensor);
+
+ // assert
+ Assert.AreEqual(testValue, actualValue);
+ }
+
+ [Test]
+ public void GetValue_Pl1PlLineOffsetBelowDikeToeAtPolderAndDataSourceTypeSensor_ShouldReturnNull()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double sensorValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, sensorValue } };
+ var sensorLocation = CreateValidSensorLocation();
+
+ sensorLocation.Pl1PlLineOffsetBelowDikeToeAtPolder = DataSourceTypeSensors.Sensor;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl1PlLineOffsetBelowDikeToeAtPolder, sensorValues, sensor);
+
+ // assert
+ Assert.IsNull(actualValue);
+ }
+
+ [Test]
+ public void GetValue_Pl1PLLineOffsetBelowDikeTopAtPolderAndDataSourceTypeIgnore_ShouldReturnNull()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double sensorValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, sensorValue } };
+ var sensorLocation = CreateValidSensorLocation();
+
+ sensorLocation.Pl1PlLineOffsetBelowDikeTopAtPolder = DataSourceTypeSensors.Ignore;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl1PlLineOffsetBelowDikeTopAtPolder, sensorValues, sensor);
+
+ // assert
+ Assert.IsNull(actualValue);
+ }
+
+ [Test]
+ public void GetValue_Pl1PLLineOffsetBelowDikeTopAtPolderAndDataSourceTypeLocationData_ShouldReturnValue()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double testValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, testValue } };
+ var sensorLocation = CreateValidSensorLocation();
+ location.PlLineOffsetBelowDikeTopAtPolder = testValue;
+
+ sensorLocation.Pl1PlLineOffsetBelowDikeTopAtPolder = DataSourceTypeSensors.LocationData;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl1PlLineOffsetBelowDikeTopAtPolder, sensorValues, sensor);
+
+ // assert
+ Assert.AreEqual(testValue, actualValue);
+ }
+
+ [Test]
+ public void GetValue_Pl1PLLineOffsetBelowDikeTopAtPolderAndDataSourceTypeSensor_ShouldReturnNull()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double sensorValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, sensorValue } };
+ var sensorLocation = CreateValidSensorLocation();
+
+ sensorLocation.Pl1PlLineOffsetBelowDikeTopAtPolder = DataSourceTypeSensors.Sensor;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl1PlLineOffsetBelowDikeTopAtPolder, sensorValues, sensor);
+
+ // assert
+ Assert.IsNull(actualValue);
+ }
+
+ [Test]
+ public void GetValue_Pl1PlLineOffsetBelowDikeTopAtRiverAndDataSourceTypeIgnore_ShouldReturnNull()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double sensorValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, sensorValue } };
+ var sensorLocation = CreateValidSensorLocation();
+
+ sensorLocation.Pl1PlLineOffsetBelowDikeTopAtRiver = DataSourceTypeSensors.Ignore;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl1PlLineOffsetBelowDikeTopAtRiver, sensorValues, sensor);
+
+ // assert
+ Assert.IsNull(actualValue);
+ }
+
+ [Test]
+ public void GetValue_Pl1PlLineOffsetBelowDikeTopAtRiverAndDataSourceTypeLocationData_ShouldReturnValue()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double testValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, testValue } };
+ var sensorLocation = CreateValidSensorLocation();
+ location.PlLineOffsetBelowDikeTopAtRiver = testValue;
+
+ sensorLocation.Pl1PlLineOffsetBelowDikeTopAtRiver = DataSourceTypeSensors.LocationData;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl1PlLineOffsetBelowDikeTopAtRiver, sensorValues, sensor);
+
+ // assert
+ Assert.AreEqual(testValue, actualValue);
+ }
+
+ [Test]
+ public void GetValue_Pl1PlLineOffsetBelowDikeTopAtRiverAndDataSourceTypeSensor_ShouldReturnNull()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double sensorValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, sensorValue } };
+ var sensorLocation = CreateValidSensorLocation();
+
+ sensorLocation.Pl1PlLineOffsetBelowDikeTopAtRiver = DataSourceTypeSensors.Sensor;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl1PlLineOffsetBelowDikeTopAtRiver, sensorValues, sensor);
+
+ // assert
+ Assert.IsNull(actualValue);
+ }
+
+ [Test]
+ public void GetValue_Pl1PLLineOffsetBelowShoulderBaseInsideAndDataSourceTypeIgnore_ShouldReturnNull()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double sensorValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, sensorValue } };
+ var sensorLocation = CreateValidSensorLocation();
+
+ sensorLocation.Pl1PlLineOffsetBelowShoulderBaseInside = DataSourceTypeSensors.Ignore;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl1PlLineOffsetBelowShoulderBaseInside, sensorValues, sensor);
+
+ // assert
+ Assert.IsNull(actualValue);
+ }
+
+ [Test]
+ public void GetValue_Pl1PLLineOffsetBelowShoulderBaseInsideAndDataSourceTypeLocationData_ShouldReturnValue()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double testValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, testValue } };
+ var sensorLocation = CreateValidSensorLocation();
+ location.PlLineOffsetBelowShoulderBaseInside = testValue;
+
+ sensorLocation.Pl1PlLineOffsetBelowShoulderBaseInside = DataSourceTypeSensors.LocationData;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl1PlLineOffsetBelowShoulderBaseInside, sensorValues, sensor);
+
+ // assert
+ Assert.AreEqual(testValue, actualValue);
+ }
+
+ [Test]
+ public void GetValue_Pl1PLLineOffsetBelowShoulderBaseInsideAndDataSourceTypeSensor_ShouldReturnNull()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double sensorValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, sensorValue } };
+ var sensorLocation = CreateValidSensorLocation();
+
+ sensorLocation.Pl1PlLineOffsetBelowShoulderBaseInside = DataSourceTypeSensors.Sensor;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl1PlLineOffsetBelowShoulderBaseInside, sensorValues, sensor);
+
+ // assert
+ Assert.IsNull(actualValue);
+ }
+
+ [Test]
+ public void GetValue_WaterLevelAtPolderAndDataSourceTypeIgnore_ShouldReturnNull()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double sensorValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, sensorValue } };
+ var sensorLocation = CreateValidSensorLocation();
+
+ sensorLocation.Pl1WaterLevelAtPolder = DataSourceTypeSensors.Ignore;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl1WaterLevelAtPolder, sensorValues, sensor);
+
+ // assert
+ Assert.IsNull(actualValue);
+ }
+
+ [Test]
+ public void GetValue_WaterLevelAtPolderAndDataSourceTypeLocationData_ShouldReturnValue()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double testValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, testValue } };
+ var sensorLocation = CreateValidSensorLocation();
+ location.PolderLevel = testValue;
+
+ sensorLocation.Pl1WaterLevelAtPolder = DataSourceTypeSensors.LocationData;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl1WaterLevelAtPolder, sensorValues, sensor);
+
+ // assert
+ Assert.AreEqual(testValue, actualValue);
+ }
+
+ [Test]
+ public void GetValue_WaterLevelAtPolderAndDataSourceTypeSensor_ShouldReturnValue()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double expectedValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, expectedValue } };
+ var sensorLocation = CreateValidSensorLocation();
+
+ sensorLocation.Pl1WaterLevelAtPolder = DataSourceTypeSensors.Sensor;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl1WaterLevelAtPolder, sensorValues, sensor);
+
+ // assert
+ Assert.AreEqual(expectedValue, actualValue);
+ }
+
+ [Test]
+ public void GetValue_WaterLevelAtRiverAndDataSourceTypeIgnore_ShouldReturnNull()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double sensorValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, sensorValue } };
+ var sensorLocation = CreateValidSensorLocation();
+
+ sensorLocation.Pl1WaterLevelAtRiver = DataSourceTypeSensors.Ignore;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl1WaterLevelAtRiver, sensorValues, sensor);
+
+ // assert
+ Assert.IsNull(actualValue);
+ }
+
+ [Test]
+ public void GetValue_WaterLevelAtRiverAndDataSourceTypeLocationData_ShouldReturnValue()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double testValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, testValue } };
+ var sensorLocation = CreateValidSensorLocation();
+
+ location.RiverLevel = testValue;
+ Assert.AreEqual(testValue, location.RiverLevel);
+
+ sensorLocation.Pl1WaterLevelAtRiver = DataSourceTypeSensors.LocationData;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl1WaterLevelAtRiver, sensorValues, sensor);
+
+ // assert
+ Assert.AreEqual(testValue, actualValue);
+ }
+
+ [Test]
+ public void GetValue_WaterLevelAtRiverAndDataSourceTypeSensor_ShouldReturnValue()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double expectedValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, expectedValue } };
+ var sensorLocation = CreateValidSensorLocation();
+
+ sensorLocation.Pl1WaterLevelAtRiver = DataSourceTypeSensors.Sensor;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl1WaterLevelAtRiver, sensorValues, sensor);
+
+ // assert
+ Assert.AreEqual(expectedValue, actualValue);
+ }
+
+ [Test]
+ public void GetValue_Pl3AndDataSourceTypeIgnore_ShouldReturnNull()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double sensorValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, sensorValue } };
+ var sensorLocation = CreateValidSensorLocation();
+
+ sensorLocation.Pl3 = DataSourceTypeSensors.Ignore;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl3, sensorValues, sensor);
+
+ // assert
+ Assert.IsNull(actualValue);
+ }
+
+ [Test]
+ public void GetValue_Pl3AndDataSourceTypeLocationData_ShouldReturnValue()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double testValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, testValue } };
+ var sensorLocation = CreateValidSensorLocation();
+
+ location.HeadPl3 = testValue;
+ sensorLocation.Pl3 = DataSourceTypeSensors.LocationData;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl3, sensorValues, sensor);
+
+ // assert
+ Assert.AreEqual(testValue, actualValue);
+ }
+
+ [Test]
+ public void GetValue_Pl3AndDataSourceTypeSensor_ShouldReturnValue()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double expectedValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, expectedValue } };
+ var sensorLocation = CreateValidSensorLocation();
+
+ sensorLocation.Pl3 = DataSourceTypeSensors.Sensor;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl3, sensorValues, sensor);
+
+ // assert
+ Assert.AreEqual(expectedValue, actualValue);
+ }
+
+ [Test]
+ public void GetValue_Pl4AndDataSourceTypeIgnore_ShouldReturnNull()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double sensorValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, sensorValue } };
+ var sensorLocation = CreateValidSensorLocation();
+
+ sensorLocation.Pl4 = DataSourceTypeSensors.Ignore;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl4, sensorValues, sensor);
+
+ // assert
+ Assert.IsNull(actualValue);
+ }
+
+ [Test]
+ public void GetValue_Pl4AndDataSourceTypeLocationData_ShouldReturnValue()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double testValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, testValue } };
+ var sensorLocation = CreateValidSensorLocation();
+
+ location.HeadPl4 = testValue;
+ sensorLocation.Pl4 = DataSourceTypeSensors.LocationData;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl4, sensorValues, sensor);
+
+ // assert
+ Assert.AreEqual(testValue, actualValue);
+ }
+
+ [Test]
+ public void GetValue_Pl4AndDataSourceTypeSensor_ShouldReturnValue()
+ {
+ // setup
+ var sensor = new Sensor();
+ const double expectedValue = 1.1;
+ var sensorValues = new Dictionary { { sensor, expectedValue } };
+ var sensorLocation = CreateValidSensorLocation();
+
+ sensorLocation.Pl4 = DataSourceTypeSensors.Sensor;
+
+ // call
+ var actualValue = sensorLocation.GetValue(x => x.Pl4, sensorValues, sensor);
+
+ // assert
+ Assert.AreEqual(expectedValue, actualValue);
+ }
+
+ #endregion
+
+
+
+ #region Helper methods
+
+ ///
+ /// Creates and initializes a valid sensor location for testing.
+ ///
+ ///
+ private SensorLocation CreateValidSensorLocation()
+ {
+ var factory = new SensorFactory();
+ var sensorLocation = factory.CreateSensorLocation(location);
+ return sensorLocation;
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/Sensors/SensorTest.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/Sensors/SensorTest.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/Sensors/SensorTest.cs (revision 1581)
@@ -0,0 +1,81 @@
+// 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 Deltares.DamEngine.Data.General.Sensors;
+using NUnit.Framework;
+
+namespace Deltares.DamEngine.Calculators.Tests.Sensors
+{
+ [TestFixture]
+ public class SensorTest
+ {
+ #region Setup
+
+ [TestFixtureSetUp]
+ public void FixtureSetup()
+ {
+ }
+
+ [TestFixtureTearDown]
+ public void FixtureTearDown()
+ {
+ }
+
+ [SetUp]
+ public void TestSetup()
+ {
+ }
+
+ [TearDown]
+ public void TestTearDown()
+ {
+ }
+
+ #endregion
+
+ [Test]
+ public void IsTransient_DefaultConstructedSensorAndNotSettingIDExplicitly_ShouldBeTrue()
+ {
+ // setup
+ var sensor = new Sensor();
+
+ // call
+ bool actual = sensor.IsTransient();
+
+ // assert
+ Assert.IsTrue(actual);
+ }
+
+ [Test]
+ public void IsTransient_DefaultSensorConstructedWithValidID_ShouldBeFalse()
+ {
+ // setup
+ var sensor = new Sensor { ID = 1 }; // ID should be greater then 0
+
+ // call
+ bool actual = sensor.IsTransient();
+
+ // assert
+ Assert.IsFalse(actual);
+ }
+
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/SensorFactory.cs
===================================================================
diff -u -r1122 -r1581
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/SensorFactory.cs (.../SensorFactory.cs) (revision 1122)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/SensorFactory.cs (.../SensorFactory.cs) (revision 1581)
@@ -37,6 +37,18 @@
return CreateSensorLocation(location, new Group());
}
+ internal Sensor CreateUniqueSensor(IEnumerable sensors)
+ {
+ if (sensors == null) throw new ArgumentNullException("sensors");
+
+ // TODO: see of these calls can be combined for performance reason
+ var id = sensors.GetUniqueID(x => x.ID);
+
+ Sensor sensor = new Sensor { ID = id, Type = SensorType.PiezometricHead };
+ UniqueNameProvider.ProvideUniqueName(new List(sensors), sensor);
+
+ return sensor;
+ }
///
/// Creates a sensor location.
///
@@ -55,8 +67,8 @@
Pl1PlLineOffsetBelowDikeTopAtRiver = DataSourceTypeSensors.LocationData,
Pl1PlLineOffsetBelowShoulderBaseInside = DataSourceTypeSensors.LocationData,
Pl1WaterLevelAtPolder = DataSourceTypeSensors.LocationData,
- PL3 = DataSourceTypeSensors.LocationData,
- PL4 = DataSourceTypeSensors.LocationData
+ Pl3 = DataSourceTypeSensors.LocationData,
+ Pl4 = DataSourceTypeSensors.LocationData
};
}
}
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/TypeExtensions.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/TypeExtensions.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/Standard/TypeExtensions.cs (revision 1581)
@@ -0,0 +1,36 @@
+// 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.Reflection;
+
+namespace Deltares.DamEngine.Data.Standard
+{
+ public static class TypeExtensions
+ {
+ public static bool HasDefaultConstructor(this Type type)
+ {
+ if (type.IsValueType)
+ return true;
+ return type.GetConstructor(Type.EmptyTypes) != (ConstructorInfo)null;
+ }
+ }
+}
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/ValueBoundSpecification.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/ValueBoundSpecification.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/ValueBoundSpecification.cs (revision 1581)
@@ -0,0 +1,91 @@
+// 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.
+
+namespace Deltares.DamEngine.Data.General.Specifications
+{
+ ///
+ /// With this class a value of an object bound to a property can be tested against the specification.
+ /// This is a variant of the ParameterizedSpecification
+ ///
+ /// The candidate type
+ /// The candidate property type
+ public abstract class ValueBoundSpecification : SpecificationBase
+ {
+ private readonly string attributeName;
+ private readonly TValue attributeValue;
+ private TValue candidateValue;
+
+ protected ValueBoundSpecification(string attributeName, TValue attributeValue)
+ {
+ this.attributeName = attributeName;
+ this.attributeValue = attributeValue;
+ }
+
+ ///
+ /// Gets the attribute value.
+ ///
+ public TValue AttributeValue
+ {
+ get { return attributeValue; }
+ }
+
+ ///
+ /// Gets the candidate value.
+ ///
+ public TValue CandidateValue
+ {
+ get { return candidateValue; }
+ }
+
+ ///
+ /// Gets the candidate string value.
+ ///
+ /// The candidate.
+ ///
+ protected string GetCandidateStringValue(TCandidate candidate)
+ {
+ return GetCandidateObjectValue(candidate).ToString();
+ }
+
+ ///
+ /// Gets the candidate T value.
+ ///
+ /// The candidate.
+ ///
+ protected TValue GetCandidateTValue(TCandidate candidate)
+ {
+ if (candidateValue.Equals(default(TValue)))
+ candidateValue = (TValue) GetCandidateObjectValue(candidate);
+
+ return candidateValue;
+ }
+
+ ///
+ /// Gets the candidate object value.
+ ///
+ /// The candidate.
+ ///
+ private object GetCandidateObjectValue(TCandidate candidate)
+ {
+ return candidate.GetType().GetProperty(attributeName).GetValue(candidate, null);
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/SensorRepository.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/SensorRepository.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Sensors/SensorRepository.cs (revision 1581)
@@ -0,0 +1,153 @@
+// 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.Collections.Generic;
+using Deltares.DamEngine.Data.Standard;
+
+namespace Deltares.DamEngine.Data.General.Sensors
+{
+ public class SensorRepository
+ {
+ private SensorLocation sensorLocation;
+ private readonly HashSet names;
+ private readonly HashSet ids;
+
+ private SensorRepository()
+ {
+ names = new HashSet();
+ ids = new HashSet();
+ }
+
+ public SensorRepository(Location location) : this()
+ {
+ if (location.SensorData == null)
+ {
+ location.AddNewSensorData();
+ }
+
+ sensorLocation = location.SensorData;
+
+ if (sensorLocation.Group == null)
+ sensorLocation.Group = new Group();
+ }
+
+ internal Group Group
+ {
+ get { return sensorLocation.Group; }
+ }
+
+ public IEnumerable Sensors
+ {
+ get { return Group.Selection; }
+ }
+
+ internal int GetUniqueSensorId()
+ {
+ return Group.Selection.GetUniqueID(x => x.ID);
+ }
+
+ ///
+ /// Adds a new sensor to the location sensor group.
+ ///
+ /// The created Sensor
+ public Sensor AddNew()
+ {
+ var factory = new SensorFactory();
+ Sensor sensor = factory.CreateUniqueSensor(Group.Selection);
+ AddSensor(sensor);
+ return sensor;
+ }
+
+ ///
+ /// Adds the collection of sensors to the group.
+ ///
+ /// The sensor needs to meet the business rules before it can be added
+ /// The sensor collection to add to the group of this location.
+ ///
+ ///
+ public void Add(IEnumerable sensors)
+ {
+ if (sensors == null) throw new ArgumentNullException("sensors");
+ foreach (var sensor in sensors)
+ Add(sensor);
+ }
+
+ ///
+ /// Adds the specified sensor.
+ ///
+ /// The sensor needs to meet the business rules before it can be added
+ /// The sensor to add.
+ ///
+ ///
+ public void Add(Sensor sensor)
+ {
+ if (sensor == null)
+ throw new ArgumentNullException("sensor");
+
+ if (string.IsNullOrWhiteSpace(sensor.Name))
+ throw new ArgumentException("Cant add this sensor because its name is empty");
+
+ if (sensor.IsTransient())
+ throw new ArgumentException("Cant add this sensor because its ID is not valid. The ID must be greater then -1");
+
+ if (ids.Contains(sensor.ID))
+ throw new ArgumentException("Cant add this sensor becuase its ID is already added");
+
+ if (names.Contains(sensor.Name))
+ throw new ArgumentException("Cant add this sensor because its name is already used");
+
+ AddSensor(sensor);
+ }
+
+ ///
+ /// Adds the sensor unconditionally
+ ///
+ /// The sensor.
+ private void AddSensor(Sensor sensor)
+ {
+ ids.Add(sensor.ID);
+ names.Add(sensor.Name);
+ sensorLocation.Group.Add(sensor);
+ }
+
+ ///
+ /// Serializes the state of this repository to a XML string.
+ ///
+ ///
+ internal string Serialize()
+ {
+ throw new NotImplementedException();
+ // return sensorLocation.Serialize();
+ }
+
+ ///
+ /// Deserializes the specified XML to restore the state of this repository
+ ///
+ /// The XML.
+ internal static SensorRepository Deserialize(string xml)
+ {
+ throw new NotImplementedException();
+// if (string.IsNullOrWhiteSpace(xml)) throw new ArgumentException("xml");
+// return new SensorRepository() { sensorLocation = SensorLocation.Deserialize(xml) };
+ }
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Deltares.DamEngine.Data.csproj
===================================================================
diff -u -r1497 -r1581
--- DamEngine/trunk/src/Deltares.DamEngine.Data/Deltares.DamEngine.Data.csproj (.../Deltares.DamEngine.Data.csproj) (revision 1497)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/Deltares.DamEngine.Data.csproj (.../Deltares.DamEngine.Data.csproj) (revision 1581)
@@ -77,8 +77,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163,6 +184,9 @@
+
+
+
Index: DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/ISpecification.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/ISpecification.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/General/Specifications/ISpecification.cs (revision 1581)
@@ -0,0 +1,70 @@
+// 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.
+
+namespace Deltares.DamEngine.Data.General.Specifications
+{
+ ///
+ ///
+ ///
+ public interface ISpecification
+ {
+ ///
+ /// Gets or sets the name of the specification. (Short description)
+ ///
+ ///
+ /// The name string value should be a required property for each specification.
+ ///
+ string Name { get; set; }
+
+ ///
+ /// Gets or sets the description of the specification. (Long description)
+ ///
+ ///
+ /// The description string value.
+ ///
+ string Description { get; set; }
+
+ ///
+ /// Determines whether the candidate satisfies the specification.
+ ///
+ /// The candidate.
+ ///
+ /// true if the candidate satisfies the specification otherwise, false.
+ ///
+ bool IsSatisfiedBy(object candidate);
+ }
+
+ ///
+ ///
+ ///
+ /// The type of the candidate.
+ public interface ISpecification : ISpecification
+ {
+ ///
+ /// Determines whether the candidate satisfies the specification.
+ ///
+ /// The candidate.
+ ///
+ /// true if the candidate satisfies the specification otherwise, false.
+ ///
+ bool IsSatisfiedBy(TCandidate candidate);
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/IPlLineCreator.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/IPlLineCreator.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/IPlLineCreator.cs (revision 1581)
@@ -0,0 +1,30 @@
+// 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 Deltares.DamEngine.Data.General.PlLines;
+
+namespace Deltares.DamEngine.Calculators.PlLinesCreator
+{
+ public interface IPlLineCreator
+ {
+ PlLine CreatePlLine();
+ }
+}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLine3Creator.cs
===================================================================
diff -u
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLine3Creator.cs (revision 0)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SensorPlLine3Creator.cs (revision 1581)
@@ -0,0 +1,76 @@
+// 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.Collections.Generic;
+using Deltares.DamEngine.Data.General.Sensors;
+using Deltares.DamEngine.Data.General;
+using Deltares.DamEngine.Data.General.Sensors.Specifications;
+
+namespace Deltares.DamEngine.Calculators.PlLinesCreator
+{
+ internal class SensorPlLine3Creator : SensorPlLine3Or4CreatorBase
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The sensor location.
+ /// The sensor values.
+ public SensorPlLine3Creator(SensorLocation sensorLocation, IDictionary sensorValues)
+ : base(sensorLocation, sensorValues, PlLineType.Pl3)
+ {
+ }
+
+ ///
+ /// Gets the start z level of the PL line
+ ///
+ ///
+ /// The start level is based on the Pl3 configuration (location data or sensor)
+ /// and the position of the first sensor
+ ///
+ ///
+ protected override double GetStartLevel()
+ {
+ double currentLevel;
+ bool useLocationAsDataSource = new UseLocationAsDataSource().IsSatisfiedBy(SensorLocation.Pl3);
+ if (useLocationAsDataSource)
+ {
+ if (!SensorLocation.HeadPl3.HasValue)
+ throw new PlLinesCreatorException("Pl3 head has no value defined on this location");
+
+ currentLevel = SensorLocation.HeadPl3.Value;
+ }
+ else
+ {
+ try
+ {
+ currentLevel = WaterLevelAtRiver;
+ }
+ catch (Exception e)
+ {
+ throw new PlLinesCreatorException("There was an error trying to read the water level", e);
+ }
+ }
+
+ return currentLevel;
+ }
+ }
+}
\ No newline at end of file