Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilProfile2D.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilProfile2D.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilProfile2D.cs (revision 282)
@@ -0,0 +1,188 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.Geometry;
+using Deltares.DamEngine.Data.Standard.Language;
+using Deltares.DamEngine.Data.Standard.Validation;
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// 2D Soil Profile Object
+ ///
+ public class SoilProfile2D : SoilProfile
+ {
+ private readonly Dictionary cachedSoilProfiles1D = new Dictionary();
+ private GeometryData geometry = new GeometryData();
+ private readonly List surfaces = new List();
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public SoilProfile2D()
+ {
+ Name = LocalizationManager.GetTranslatedText(this, "DefaultNameSoilProfile2D");
+ }
+
+ ///
+ /// Gets the surfaces.
+ ///
+ ///
+ /// The surfaces.
+ ///
+ [Validate]
+ public IList Surfaces
+ {
+ get
+ {
+ return surfaces;
+ }
+ }
+
+ ///
+ /// Gets or sets the geometry.
+ ///
+ ///
+ /// The geometry.
+ ///
+ public GeometryData Geometry
+ {
+ get
+ {
+ return geometry;
+ }
+ set
+ {
+ geometry = value;
+ }
+ }
+
+ ///
+ /// Gets the soil profile 1D at the given X.
+ ///
+ /// The x.
+ /// Soil Profile 1D
+ public SoilProfile1D GetSoilProfile1D(double x)
+ {
+ const double diff = 0.001;
+ SoilProfile1D soilProfile = GetCachedSoilProfile1D(x);
+
+ if (soilProfile != null)
+ {
+ return soilProfile;
+ }
+
+ soilProfile = new SoilProfile1D
+ {
+ Name = "Generated at x = " + x + " from " + Name
+ };
+ var detector = new LayerDetector(Surfaces);
+ if (x > Geometry.Right)
+ {
+ x = Geometry.Right - diff;
+ }
+ if (x < Geometry.Left)
+ {
+ x = Geometry.Left + diff;
+ }
+
+ detector.DetermineMaterials(x);
+
+ if (detector.LayerList.Count > 0)
+ {
+ soilProfile.BottomLevel = detector.LayerList[detector.LayerList.Count - 1].EndPoint.Z;
+ for (int i = 0; i < detector.LayerList.Count; i++)
+ {
+ var layer = new SoilLayer1D(detector.LayerList[i].Soil, detector.LayerList[i].StartPoint.Z)
+ {
+ IsAquifer = detector.LayerList[i].IsAquifer
+ };
+ soilProfile.Layers.Add(layer);
+ }
+ }
+
+
+ cachedSoilProfiles1D[x] = soilProfile;
+
+ return soilProfile;
+ }
+
+ ///
+ /// Get the surface from the point
+ ///
+ /// The point which is supposed to be within the soil layer
+ /// Surface
+ public SoilLayer2D GetSoilLayer(Point2D point)
+ {
+ for (int i = 0; i < Surfaces.Count; i++)
+ {
+ SoilLayer2D surface = Surfaces[i];
+ GeometryLoop surfaceLine = surface.GeometrySurface.OuterLoop;
+ if (surfaceLine.IsPointInLoopArea(point))
+ {
+ bool found = true;
+
+ // if point lies in an innerloop it belongs to another area
+ foreach (var innerloop in surface.GeometrySurface.InnerLoops)
+ {
+ if (innerloop.IsPointInLoopArea(point))
+ {
+ found = false;
+ }
+ }
+
+ if (found)
+ {
+ return surface;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return Name;
+ }
+
+ ///
+ /// Gets the cached soil profile1 d.
+ ///
+ /// The x.
+ ///
+ private SoilProfile1D GetCachedSoilProfile1D(double x)
+ {
+ if (cachedSoilProfiles1D.ContainsKey(x))
+ {
+ return cachedSoilProfiles1D[x];
+ }
+ return null;
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Deltares.DamEngine.Data.csproj
===================================================================
diff -u -r278 -r282
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Deltares.DamEngine.Data.csproj (.../Deltares.DamEngine.Data.csproj) (revision 278)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Deltares.DamEngine.Data.csproj (.../Deltares.DamEngine.Data.csproj) (revision 282)
@@ -74,16 +74,23 @@
+
+
+
+
+
+
+
@@ -94,17 +101,25 @@
+
+
+
+
+
+
+
+
@@ -120,8 +135,10 @@
+
+
@@ -132,6 +149,7 @@
+
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DAMFailureMechanismeCalculator.cs
===================================================================
diff -u -r276 -r282
--- dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DAMFailureMechanismeCalculator.cs (.../DAMFailureMechanismeCalculator.cs) (revision 276)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Calculators/General/DAMFailureMechanismeCalculator.cs (.../DAMFailureMechanismeCalculator.cs) (revision 282)
@@ -20,6 +20,7 @@
using Deltares.Dam.Data;
using Deltares.DamEngine.Data.Design;
using Deltares.DamEngine.Data.General;
+using Deltares.DamEngine.Data.General.NWO;
using Deltares.DamEngine.Data.Geometry;
using Deltares.DamEngine.Data.Geotechnics;
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/LayerDetector.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/LayerDetector.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/LayerDetector.cs (revision 282)
@@ -0,0 +1,367 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.Geometry;
+using Deltares.DamEngine.Data.Standard;
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ ///When publisherEventArgs vertical is drawn in the Geometry, this reports the intersection layers.
+ ///
+ /// Step 1: To Determine the possibility of Surface and Vertical intersection, Min/Max of each surface
+ /// is checked with Vertical's X coordinate.
+ /// Step 2: Intersection Points of each surface with the vertical are determined and added to pointlist
+ /// in sorted order (greatest Y at first).
+ /// Step 3: For forming the Intersection Curves, the consecutive points in the pointlist are checked if
+ /// their mid-point lies in the surface and not in the innerloop. They are stored in the sorted order.
+ ///
+ public class LayerDetector
+ {
+ private readonly List intersectionSurfacesList = new List();
+ private readonly List layerList = new List();
+ private readonly List pointList = new List();
+ private readonly IList soilSurfaces;
+
+ private double verticalXCoordinate;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The soil surfaces.
+ public LayerDetector(IList soilSurfaces)
+ {
+ this.soilSurfaces = soilSurfaces;
+ }
+
+ ///
+ /// Gets the layer list.
+ ///
+ ///
+ /// The layer list.
+ ///
+ public List LayerList
+ {
+ get
+ {
+ return layerList;
+ }
+ }
+
+
+ ///
+ /// Determines the materials.
+ ///
+ /// A vertical x coordinate.
+ public void DetermineMaterials(double aVerticalXCoordinate)
+ {
+ verticalXCoordinate = aVerticalXCoordinate;
+
+ // The detection process
+ StartDetection();
+ }
+
+ private void StartDetection()
+ {
+ ClearLists();
+ GetIntersectionPointList();
+ DeleteDuplicateCurve();
+ }
+
+ private void GetIntersectionPointList()
+ {
+ foreach (var surface in soilSurfaces)
+ {
+ if (intersectionSurfacesList.Contains(surface) == false)
+ {
+ foreach (var curve in surface.GeometrySurface.OuterLoop.CurveList)
+ {
+ FindIntersections(curve.HeadPoint, curve.EndPoint, surface);
+ }
+ // check if it has inner loops
+ if (surface.GeometrySurface.InnerLoops.Count > 0)
+ {
+ List loopList = surface.GeometrySurface.InnerLoops;
+ foreach (var loop in loopList)
+ {
+ foreach (var curve in loop.CurveList)
+ {
+ FindIntersections(curve.HeadPoint, curve.EndPoint, surface);
+ }
+ }
+ }
+ //create intersection curves
+ if (pointList.Count > 0)
+ {
+ GetLayerList();
+ pointList.Clear();
+ }
+ }
+ }
+ }
+
+ // finds intersections with regard to publisherEventArgs curve
+ private void FindIntersections(Point2D aHeadpoint, Point2D aEndPoint, SoilLayer2D aSurfaceRefKey)
+ {
+ double maxvalue = 999999999.0;
+ double minvalue = -999999999.0;
+ var verticalHeadPoint = new Point2D(verticalXCoordinate, maxvalue);
+ var verticalEndPoint = new Point2D(verticalXCoordinate, minvalue);
+ Point2D intersectionPoint;
+
+ LineIntersection intersectionResult = Routines2D.DetermineIf2DLinesIntersectStrickly(verticalHeadPoint.X, verticalHeadPoint.Z,
+ verticalEndPoint.X, verticalEndPoint.Z, aHeadpoint.X, aHeadpoint.Z, aEndPoint.X, aEndPoint.Z, out intersectionPoint);
+
+ if (intersectionResult == LineIntersection.Intersects)
+ {
+ AddPointToList(new LayerIntersectionPoint(intersectionPoint, aSurfaceRefKey));
+ }
+ else if (intersectionResult == LineIntersection.NoIntersection || intersectionResult == LineIntersection.Parallel)
+ {
+ const double cEpsilon = 1.0e-3;
+ if ((Routines2D.DoesPointExistInLine(verticalHeadPoint.X, verticalHeadPoint.Z, verticalEndPoint.X, verticalEndPoint.Z,
+ aHeadpoint.X, aHeadpoint.Z, cEpsilon)) && (Routines2D.DoesPointExistInLine(verticalHeadPoint.X, verticalHeadPoint.Z,
+ verticalEndPoint.X, verticalEndPoint.Z, aEndPoint.X, aEndPoint.Z, cEpsilon)))
+ {
+ AddPointToList(new LayerIntersectionPoint(aHeadpoint, aSurfaceRefKey));
+ AddPointToList(new LayerIntersectionPoint(aEndPoint, aSurfaceRefKey));
+ }
+ }
+ }
+
+ private void GetLayerList()
+ {
+ int pointCount = pointList.Count;
+
+ if (pointCount > 1)
+ {
+ object point1 = null;
+
+ for (int index = 0; index < pointCount; index++)
+ {
+ if (point1 == null)
+ {
+ point1 = pointList[index];
+ }
+ else
+ {
+ //point not same condition
+ bool notSameCondition = ((pointList[index].IntersectionPoint.X.IsNearEqual((
+ (LayerIntersectionPoint) point1).IntersectionPoint.X)) && (pointList[index].IntersectionPoint.Z.IsNearEqual((
+ (LayerIntersectionPoint) point1).IntersectionPoint.Z)));
+
+ if (notSameCondition == false)
+ {
+ object point2 = pointList[index];
+ FindLayer((LayerIntersectionPoint) point1, (LayerIntersectionPoint) point2);
+ point1 = pointList[index];
+ }
+ }
+ }
+ }
+ }
+
+ private void ClearLists()
+ {
+ pointList.Clear();
+ layerList.Clear();
+ intersectionSurfacesList.Clear();
+ }
+
+ // To make it top to bottom
+ private void CheckTopToBottom(ref Point2D aHeadPoint, ref Point2D aEndPoint)
+ {
+ if (aHeadPoint.Z.IsLessThan(aEndPoint.Z))
+ {
+ var temp = aHeadPoint;
+ aHeadPoint = aEndPoint;
+ aEndPoint = temp;
+ }
+ }
+
+ // Finds what kind of passage does this curve make with regard to the surface
+ private void FindLayer(LayerIntersectionPoint aPoint1, LayerIntersectionPoint aPoint2)
+ {
+ var midPoint = new GeometryPoint()
+ {
+ X = (aPoint1.IntersectionPoint.X + aPoint2.IntersectionPoint.X)/2,
+ Z = (aPoint1.IntersectionPoint.Z + aPoint2.IntersectionPoint.Z)/2
+ };
+
+ // check where the mid point lies
+ PointInPolygon polygonResult = Routines2D.CheckIfPointIsInPolygon(aPoint1.SurfaceRefKey.GeometrySurface.OuterLoop,
+ midPoint.X, midPoint.Z);
+
+
+ var startPoint = aPoint1.IntersectionPoint;
+ var endPoint = aPoint2.IntersectionPoint;
+
+ Soil soil = aPoint1.SurfaceRefKey.Soil;
+ var isAquifer = aPoint1.SurfaceRefKey.IsAquifer;
+ if (polygonResult == PointInPolygon.InsidePolygon || polygonResult == PointInPolygon.OnPolygonEdge)
+ {
+ bool isPresentInInnerLoop = false;
+ List innerLoopList = aPoint1.SurfaceRefKey.GeometrySurface.InnerLoops;
+ foreach (var innerLoop in innerLoopList)
+ {
+ PointInPolygon innerPolygonResult = Routines2D.CheckIfPointIsInPolygon(innerLoop, midPoint.X, midPoint.Z);
+ if (innerPolygonResult != PointInPolygon.OutsidePolygon)
+ {
+ isPresentInInnerLoop = true;
+ }
+ }
+ if (isPresentInInnerLoop == false)
+ {
+ var layerCurve = new Layer(startPoint, endPoint, soil)
+ {
+ IsAquifer = isAquifer
+ };
+ AddLayerToList(layerCurve);
+ }
+ }
+ }
+
+ // Adds the LayerIntersectionCurve in publisherEventArgs sorted order - Top to bottom
+ private void AddLayerToList(Layer aLayer)
+ {
+ int count = layerList.Count;
+ bool isAdded = false;
+ var startPoint = aLayer.StartPoint;
+ var endPoint = aLayer.EndPoint;
+ CheckTopToBottom(ref startPoint, ref endPoint);
+ aLayer.StartPoint = startPoint;
+ aLayer.EndPoint = endPoint;
+
+ if (count == 0)
+ {
+ layerList.Add(aLayer);
+ }
+ else
+ {
+ for (int index = 0; index < count; index++)
+ {
+ if (aLayer.StartPoint.Z.IsGreaterThanOrEqualTo(layerList[index].StartPoint.Z))
+ {
+ layerList.Insert(index, aLayer);
+ isAdded = true;
+ break;
+ }
+ }
+ if (isAdded == false)
+ {
+ layerList.Add(aLayer);
+ }
+ }
+ }
+
+ // Adds the LayerIntersectionPoints (ignores duplicates when found within same surface)
+ private void AddPointToList(LayerIntersectionPoint aPoint)
+ {
+ if (intersectionSurfacesList.Contains(aPoint.SurfaceRefKey) == false)
+ {
+ intersectionSurfacesList.Add(aPoint.SurfaceRefKey);
+ }
+
+ int count = pointList.Count;
+ bool isPointFound = false;
+ if (count > 0)
+ {
+ for (int index = 0; index < count; index++) // to find duplicate
+ {
+ if ((aPoint.IntersectionPoint.X.IsNearEqual(pointList[index].IntersectionPoint.X))
+ && (aPoint.IntersectionPoint.Z.IsNearEqual(pointList[index].IntersectionPoint.Z))
+ && (aPoint.SurfaceRefKey == pointList[index].SurfaceRefKey))
+ {
+ isPointFound = true;
+ break;
+ }
+ }
+ if (isPointFound == false) // to be added in the sorted order Z greater at the top
+ {
+ bool isAdded = false;
+ for (int index = 0; index < count; index++)
+ {
+ if (aPoint.IntersectionPoint.Z.IsGreaterThanOrEqualTo(pointList[index].IntersectionPoint.Z))
+ {
+ pointList.Insert(index, aPoint);
+ isAdded = true;
+ break;
+ }
+ }
+
+ if (isAdded == false)
+ {
+ pointList.Add(aPoint);
+ }
+ }
+ }
+ else
+ {
+ pointList.Add(aPoint);
+ }
+ }
+
+ ///
+ /// if two surfaces share the same curve choose any one surface
+ ///
+ private void DeleteDuplicateCurve()
+ {
+ var duplicateList = new List();
+ int curveCount = layerList.Count;
+ object curve1 = null;
+
+ for (int index = 0; index < curveCount; index++)
+ {
+ if (curve1 == null)
+ {
+ curve1 = layerList[index];
+ }
+ else
+ {
+ var curve2 = layerList[index];
+
+ // check if there is overlapping
+ var curveOne = (Layer) curve1;
+ var curveTwo = curve2;
+
+ if (curveOne.StartPoint.Z.IsGreaterThanOrEqualTo(curveTwo.StartPoint.Z) && curveOne.EndPoint.Z.IsLessThanOrEqualTo(curveTwo.EndPoint.Z))
+ {
+ duplicateList.Add(layerList[index]);
+ }
+ // Case - No space between two consecutive curves
+ else
+ {
+ curve1 = layerList[index];
+ }
+ }
+ }
+
+ for (int index = 0; index < duplicateList.Count; index++)
+ {
+ if (layerList.Contains(duplicateList[index]))
+ {
+ layerList.Remove(duplicateList[index]);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilSurfaceProfile.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilSurfaceProfile.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilSurfaceProfile.cs (revision 282)
@@ -0,0 +1,601 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Delta Shell Light Library.
+//
+// The Delta Shell Light Library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Xml.Serialization;
+using Deltares.DamEngine.Data.Geometry;
+using Deltares.DamEngine.Data.Standard;
+using Deltares.DamEngine.Data.Standard.Validation;
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ ///
+ /// A SoilSurfaceProfile constructs a SoilProfile2D object by merging an existing SoilProfile1D with a SurfaceLine
+ ///
+ /// Note that actual contruction of 2D based on surface line and 1D happens on setting the properties using dirty flags.
+ ///
+ public class SoilSurfaceProfile : SoilProfile2D
+ {
+ private Soil dikeEmbankmentMaterial;
+ private bool dirty;
+ private bool initial = true;
+ private SoilProfile1D soilProfile;
+ private SoilProfile1D orgSoilProfile;
+ private GeometryPointString surfaceLine;
+ private SurfaceLine2 surfaceLine2;
+ private bool createSettlementZones;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public SoilSurfaceProfile()
+ {
+ Name = "Soil Surface Profile";
+ }
+
+ ///
+ /// Gets or sets the surface line.
+ ///
+ ///
+ /// The surface line.
+ ///
+ [Validate]
+ public GeometryPointString SurfaceLine
+ {
+ get
+ {
+ return surfaceLine;
+ }
+ set
+ {
+ surfaceLine = value;
+ dirty = true;
+ }
+ }
+
+ ///
+ /// Gets or sets the surface line2.
+ ///
+ [Validate]
+ public SurfaceLine2 SurfaceLine2
+ {
+ get
+ {
+ return surfaceLine2;
+ }
+ set
+ {
+ surfaceLine2 = value;
+ if (surfaceLine2 != null)
+ {
+ SurfaceLine = surfaceLine2.Geometry;
+ }
+ else
+ {
+ SurfaceLine = null;
+ }
+ dirty = true;
+ }
+ }
+
+ ///
+ /// Gets or sets the soil profile.
+ ///
+ ///
+ /// The soil profile.
+ ///
+ [Validate]
+ public SoilProfile1D SoilProfile
+ {
+ get
+ {
+ return orgSoilProfile;
+ }
+ set
+ {
+ orgSoilProfile = value;
+ dirty = true;
+ }
+ }
+
+ ///
+ /// Gets or sets the dike material.
+ ///
+ ///
+ /// The dike material.
+ ///
+ public Soil DikeEmbankmentMaterial
+ {
+ get
+ {
+ return dikeEmbankmentMaterial;
+ }
+ set
+ {
+ dikeEmbankmentMaterial = value;
+ dirty = true;
+ }
+ }
+
+ ///
+ /// List of preconsolidation stresses
+ ///
+ [XmlIgnore]
+ public override List PreconsolidationStresses
+ {
+ get
+ {
+ if (orgSoilProfile != null)
+ {
+ return orgSoilProfile.PreconsolidationStresses;
+ }
+ return null;
+ }
+ }
+
+ ///
+ /// Gets the surfaces.
+ ///
+ ///
+ /// The surfaces.
+ ///
+ [XmlIgnore]
+ [Validate]
+ public override IList Surfaces
+ {
+ get
+ {
+ if (initial || dirty)
+ {
+ UpdateLayers();
+ }
+ return base.Surfaces;
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating whether to [create settlement zones].
+ ///
+ ///
+ /// true if [create settlement zones]; otherwise, false.
+ ///
+ public bool CreateSettlementZones
+ {
+ get
+ {
+ return createSettlementZones;
+ }
+ set
+ {
+ createSettlementZones = value;
+ }
+ }
+
+ ///
+ /// Generates a 1D profile at a given x
+ ///
+ ///
+ /// Generated 1D soil profile
+ public override SoilProfile1D GetSoilProfile1D(double x)
+ {
+ if (initial || dirty)
+ {
+ initial = false;
+
+ UpdateLayers();
+ }
+
+ // Try to obtain a cached soil profile (performance optimization)
+ var soilProfile1D = GetCachedSoilProfile1D(x);
+ if (soilProfile1D != null)
+ {
+ return soilProfile1D;
+ }
+
+ // Otherwise, create and configure a new soil profile
+ soilProfile1D = new SoilProfile1D();
+
+ double top = SurfaceLine.GetZAtX(x);
+ soilProfile1D.BottomLevel = soilProfile.BottomLevel;
+
+ if (top > soilProfile.TopLevel)
+ {
+ var emptyTopLayer = new SoilLayer1D(null, top)
+ {
+ SoilProfile = soilProfile1D
+ };
+ soilProfile1D.Layers.Add(emptyTopLayer);
+ }
+
+ for (int i = 0; i < soilProfile.Layers.Count; i++)
+ {
+ SoilLayer1D layer = soilProfile.Layers[i];
+ if (layer.BottomLevel < top)
+ {
+ // Perform without publishing events because otherwise the soil profile cache would get lost
+ DataEventPublisher.InvokeWithoutPublishingEvents(() =>
+ {
+ var newLayer = new SoilLayer1D(layer.Soil, Math.Min(layer.TopLevel, top))
+ {
+ IsAquifer = layer.IsAquifer,
+ WaterpressureInterpolationModel = layer.WaterpressureInterpolationModel,
+ SoilProfile = soilProfile1D
+ };
+ soilProfile1D.Layers.Add(newLayer);
+ });
+ }
+ }
+
+ // Add the newly created soil profile to the cache
+ cachedSoilProfiles1D[x] = soilProfile1D;
+
+ return soilProfile1D;
+ }
+
+ ///
+ /// Returns a that represents this instance (either Name or SoilProfile).
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ if (!string.IsNullOrEmpty(Name))
+ {
+ return Name;
+ }
+ if (orgSoilProfile != null)
+ {
+ return orgSoilProfile.ToString();
+ }
+ return "Soil Surface Profile with null Soil Profile";
+ }
+
+ ///
+ /// Converts to soil profile2D.
+ ///
+ ///
+ public SoilProfile2D ConvertToSoilProfile2D()
+ {
+ var soilProfile2D = new SoilProfile2D
+ {
+ Geometry = Geometry
+ };
+ soilProfile2D.Surfaces.AddRange(Surfaces);
+ soilProfile2D.Name = Name;
+ return soilProfile2D;
+
+ }
+
+ #region IDisposable
+
+ public override void Dispose()
+ {
+ DataEventPublisher.OnAfterChange -= DataEventPublisherListener;
+ // TODO: Base also subscribed to this event: reuse?
+ DataEventPublisher.OnDataListModified -= DataEventPublisherListener;
+ // TODO: Base also subscribed to this event: reuse?
+ DataEventPublisher.OnActionCompleted -= DataEventPublisher_OnActionCompleted;
+
+ var disposableSurfaceLine = surfaceLine as IDisposable;
+ if (disposableSurfaceLine != null)
+ {
+ disposableSurfaceLine.Dispose();
+ }
+
+ base.Dispose();
+ }
+
+ #endregion
+
+ ///
+ /// Handles the events of the DataEventPublisher control:
+ /// sets dirty to true if sender is SoilLayer1D and Properties[0] is SoilProfile
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ private void DataEventPublisherListener(object sender, PublishEventArgs e)
+ {
+ if (!dirty && NeedsUpdate(sender))
+ {
+ if (!(sender is SoilLayer1D && e.Properties.Length > 0 && e.Properties[0].Equals("SoilProfile")))
+ {
+ dirty = true;
+ }
+ }
+ if (orgSoilProfile != null && ReferenceEquals(sender, orgSoilProfile.Layers) && e is DataListModifiedArgs)
+ {
+ UpdateLayers();
+ }
+ }
+
+ ///
+ /// Handles the OnActionCompleted event of the DataEventPublisher control: Updates layers.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ private void DataEventPublisher_OnActionCompleted(object sender, PublishEventArgs e)
+ {
+ if (dirty && !initial)
+ {
+ UpdateLayers();
+ }
+ }
+
+ ///
+ /// Checks whether an update is necessary
+ ///
+ ///
+ /// true if an update is necessary; otherwise, false.
+ ///
+ private bool NeedsUpdate(object sender)
+ {
+ if (sender == null)
+ {
+ return false;
+ }
+
+ // check surface line
+ if (sender == surfaceLine
+ || (surfaceLine != null && sender == surfaceLine.Points))
+ {
+ return true;
+ }
+
+ // check soil profile
+ if (sender == orgSoilProfile)
+ {
+ return true;
+ }
+
+ // check soil layers in soil profile
+ if (sender is SoilLayer1D
+ && orgSoilProfile != null
+ && orgSoilProfile.Layers.Any(layer => layer == sender))
+ {
+ return true;
+ }
+
+ // check points in surface line
+ if (sender is GeometryPoint && surfaceLine != null)
+ {
+ return surfaceLine.Points.Any(point => point == sender);
+ }
+
+ return false;
+ }
+
+ ///
+ /// Updates the dike material.
+ ///
+ private void UpdateDikeMaterial()
+ {
+ if (soilProfile != null && SurfaceLine != null)
+ {
+ double topSurfaceLine = SurfaceLine.GetMaxZ();
+ if (!double.IsNaN(topSurfaceLine) && (soilProfile.Layers.Count == 0 || soilProfile.TopLevel < topSurfaceLine))
+ {
+ double newTopLevel = topSurfaceLine + 0.5;
+
+ if (soilProfile.Layers.Count > 0 && soilProfile.Layers[0].Soil == DikeEmbankmentMaterial)
+ {
+ SoilLayer1D dikeMaterialLayer = soilProfile.Layers[0];
+ dikeMaterialLayer.TopLevel = newTopLevel;
+ }
+ else
+ {
+ // Add toplayer of dikematerial
+ var newLayer = new SoilLayer1D
+ {
+ TopLevel = newTopLevel,
+ Soil = DikeEmbankmentMaterial,
+ };
+
+ // special handling for dummy soil profiles
+ if (soilProfile.Layers.Count == 0 && DikeEmbankmentMaterial == null)
+ {
+ soilProfile.BottomLevel = SurfaceLine.GetMinZ() - 1;
+ }
+
+ soilProfile.Layers.Insert(0, newLayer);
+ soilProfile.EnsureLastLayerHasHeight();
+ }
+ }
+ }
+ }
+
+ ///
+ /// Adds the layer geometry.
+ ///
+ /// The data.
+ /// The layer.
+ /// The minimum x.
+ /// The maximum x.
+ private static void AddLayerGeometry(GeometryData data, SoilLayer1D layer, double minX, double maxX)
+ {
+ var top = layer.TopLevel;
+ var bottom = layer.BottomLevel;
+
+ if (Math.Abs(layer.BottomLevel - layer.SoilProfile.BottomLevel) < GeometryConstants.Accuracy)
+ {
+ bottom = data.Bottom;
+ }
+
+ var bottomLeft = new GeometryPoint(minX, 0, bottom);
+ var bottomRight = new GeometryPoint(maxX, 0, bottom);
+ var topLeft = new GeometryPoint(minX, 0, top);
+ var topRight = new GeometryPoint(maxX, 0, top);
+
+ data.Points.Add(bottomLeft);
+ data.Points.Add(bottomRight);
+ data.Points.Add(topLeft);
+ data.Points.Add(topRight);
+
+ data.Curves.Add(new GeometryCurve(bottomLeft, bottomRight));
+ data.Curves.Add(new GeometryCurve(bottomRight, topRight));
+ data.Curves.Add(new GeometryCurve(topRight, topLeft));
+ data.Curves.Add(new GeometryCurve(topLeft, bottomLeft));
+ }
+
+ private void AddSurfaceLineGeometry(GeometryData data)
+ {
+ var current = surfaceLine.Points[0];
+ data.Points.Add(current);
+ for (int i = 1; i < surfaceLine.Points.Count; ++i)
+ {
+ var previous = current;
+ current = surfaceLine.Points[i];
+
+ data.Points.Add(current);
+ data.Curves.Add(new GeometryCurve(previous, current));
+ }
+ }
+
+ private void AddSettlementZones(GeometryData locGeometry)
+ {
+
+ if (surfaceLine2 != null && surfaceLine2.HasDike())
+ {
+ var xToeRiver = surfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).X;
+ AddVerticalAt(locGeometry, xToeRiver);
+ var xTopRiver = surfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).X;
+ var xRiver = xToeRiver + (xTopRiver - xToeRiver) / 3.0;
+ AddVerticalAt(locGeometry, xRiver);
+
+ var xToePolder = surfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X;
+ var xTopPolder = surfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X;
+ var xPolder = xTopPolder + 2 * (xToePolder - xTopPolder) / 3.0;
+ AddVerticalAt(locGeometry, xPolder);
+ AddVerticalAt(locGeometry, xToePolder);
+ }
+ }
+
+ private void AddVerticalAt(GeometryData aGeometry, double x)
+ {
+ const double ymax = 100000.0;
+ var topX = new GeometryPoint(x, 0, ymax);
+ var bottomX = new GeometryPoint(x, 0, -ymax);
+ aGeometry.Points.Add(topX);
+ aGeometry.Points.Add(bottomX);
+ aGeometry.Curves.Add(new GeometryCurve(topX, bottomX));
+ aGeometry.NewlyEffectedCurves.Add(aGeometry.Curves.Last());
+ }
+
+ private void BuildGeometryModel()
+ {
+ if (surfaceLine == null
+ || soilProfile == null
+ || soilProfile.Layers.Count == 0
+ || surfaceLine.GetMaxZ() < soilProfile.BottomLevel
+ || surfaceLine.Points.Count < 2)
+ {
+ return;
+ }
+
+ var bounds = SurfaceLine.GetGeometryBounds();
+ double minX = bounds.Left;
+ double maxX = bounds.Right;
+
+ Geometry.Clear();
+ Geometry.Left = minX;
+ Geometry.Right = maxX;
+ Geometry.Bottom = Math.Min(soilProfile.BottomLevel, surfaceLine.GetMinZ() - 1);
+
+ // add profile geometry
+ soilProfile.Layers.Sort();
+ foreach (var layer in soilProfile.Layers)
+ {
+ AddLayerGeometry(Geometry, layer, minX, maxX);
+ }
+
+ // add surface line geometry
+ AddSurfaceLineGeometry(Geometry);
+
+ // add the extra lines to create the settlementzones if required
+ if (createSettlementZones)
+ {
+ AddSettlementZones(Geometry);
+ }
+ Geometry.NewlyEffectedPoints.AddRange(Geometry.Points);
+ Geometry.NewlyEffectedCurves.AddRange(Geometry.Curves);
+ Geometry.RegenerateGeometry();
+ Geometry.DeleteLooseCurves();
+ }
+
+ private void RebuildSurfaces(GeometryData locGeometry)
+ {
+ Surfaces.Clear();
+ if (locGeometry == null || surfaceLine == null)
+ {
+ return;
+ }
+ var gu = new GeotechnicsUtilities();
+ gu.RemoveGeometryDataAboveSurfaceLine(ref locGeometry, surfaceLine);
+ foreach (var geometrySurface in locGeometry.Surfaces)
+ {
+ var bounds = geometrySurface.GetGeometryBounds();
+ var z = (bounds.Top + bounds.Bottom) * 0.5;
+
+ var soilLayer = soilProfile.GetLayerAt(z);
+
+ if (soilLayer != null)
+ {
+ Surfaces.Add(new SoilLayer2D
+ {
+ GeometrySurface = geometrySurface,
+ IsAquifer = soilLayer.IsAquifer,
+ WaterpressureInterpolationModel = soilLayer.WaterpressureInterpolationModel,
+ Soil = soilLayer.Soil,
+ SoilProfile = this
+ });
+ }
+ }
+ }
+
+ ///
+ /// Updates the layers.
+ ///
+ private void UpdateLayers()
+ {
+ dirty = false;
+ initial = false;
+
+ // Clear all cached soil profiles
+ cachedSoilProfiles1D.Clear();
+
+ DataEventPublisher.InvokeWithoutPublishingEvents(() =>
+ {
+ if (orgSoilProfile != null)
+ {
+ soilProfile = (SoilProfile1D)orgSoilProfile.Clone();
+
+ UpdateDikeMaterial();
+ BuildGeometryModel();
+ RebuildSurfaces(Geometry);
+ }
+ });
+ DataEventPublisher.DataListModified(Surfaces);
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SurfaceLineException.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SurfaceLineException.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SurfaceLineException.cs (revision 282)
@@ -0,0 +1,35 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Delta Shell Light Library.
+//
+// The Delta Shell Light Library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// Surface Line Exception
+ ///
+ public class SurfaceLineException : System.Exception
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The message that describes the error.
+ public SurfaceLineException(string message) : base(message) {}
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Sensors/SensorLocation.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Sensors/SensorLocation.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Sensors/SensorLocation.cs (revision 282)
@@ -0,0 +1,473 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2012 Deltares. All rights reserved.
+//
+// B. Faassen
+// barry.faassen@deltares.nl
+// 1-8-2012
+// n.a.
+//-----------------------------------------------------------------------
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Xml.Serialization;
+using Deltares.DamEngine.Data.Geotechnics;
+using Deltares.DamEngine.Data.Standard;
+
+namespace Deltares.DamEngine.Data.General.Sensors
+{
+ ///
+ /// Association class for sensor data and a location
+ ///
+ [Serializable]
+ public class SensorLocation
+ {
+ #region Business Rules
+
+ ///
+ /// Specication to test if the value of the candidate is valid
+ ///
+ internal class IgnoreOrLocationData : PredicateSpecification
+ {
+ public IgnoreOrLocationData()
+ : base(x => x == DataSourceTypeSensors.Ignore || x == DataSourceTypeSensors.LocationData)
+ {
+ Description = "Only Ignore or LocationData value allowed for this property.";
+ }
+ }
+
+ ///
+ /// Specication to test if the value of the candidate is valid
+ ///
+ internal class SensorOrLocationData : PredicateSpecification
+ {
+ public SensorOrLocationData()
+ : base(x => x == DataSourceTypeSensors.Sensor || x == DataSourceTypeSensors.LocationData)
+ {
+ Description = "Only Sensor or LocationData value allowed for this property.";
+ }
+ }
+
+ #endregion
+
+ ///
+ /// Constructor is needed for XML deserialization
+ ///
+
+ public SensorLocation()
+ {
+ PL1WaterLevelAtRiver = DataSourceTypeSensors.LocationData;
+ PL1WaterLevelAtPolder = DataSourceTypeSensors.LocationData;
+ }
+
+ private Group sensorGroup;
+
+ ///
+ /// Gets the PL line offset below dike top at river.
+ ///
+ public double PLLineOffsetBelowDikeTopAtRiver
+ {
+ get { return Location.PlLineOffsetBelowDikeTopAtRiver; }
+ }
+
+ ///
+ /// Gets the PL line offset below dike top at polder.
+ ///
+ public double PLLineOffsetBelowDikeTopAtPolder
+ {
+ get { return Location.PLLineOffsetDryBelowDikeTopAtPolder; }
+ }
+
+ ///
+ /// Gets the PL line offset below dike toe at polder.
+ ///
+ public double PLLineOffsetBelowDikeToeAtPolder
+ {
+ get { return Location.PlLineOffsetBelowDikeToeAtPolder; }
+ }
+
+ ///
+ /// Gets the PL line offset dry below shoulder base inside.
+ ///
+ public double PLLineOffsetDryBelowShoulderBaseInside
+ {
+ get { return Location.PlLineOffsetBelowShoulderBaseInside; }
+ }
+
+ ///
+ /// Gets or sets the DAM location.
+ ///
+ ///
+ /// The location.
+ ///
+ [XmlIgnore]
+ [Specification(typeof(NotNullSpecification))]
+ public Location Location { get; set; }
+
+ ///
+ /// Gets the location Name.
+ ///
+ ///
+ /// If the Name is empty it could indicate that there is no reference
+ /// to a valid location
+ ///
+ [XmlIgnore]
+ public string LocationName
+ {
+ get { return (Location != null) ? Location.Name : string.Empty; }
+ }
+
+ ///
+ /// Gets or sets the sensor group.
+ ///
+ ///
+ /// The group.
+ ///
+ [Specification(typeof(NotNullSpecification))]
+ public Group Group
+ {
+ get { return sensorGroup; }
+ set
+ {
+ sensorGroup = value;
+ }
+ }
+
+ public void ResetGroupID(int id)
+ {
+ sensorGroup.ID = id;
+ }
+
+ ///
+ /// Gets the group ID.
+ ///
+ ///
+ /// If the ID has value -1 then the there is no valid reference (null)
+ /// or the group is transient.
+ ///
+ [XmlIgnore]
+ public int GroupID
+ {
+ get
+ {
+ if (sensorGroup == null)
+ return -1;
+
+ return sensorGroup.ID;
+ }
+ }
+
+ ///
+ /// Gets the sensor selection.
+ ///
+ [XmlIgnore]
+ public IEnumerable Sensors
+ {
+ get
+ {
+ if (sensorGroup == null)
+ return new Sensor[0];
+
+ return sensorGroup.Selection;
+ }
+ }
+
+ ///
+ /// Gets or sets the PL3 data source type.
+ ///
+ ///
+ /// The PL3.
+ ///
+ [Specification(typeof(SensorOrLocationData))]
+ public DataSourceTypeSensors PL3 { get; set; }
+
+ ///
+ /// Gets or sets the PL4 data source type.
+ ///
+ ///
+ /// The PL4.
+ ///
+ [Specification(typeof(SensorOrLocationData))]
+ public DataSourceTypeSensors PL4 { get; set; }
+
+
+ ///
+ /// Gets or sets the outer water level data source type.
+ ///
+ ///
+ /// The outer water level.
+ ///
+ [Specification(typeof(SensorOrLocationData))]
+ public DataSourceTypeSensors PL1WaterLevelAtRiver { get; set; }
+
+ ///
+ /// 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.
+ ///
+ [Specification(typeof(IgnoreOrLocationData))]
+ public DataSourceTypeSensors PL1PLLineOffsetBelowDikeTopAtRiver { get; set; }
+
+ ///
+ /// 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.
+ ///
+ [Specification(typeof(IgnoreOrLocationData))]
+ public DataSourceTypeSensors PL1PLLineOffsetBelowDikeTopAtPolder { get; set; }
+
+ ///
+ /// Gets or sets the PL1 PL line offset below shoulder base inside data source type
+ ///
+ ///
+ /// 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.
+ ///
+ ///
+ /// 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.
+ ///
+ ///
+ /// The PL1 polder level.
+ ///
+ [Specification(typeof(SensorOrLocationData))]
+ public DataSourceTypeSensors PL1WaterLevelAtPolder { get; set; }
+
+ ///
+ /// Gets the sensor count.
+ ///
+ public int SensorCount
+ {
+ get
+ {
+ return sensorGroup == null ? 0 : Group.SensorCount;
+ }
+ }
+
+ public SurfaceLine2 SurfaceLine
+ {
+ get { return Location.SurfaceLine2; }
+ }
+
+ public double RiverLevel
+ {
+ get { return Location.RiverLevel; }
+ }
+
+ public double PolderLevel
+ {
+ get { return Location.PolderLevel; }
+ }
+
+ public double? HeadPl3
+ {
+ get { return Location.HeadPl3; }
+ }
+
+ public double? HeadPl4
+ {
+ get { return Location.HeadPl4; }
+ }
+
+ public string Alias { get; set; } // ToDo Tom/Kin Sun Waarvoor nodig? Wordt nergens gebruikt. Kan gewoon weg!?
+
+ public string Profile
+ {
+ get; //{ return SoilProfile2D } ;
+ set;
+ }
+
+ public string MStabFile
+ {
+ get; //{ return SoilProfile2D } ;
+ set;
+ }
+
+ ///
+ /// Gets the PiezometricHead type sensors sorted by relative location along profile.
+ ///
+ /// 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;
+ }
+
+ ///
+ /// Builds the relative location table.
+ ///
+ ///
+ internal IDictionary BuildRelativeLocationTable()
+ {
+ var surfaceLevelOutside = SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelOutside);
+ if (surfaceLevelOutside == null)
+ throw new InvalidOperationException("No SurfaceLevelOutside point on surface line defined");
+
+ double startPoint = surfaceLevelOutside.X;
+
+ var dict = new Dictionary();
+ foreach (Sensor sensor in Sensors)
+ {
+ double relativeLocation = startPoint + (Location.XRdDikeLine - sensor.XRd);
+ dict.Add(sensor, relativeLocation);
+ }
+ return dict;
+ }
+
+ internal static class MemberNames
+ {
+ internal static readonly string OffsetBelowDikeToeAtPolder = StaticReflection.GetMemberName(x => x.PL1PLLineOffsetBelowDikeToeAtPolder);
+ internal static readonly string OffsetBelowDikeTopAtPolder = StaticReflection.GetMemberName(x => x.PL1PLLineOffsetBelowDikeTopAtPolder);
+ internal static readonly string OffsetBelowDikeTopAtRiver = StaticReflection.GetMemberName(x => x.PL1PLLineOffsetBelowDikeTopAtRiver);
+ 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);
+ }
+
+ public double? GetValue(Expression> expression, IDictionary sensorValues, Sensor sensor)
+ {
+ if (sensorValues == null) throw new ArgumentNullException("sensorValues");
+ if (sensor == null) throw new ArgumentNullException("sensor");
+
+ if (!sensorValues.ContainsKey(sensor))
+ throw new ArgumentException("The given sensor is not an item/key in the table of sensor values");
+
+ var memberName = StaticReflection.GetMemberName(expression);
+
+ if (memberName == MemberNames.OffsetBelowDikeToeAtPolder)
+ {
+ if (PL1PLLineOffsetBelowDikeToeAtPolder == DataSourceTypeSensors.LocationData)
+ return Location.PlLineOffsetBelowDikeToeAtPolder;
+ }
+
+ if (memberName == MemberNames.OffsetBelowDikeTopAtPolder)
+ {
+ if (PL1PLLineOffsetBelowDikeTopAtPolder == DataSourceTypeSensors.LocationData)
+ return Location.PlLineOffsetBelowDikeTopAtPolder;
+ }
+
+ if (memberName == MemberNames.OffsetBelowDikeTopAtRiver)
+ {
+ if (PL1PLLineOffsetBelowDikeTopAtRiver == DataSourceTypeSensors.LocationData)
+ return Location.PlLineOffsetBelowDikeTopAtRiver;
+ }
+
+ if (memberName == MemberNames.OffsetBelowShoulderBaseInside)
+ {
+ if (PL1PLLineOffsetBelowShoulderBaseInside == DataSourceTypeSensors.LocationData)
+ return Location.PlLineOffsetBelowShoulderBaseInside;
+ }
+
+ if (memberName == MemberNames.WaterLevelAtRiver)
+ {
+ if (PL1WaterLevelAtRiver == DataSourceTypeSensors.LocationData)
+ return Location.RiverLevel;
+
+ if (PL1WaterLevelAtRiver == DataSourceTypeSensors.Sensor)
+ return sensorValues[sensor];
+ }
+
+ if (memberName == MemberNames.PolderLevel)
+ {
+ if (PL1WaterLevelAtPolder == DataSourceTypeSensors.LocationData)
+ return Location.PolderLevel;
+
+ if (PL1WaterLevelAtPolder == DataSourceTypeSensors.Sensor)
+ return sensorValues[sensor];
+ }
+
+ if (memberName == MemberNames.PL3)
+ {
+ if (PL3 == DataSourceTypeSensors.LocationData)
+ return Location.HeadPl3;
+
+ if (PL3 == DataSourceTypeSensors.Sensor)
+ return sensorValues[sensor];
+ }
+
+ if (memberName == MemberNames.PL4)
+ {
+ if (PL4 == DataSourceTypeSensors.LocationData)
+ return Location.HeadPl4;
+
+ if (PL4 == DataSourceTypeSensors.Sensor)
+ return sensorValues[sensor];
+ }
+
+
+ return null;
+ }
+
+ ///
+ /// Determines whether this instance is valid.
+ ///
+ ///
+ /// true if this instance is valid; otherwise, false.
+ ///
+ public bool IsValid()
+ {
+ return !Validator.Validate(this).Any();
+ }
+
+ ///
+ /// Gets or sets the GetGroups function (injectable list, for UI purposes).
+ ///
+ ///
+ /// The list of available Groups.
+ ///
+ [XmlIgnore]
+ public static Func> GetGroups { get; set; }
+
+ private ICollection GetGroupsDomain()
+ {
+ if (GetGroups == null)
+ {
+ return null;
+ }
+
+ return GetGroups(this).ToList();
+ }
+ }
+}
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Validator.cs
===================================================================
diff -u -r278 -r282
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Validator.cs (.../SurfaceLine2Validator.cs) (revision 278)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Validator.cs (.../SurfaceLine2Validator.cs) (revision 282)
@@ -52,7 +52,7 @@
///
/// The surfaceline being evaluated.
/// The collection of validation results.
- private IEnumerable ValidateGeometryPointsAreOrdered(SurfaceLine2 surfaceline)
+ public IEnumerable ValidateGeometryPointsAreOrdered(SurfaceLine2 surfaceline)
{
if (!ArePointsAscending(surfaceline))
{
@@ -67,7 +67,7 @@
///
/// The surfaceline being evaluated.
/// The collection of validation results.
- private IEnumerable ValidateCharacteristicPointsAreOrdered(SurfaceLine2 surfaceline)
+ public IEnumerable ValidateCharacteristicPointsAreOrdered(SurfaceLine2 surfaceline)
{
if (!AreAllCharacteristicPointsXCoordinatesAscending(surfaceline))
{
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/ListExtension.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/ListExtension.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/ListExtension.cs (revision 282)
@@ -0,0 +1,515 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Delta Shell Light Library.
+//
+// The Delta Shell Light Library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Deltares.DamEngine.Data.Standard
+{
+ ///
+ /// Defines a library of common IList, ICollection or IEnumerable extension methods
+ ///
+ public static class ListExtensions
+ {
+ public static bool IsEmpty(IEnumerable collection)
+ {
+ return collection == null || !collection.Any();
+ }
+
+ ///
+ /// Gets or creates rows of a given sequence i.e. the sequence will be transformed to a grid
+ ///
+ /// The element type in the sequence
+ /// The sequence to transform
+ /// The size of one row
+ /// A sequence of rows containing the number of rowSize elements
+ public static IEnumerable> Rows(this IEnumerable sequence, int rowSize)
+ {
+ int count = sequence.Count();
+
+ for (int i = 0; i < count/rowSize; i++)
+ {
+ yield return sequence.Skip(i*rowSize).Take(rowSize);
+ }
+ }
+
+ ///
+ /// Removes the conditionally.
+ ///
+ ///
+ /// The collection.
+ /// The predicate.
+ public static void RemoveConditionally(this IList collection, Predicate predicate)
+ {
+ var work = new Queue();
+ foreach (var item in collection)
+ {
+ if (predicate(item))
+ {
+ work.Enqueue(item);
+ }
+ }
+
+ while (work.Count > 0)
+ {
+ var item = work.Dequeue();
+ collection.Remove(item);
+ }
+ }
+
+ ///
+ /// Adds a range of items to the list without adding null elements
+ ///
+ /// The type of the elements in the list
+ /// The collection to add the items to
+ /// The items (collection) to add to the list
+ public static void AddRangeLeavingNullElementsOut(this IList collection, IEnumerable items)
+ where T : class
+ {
+ AddRangeConditionally(collection, items, x => x != null);
+ }
+
+ ///
+ /// Gets the unique ID. It fills in gaps of the collection
+ ///
+ /// The type if the collection item
+ /// The collection to inspect.
+ /// The lambda that can gets the id from a item in the collection.
+ /// A unique ID greater then 0
+ public static int GetUniqueID(this IEnumerable collection, Func idGetter)
+ {
+ if (collection == null)
+ {
+ throw new ArgumentNullException("collection");
+ }
+
+ const int tmp = 1;
+ bool any = collection.Any(item => idGetter(item) == tmp);
+ if (!any)
+ {
+ return tmp;
+ }
+
+ int min = 1, max = 2; // min is inclusive, max is exclusive/untested
+
+ while (collection.Any(item => idGetter(item) == max))
+ {
+ min = max;
+ max *= 2;
+ }
+
+ while (max != min + 1)
+ {
+ int pivot = (max + min)/2;
+ if (collection.Any(item => idGetter(item) == pivot))
+ {
+ min = pivot;
+ }
+ else
+ {
+ max = pivot;
+ }
+ }
+
+ return max;
+ }
+
+ ///
+ /// Adds a range of items to the list
+ ///
+ /// The type of the elements in the list
+ /// The list to add the items to
+ /// The items (collection) to add to the list
+ public static void AddRange(this IList theListToAddTo, IEnumerable collection)
+ {
+ if (theListToAddTo == null)
+ {
+ throw new ArgumentNullException("theListToAddTo");
+ }
+
+ if (collection == null)
+ {
+ throw new ArgumentNullException("collection");
+ }
+
+ foreach (var item in collection)
+ {
+ theListToAddTo.Add(item);
+ }
+ }
+
+ ///
+ /// Sorts the items in a list
+ ///
+ /// The type of the elements in the list
+ /// the list to be sorted
+ public static void Sort(this IList sortList)
+ {
+ if (sortList is ISortableList)
+ {
+ ((ISortableList) sortList).Sort();
+ }
+ else if (sortList is List)
+ {
+ ((List) sortList).Sort();
+ }
+ else
+ {
+ var workList = new List();
+ foreach (var item in sortList)
+ {
+ workList.Add(item);
+ }
+
+ workList.Sort();
+
+ sortList.Clear();
+ foreach (var item in workList)
+ {
+ sortList.Add(item);
+ }
+ }
+ }
+
+ public static void Sort(this IList sortList, Comparison func)
+ {
+ if (sortList is ISortableList)
+ {
+ ((ISortableList) sortList).Sort();
+ }
+ else if (sortList is List)
+ {
+ ((List) sortList).Sort();
+ }
+ else
+ {
+ var workList = new List();
+ foreach (var item in sortList)
+ {
+ workList.Add(item);
+ }
+
+ workList.Sort(func);
+
+ // Silence events for custom IList implementations, as we do not want to fire events for clear or add:
+ sortList.Clear();
+ foreach (var item in workList)
+ {
+ sortList.Add(item);
+ }
+ }
+ }
+
+ ///
+ /// Sorts the items in a list in reversed order
+ ///
+ /// The type of the elements in the list
+ /// the list to be sorted
+ public static void Reverse(this IList sortList)
+ {
+ if (sortList is ISortableList)
+ {
+ ((ISortableList) sortList).Reverse();
+ }
+ else if (sortList is List)
+ {
+ ((List) sortList).Reverse();
+ }
+ else
+ {
+ var workList = new List();
+ foreach (var item in sortList)
+ {
+ workList.Add(item);
+ }
+
+ workList.Reverse();
+
+ sortList.Clear();
+ foreach (var item in workList)
+ {
+ sortList.Add(item);
+ }
+ }
+ }
+
+ public static T Find(this IList findList, Predicate match)
+ {
+ if (findList is IFindList)
+ {
+ return ((IFindList) findList).Find(match);
+ }
+ else if (findList is List)
+ {
+ return ((List) findList).Find(match);
+ }
+ else
+ {
+ throw new NotImplementedException("Find");
+ }
+ }
+
+ public static List FindAll(this IList findList, Predicate match)
+ {
+ if (findList is IFindList)
+ {
+ return ((IFindList) findList).FindAll(match);
+ }
+ else if (findList is List)
+ {
+ return ((List) findList).FindAll(match);
+ }
+ else
+ {
+ throw new NotImplementedException("FindAll");
+ }
+ }
+
+ public static int FindIndex(this IList findList, Predicate match)
+ {
+ if (findList is IFindList)
+ {
+ return ((IFindList) findList).FindIndex(match);
+ }
+ else if (findList is List)
+ {
+ return ((List) findList).FindIndex(match);
+ }
+ else
+ {
+ throw new NotImplementedException("Find");
+ }
+ }
+
+ public static T FindLast(this IList findList, Predicate match)
+ {
+ if (findList is IFindList)
+ {
+ return ((IFindList) findList).FindLast(match);
+ }
+ else if (findList is List)
+ {
+ return ((List) findList).FindLast(match);
+ }
+ else
+ {
+ throw new NotImplementedException("Find");
+ }
+ }
+
+ public static int FindLastIndex(this IList findList, Predicate match)
+ {
+ if (findList is IFindList)
+ {
+ return ((IFindList) findList).FindLastIndex(match);
+ }
+ if (findList is List)
+ {
+ return ((List) findList).FindLastIndex(match);
+ }
+ else
+ {
+ throw new NotImplementedException("Find");
+ }
+ }
+
+ ///
+ /// Adds a range of items to the list
+ ///
+ /// The type of the elements in the list
+ /// The list to add the items to
+ /// The items (collection) to add to the list
+ /// The items predicate or requirement that needs to be true before the item can be added
+ public static void AddRangeConditionally(this IList collection, IEnumerable items,
+ Func predicate)
+ where T : class
+ {
+ if (collection == null)
+ {
+ throw new ArgumentNullException("collection");
+ }
+
+ if (items == null)
+ {
+ throw new ArgumentNullException("items");
+ }
+
+ if (predicate == null)
+ {
+ throw new ArgumentNullException("predicate");
+ }
+
+ foreach (var item in items)
+ {
+ if (predicate(item))
+ {
+ collection.Add(item);
+ }
+ }
+ }
+
+ ///
+ /// Adds a range of items to the list
+ ///
+ /// The type of the elements in the list
+ /// The type of the elements in the collection
+ /// The collection to add the items to
+ /// The items to add to the list
+ ///
+ public static void AddRange(this IList collection,
+ IEnumerable items,
+ Func selector)
+ {
+ if (items == null)
+ {
+ throw new ArgumentNullException("collection");
+ }
+
+ if (items == null)
+ {
+ throw new ArgumentNullException("items");
+ }
+
+ if (selector == null)
+ {
+ throw new ArgumentNullException("selector");
+ }
+
+ foreach (var item in items)
+ {
+ collection.Add(selector(item));
+ }
+ }
+
+ ///
+ /// Maps a list of a specific type to a list with another type
+ ///
+ /// The source list element type
+ /// The destination type
+ /// The source list
+ /// The selector that returns the destination type instance
+ /// A collection with the mapped items
+ public static IEnumerable MapTo(
+ this IEnumerable source, Func selector)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException("source");
+ }
+
+ if (selector == null)
+ {
+ throw new ArgumentNullException("selector");
+ }
+
+ foreach (var item in source)
+ {
+ yield return selector(item);
+ }
+ }
+
+ ///
+ /// Removes null elements from a list
+ ///
+ ///
+ ///
+ public static void RemoveNullElements(this IList list)
+ where T : class
+ {
+ int index;
+ while ((index = list.IndexOf(null)) >= 0)
+ {
+ list.RemoveAt(index);
+ }
+ }
+
+ ///
+ /// Performs a binary search on the specified collection.
+ ///
+ /// The type of the item.
+ /// The type of the searched item.
+ /// The list to be searched.
+ /// The value to search for.
+ /// The comparer that is used to compare the value with the list items.
+ ///
+ public static int BinarySearch(this IList list, TSearch value, Func comparer)
+ {
+ if (list == null)
+ {
+ throw new ArgumentNullException("list");
+ }
+ if (comparer == null)
+ {
+ throw new ArgumentNullException("comparer");
+ }
+
+ int lower = 0;
+ int upper = list.Count - 1;
+
+ int middle = lower;
+ while (lower <= upper)
+ {
+ middle = lower + (upper - lower)/2;
+ int comparisonResult = comparer(value, list[middle]);
+ if (comparisonResult < 0)
+ {
+ upper = middle - 1;
+ }
+ else if (comparisonResult > 0)
+ {
+ lower = middle + 1;
+ }
+ else
+ {
+ return middle;
+ }
+ }
+
+ return ~lower;
+ }
+
+ ///
+ /// Performs a binary search on the specified collection.
+ ///
+ /// The type of the item.
+ /// The list to be searched.
+ /// The value to search for.
+ ///
+ public static int BinarySearch(this IList list, TItem value)
+ {
+ return BinarySearch(list, value, Comparer.Default);
+ }
+
+ ///
+ /// Performs a binary search on the specified collection.
+ ///
+ /// The type of the item.
+ /// The list to be searched.
+ /// The value to search for.
+ /// The comparer that is used to compare the value with the list items.
+ ///
+ public static int BinarySearch(this IList list, TItem value, IComparer comparer)
+ {
+ return list.BinarySearch(value, comparer.Compare);
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Location.cs
===================================================================
diff -u -r276 -r282
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Location.cs (.../Location.cs) (revision 276)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Location.cs (.../Location.cs) (revision 282)
@@ -14,10 +14,15 @@
using System.ComponentModel;
using System.Globalization;
using System.IO;
+using System.Linq;
using System.Xml.Serialization;
using Deltares.DamEngine.Data.Design;
+using Deltares.DamEngine.Data.General.Gauges;
+using Deltares.DamEngine.Data.General.PlLines;
using Deltares.DamEngine.Data.Geometry;
using Deltares.DamEngine.Data.Geotechnics;
+using Deltares.DamEngine.Data.Probabilistic;
+using Deltares.DamEngine.Data.Standard;
using Deltares.DamEngine.Data.Standard.Language;
using Deltares.DamEngine.Data.Standard.Validation;
@@ -123,8 +128,7 @@
public const string IntrusionVerticalWaterPressure = "IntrusionVerticalWaterPressure";
}
- [TrackChanges]
- public class Location : IDisposable
+ public class Location
{
// Added initial value as these properties must be tested for real values on import
public const string AllCategory = "MainItems";
@@ -3772,18 +3776,6 @@
return sb.ToString();*/
}
- public void Dispose()
- {
- if (surfaceLine != null)
- {
- surfaceLine.Dispose();
- }
- if (LocalXZSurfaceLine2 != null)
- {
- LocalXZSurfaceLine2.Dispose();
- }
- }
-
public ICollection GetDomain(string property)
{
switch (property)
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/IFindList.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/IFindList.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/IFindList.cs (revision 282)
@@ -0,0 +1,35 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Delta Shell Light Library.
+//
+// The Delta Shell Light Library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+using System;
+using System.Collections.Generic;
+
+namespace Deltares.DamEngine.Data.Standard
+{
+ public interface IFindList
+ {
+ T Find(Predicate match);
+ List FindAll(Predicate match);
+ int FindIndex(Predicate match);
+ T FindLast(Predicate match);
+ int FindLastIndex(Predicate match);
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/Layer.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/Layer.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/Layer.cs (revision 282)
@@ -0,0 +1,93 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.Geometry;
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// publisherEventArgs helper struct, to aid in Layer Intersection
+ /// TODO: Comment
+ ///
+ public struct LayerIntersectionPoint
+ {
+ private readonly Point2D intersectionPoint;
+ private readonly SoilLayer2D surfaceRefKey;
+
+ internal LayerIntersectionPoint(Point2D aIntersectionPoint, SoilLayer2D aSurfaceRefKey)
+ {
+ intersectionPoint = aIntersectionPoint;
+ surfaceRefKey = aSurfaceRefKey;
+ }
+
+ internal Point2D IntersectionPoint
+ {
+ get
+ {
+ return intersectionPoint;
+ }
+ }
+
+ internal SoilLayer2D SurfaceRefKey
+ {
+ get
+ {
+ return surfaceRefKey;
+ }
+ }
+ }
+
+ ///
+ /// publisherEventArgs helper struct, to aid in Layer Intersection
+ /// TODO: Comment
+ ///
+ public class Layer : SoilLayer1D
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// A start point.
+ /// An end point.
+ /// A stability soil properties ID.
+ public Layer(Point2D aStartPoint, Point2D aEndPoint, Soil aStabilitySoilPropertiesId)
+ {
+ StartPoint = aStartPoint;
+ EndPoint = aEndPoint;
+ Soil = aStabilitySoilPropertiesId;
+ }
+
+ ///
+ /// Gets or sets the start point.
+ ///
+ ///
+ /// The start point.
+ ///
+ public Point2D StartPoint { get; set; }
+
+ ///
+ /// Gets or sets the end point.
+ ///
+ ///
+ /// The end point.
+ ///
+ public Point2D EndPoint { get; set; }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Segment.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Segment.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Segment.cs (revision 282)
@@ -0,0 +1,236 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2010 Deltares. All rights reserved.
+//
+// B.S.T.I.M. The
+// tom.the@deltares.nl
+// 18-05-2010
+// Segment data
+//-----------------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Deltares.DamEngine.Data.Geotechnics;
+
+namespace Deltares.DamEngine.Data.General
+{
+ public class SoilGeometryProbability : IComparable
+ {
+ public virtual SoilProfile1D SoilProfile { get; set; }
+ public virtual string SoilGeometry2DName { get; set; }
+ public virtual SoilProfile2D SoilProfile2D { get; set; }
+ public virtual FailureMechanismSystemType? SegmentFailureMechanismType { get; set; }
+ public virtual double Probability { get; set; } // Probability of occurance; number between 0.0 and 100.0
+
+ ///
+ /// Assigns the specified soil geometry probability.
+ ///
+ /// The soil geometry probability.
+ public void Assign(SoilGeometryProbability soilGeometryProbability)
+ {
+ if (soilGeometryProbability.SoilProfile != null)
+ {
+ SoilProfile = new SoilProfile1D();
+ SoilProfile.Assign(soilGeometryProbability.SoilProfile);
+ }
+ SegmentFailureMechanismType = soilGeometryProbability.SegmentFailureMechanismType;
+ Probability = soilGeometryProbability.Probability;
+ SoilGeometry2DName = soilGeometryProbability.SoilGeometry2DName;
+ }
+
+ public SoilGeometryType SoilGeometryType
+ {
+ get
+ {
+ if (SoilProfile != null)
+ {
+ return SoilGeometryType.SoilGeometry1D;
+ }
+ else
+ {
+ if (SoilGeometry2DName == null)
+ {
+ throw new Exception("No soilprofile assigned");
+ }
+ return SoilGeometryType.SoilGeometry2D;
+ }
+ }
+ }
+
+ ///
+ /// Returns either the 1D-geometry or the 2D-geometry name
+ ///
+ public virtual string SoilGeometryName
+ {
+ get
+ {
+ string soilGeometryName = "";
+ if (this.SoilProfile != null)
+ {
+ soilGeometryName = this.SoilProfile.Name;
+ }
+ else
+ {
+ soilGeometryName = this.SoilGeometry2DName;
+ } return soilGeometryName;
+ }
+ }
+
+ public int CompareTo(SoilGeometryProbability other)
+ {
+ return - this.Probability.CompareTo(other.Probability);
+ }
+ }
+
+ public class Segment
+ {
+ private List soilGeometryProbabilities = new List();
+
+ public virtual string Name { get; set; }
+
+ ///
+ /// Gets the soil probalilities for this segment
+ ///
+ public virtual List SoilProfileProbabilities
+ {
+ get { return this.soilGeometryProbabilities; }
+ }
+
+ public SoilProfile1D GetMostProbableProfile(FailureMechanismSystemType? segmentFailureMechanismType)
+ {
+ IEnumerable spps = from SoilGeometryProbability spp in this.soilGeometryProbabilities
+ where !spp.SegmentFailureMechanismType.HasValue || !segmentFailureMechanismType.HasValue || spp.SegmentFailureMechanismType == segmentFailureMechanismType
+ orderby spp.Probability descending
+ select spp;
+ if (spps.Count() > 0)
+ return spps.First().SoilProfile;
+ else
+ return null;
+ }
+
+ public string GetMostProbableGeometry2DName(FailureMechanismSystemType? segmentFailureMechanismType)
+ {
+ IEnumerable spps = from SoilGeometryProbability spp in this.soilGeometryProbabilities
+ where !spp.SegmentFailureMechanismType.HasValue || !segmentFailureMechanismType.HasValue || spp.SegmentFailureMechanismType == segmentFailureMechanismType
+ orderby spp.Probability descending
+ select spp;
+ if (spps.Count() > 0)
+ return spps.First().SoilGeometry2DName;
+ else
+ return null;
+ }
+
+ public void AddSoilProfileProbability(SoilProfile1D soilProfile, double probability, FailureMechanismSystemType? segmentFailureMechanismType)
+ {
+ if (this.soilGeometryProbabilities.Where(x => x.SoilProfile == soilProfile && x.SegmentFailureMechanismType == segmentFailureMechanismType).Count() == 0)
+ this.soilGeometryProbabilities.Add(new SoilGeometryProbability() { SoilProfile = soilProfile, Probability = probability, SegmentFailureMechanismType = segmentFailureMechanismType, SoilGeometry2DName = null });
+ }
+
+ public double? GetSoilProfileProbability(SoilProfile1D soilProfile, FailureMechanismSystemType? segmentFailureMechanismType)
+ {
+ IEnumerable probs = this.soilGeometryProbabilities.Where(
+ x => (x.SoilProfile == soilProfile) &&
+ (segmentFailureMechanismType == null || x.SegmentFailureMechanismType == segmentFailureMechanismType || x.SegmentFailureMechanismType == null));
+
+ if (probs.Count() > 0)
+ return probs.Select(x => x.Probability).Average();
+ else
+ return null;
+ }
+
+ public void AddSoilGeometry2DProbability(string soilGeometry2DName, double probability, FailureMechanismSystemType? segmentFailureMechanismType)
+ {
+ if (this.soilGeometryProbabilities.Where(x => x.SoilGeometry2DName == soilGeometry2DName && x.SegmentFailureMechanismType == segmentFailureMechanismType).Count() == 0)
+ this.soilGeometryProbabilities.Add(new SoilGeometryProbability() { SoilProfile = null, Probability = probability, SegmentFailureMechanismType = segmentFailureMechanismType, SoilGeometry2DName = soilGeometry2DName });
+ }
+
+ public double? GetSoilGeometry2DProbability(string soilGeometry2DName, FailureMechanismSystemType? segmentFailureMechanismType)
+ {
+ IEnumerable probs = this.soilGeometryProbabilities.Where(
+ x => (x.SoilGeometry2DName == soilGeometry2DName) &&
+ (segmentFailureMechanismType == null || x.SegmentFailureMechanismType == segmentFailureMechanismType || x.SegmentFailureMechanismType == null));
+
+ if (probs.Count() > 0)
+ return probs.Select(x => x.Probability).Average();
+ else
+ return null;
+ }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append(this.Name);
+ sb.Append(": ");
+ foreach (FailureMechanismSystemType type in Enum.GetValues(typeof(FailureMechanismSystemType)))
+ {
+ sb.Append(type.ToString());
+ sb.Append(": ");
+ foreach (SoilGeometryProbability spp in this.SoilProfileProbabilities.Where(x => x.SegmentFailureMechanismType == null || x.SegmentFailureMechanismType == type))
+ {
+ if (spp.SoilProfile != null)
+ {
+ sb.Append(String.Format("(1D) {0} ({1}%) ", spp.SoilProfile.Name, spp.Probability));
+ }
+ else
+ {
+ sb.Append(String.Format("(2D) {0} ({1}%) ", spp.SoilGeometry2DName, spp.Probability));
+ }
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ ///
+ /// Assemble a list of key/value pairs with the relevant parameters for the specified 1d-profile
+ ///
+ ///
+ public Dictionary GetParametersForSoilProfile1DAsNameValuePairs(string soilProfile1DId, FailureMechanismSystemType failureMechanismSystemType)
+ {
+ SoilGeometryProbability soilProfileProbability = this.SoilProfileProbabilities.FirstOrDefault(x => (x.SoilProfile != null &&
+ x.SoilProfile.Name.Equals(soilProfile1DId) &&
+ x.SegmentFailureMechanismType == failureMechanismSystemType
+ ));
+ if (soilProfileProbability != null)
+ {
+ var nameValuePairs = new Dictionary();
+ var numberFormatInfo = new NumberFormatInfo();
+ numberFormatInfo.NumberDecimalSeparator = ".";
+ nameValuePairs.Add("Probability", soilProfileProbability.Probability.ToString(numberFormatInfo));
+ nameValuePairs.Add("FailureMechanismType", soilProfileProbability.SegmentFailureMechanismType.ToString());
+ return nameValuePairs;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ ///
+ /// Assemble a list of key/value pairs with the relevant parameters for the specified 2d-profile
+ ///
+ ///
+ public Dictionary GetParametersForSoilProfile2DAsNameValuePairs(string soilProfile2DId, FailureMechanismSystemType failureMechanismSystemType)
+ {
+ SoilGeometryProbability soilProfileProbability = this.SoilProfileProbabilities.FirstOrDefault(x => x.SoilGeometry2DName.Equals(soilProfile2DId) &&
+ x.SegmentFailureMechanismType == failureMechanismSystemType);
+ if (soilProfileProbability != null)
+ {
+ var nameValuePairs = new Dictionary();
+ var numberFormatInfo = new NumberFormatInfo();
+ numberFormatInfo.NumberDecimalSeparator = ".";
+ nameValuePairs.Add("Probability", soilProfileProbability.Probability.ToString(numberFormatInfo));
+ nameValuePairs.Add("FailureMechanismType", soilProfileProbability.SegmentFailureMechanismType.ToString());
+ return nameValuePairs;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Dike.cs
===================================================================
diff -u -r278 -r282
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Dike.cs (.../Dike.cs) (revision 278)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Dike.cs (.../Dike.cs) (revision 282)
@@ -11,11 +11,10 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
-using System.IO;
using System.Linq;
-using System.Xml.Serialization;
using Deltares.DamEngine.Data.Design;
using Deltares.DamEngine.Data.General.Gauges;
+using Deltares.DamEngine.Data.General.NWO;
using Deltares.DamEngine.Data.General.PlLines;
using Deltares.DamEngine.Data.Geotechnics;
using Deltares.DamEngine.Data.Standard;
@@ -37,7 +36,7 @@
public const string MapForSoilGeometries2D = "MapForSoilGeometries2D";
}
- public class Dike: IDisposable
+ public class Dike
{
private string description = "";
public virtual string MapForSoilGeometries2D { get; set; }
@@ -62,7 +61,7 @@
this.locations = new List();
this.soilProfiles = new List();
- this.surfaceLines = new DelegatedList { AddMethod = ConvertAddedOldSurfaceLineToNewFormat };
+ // this.surfaceLines = new DelegatedList { AddMethod = ConvertAddedOldSurfaceLineToNewFormat };
SurfaceLines2 = new List();
this.pl1Lines = new List();
this.soilList = new SoilList();
@@ -111,9 +110,6 @@
}
- [XmlIgnore]
- public SoilbaseDB SoilBaseDB { get; set; }
-
///
/// Gets the locations.
///
@@ -216,55 +212,8 @@
}
}
- public void CreateSoilBase()
- {
- if (this.SoilDatabaseName == null || !File.Exists(this.SoilDatabaseName))
- {
- throw new DikeException(String.Format("The soil database '{0}' cannot be found", this.SoilDatabaseName));
- }
- this.SoilBaseDB = SoilbaseDB.Create(this.SoilDatabaseName);
- }
-
+
///
- /// Read all the soils and their parameters from the database
- ///
- public void FillDataBaseSoilListFromSoilBase()
- {
- using (var geoDatabase = new GeoDatabase(this.SoilDatabaseName))
- {
- geoDatabase.ReUseSoils = true;
- var newSoilList = geoDatabase.ReadSoils(soilList.Soils);
- databaseSoils = newSoilList.Soils;
- }
- }
-
- ///
- /// Add 1D-soilprofiles from MGeobase database
- ///
- public void AddSoilProfilesFromDB()
- {
- if (this.SoilDatabaseName == null || !File.Exists(this.SoilDatabaseName))
- {
- throw new DikeException(String.Format("The MGeobase database '{0}' cannot be found", this.SoilDatabaseName));
- }
- if (soilList.Soils.Count == 0)
- {
- FillDataBaseSoilListFromSoilBase();
- soilList.Soils.AddRange(databaseSoils);
- }
- if (soilList.Soils.Count == 0)
- {
- throw new DikeException(String.Format("The MGeobase database '{0}' does not contain soils and can not be used.", this.SoilDatabaseName));
- }
- MGeobaseDB mgbDB = new MGeobaseDB(soilList);
- IList addedSoilProfiles = mgbDB.AddSoilProfiles(this.SoilDatabaseName);
- foreach (var addedSoilProfile in addedSoilProfiles)
- {
- soilProfiles.Add(addedSoilProfile);
- }
- }
-
- ///
/// Adapt data so it is consistent
///
public List MakeDataConsistent()
@@ -441,22 +390,10 @@
location.MapForSoilGeometries2D = this.MapForSoilGeometries2D;
location.Gauges.Clear();
- location.Gauges.AddRange(this.Gauges);
+ location.Gauges.AddRange(Gauges);
location.GaugePLLines.Clear();
- location.GaugePLLines.AddRange(this.GaugePLLines);
- }
-
- public void Dispose()
- {
- foreach (var location in Locations)
- {
- location.Dispose();
- }
- foreach (var surfaceLine2 in SurfaceLines2)
- {
- surfaceLine2.Dispose();
- }
- }
+ location.GaugePLLines.AddRange(GaugePLLines);
+ }
}
}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/Soil.cs
===================================================================
diff -u -r276 -r282
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/Soil.cs (.../Soil.cs) (revision 276)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/Soil.cs (.../Soil.cs) (revision 282)
@@ -47,13 +47,15 @@
private double cuBottom = double.NaN;
private bool usePop = true;
private double strengthIncreaseExponent = double.NaN;
+ private SoilType soilType;
///
/// Initializes a new instance of the class.
///
public Soil()
{
- Name = LocalizationManager.GetTranslatedText(this, "DefaultNameSoilMaterial");
+ Name = LocalizationManager.GetTranslatedText(this, "DefaultNameSoilMaterial");
+ soilType = SoilType.Sand;
}
@@ -78,7 +80,28 @@
{
Name = name;
}
-
+
+ ///
+ /// Gets or sets the type of the soil.
+ ///
+ ///
+ /// The type of the soil.
+ ///
+ public virtual SoilType SoilType
+ {
+ get
+ {
+ return soilType;
+ }
+ set
+ {
+ if (!soilType.Equals(value))
+ {
+ soilType = value;
+ }
+ }
+ }
+
#region property Name
///
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryData.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryData.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometryData.cs (revision 282)
@@ -0,0 +1,797 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.Xml.Serialization;
+using Deltares.DamEngine.Data.Standard.Language;
+using Deltares.DamEngine.Data.Standard.Validation;
+
+namespace Deltares.DamEngine.Data.Geometry
+{
+ ///
+ /// Class containing the geometry data
+ ///
+ ///
+ public class GeometryData : GeometryObject
+ {
+ private readonly List curveDataList = new List();
+
+ private readonly List loopDataList = new List();
+ private readonly List pointDataList = new List();
+ private readonly List surfaceDataList = new List();
+ private readonly GeometryPointString surfaceLine = new GeometryPointString();
+ private double bottom = GeometryConstants.DefaultBottomLimitGeometry;
+
+ private double left = GeometryConstants.DefaultLeftLimitGeometry;
+
+ private double right = GeometryConstants.DefaultRightLimitGeometry;
+
+ private bool updatingSurfaceLine;
+
+ #region Repairer Id's and property names
+
+ private const string sameStartAndEndPointRepairerId = "Same start and end point";
+ private const string sameStartAndEndPointRepairerPropertyName = "Points";
+ private const string noSoilRepairerId = "No Soil";
+ private const string noSoilRepairerPropertyName = "None";
+
+ #endregion
+
+ #region properties
+
+ ///
+ /// Gets the points.
+ ///
+ ///
+ /// The points.
+ ///
+ [XmlArray("Points")]
+ [Validate]
+ public IList Points
+ {
+ get
+ {
+ return pointDataList;
+ }
+ }
+
+ ///
+ /// gets the Curve data list.
+ ///
+ ///
+ /// The curves.
+ ///
+ public List Curves
+ {
+ get
+ {
+ return curveDataList;
+ }
+ }
+
+ ///
+ /// gets the Loop data list.
+ ///
+ ///
+ /// The loops.
+ ///
+ public List Loops
+ {
+ get
+ {
+ return loopDataList;
+ }
+ }
+
+ ///
+ /// gets the Surface data list.
+ ///
+ public List Surfaces
+ {
+ get
+ {
+ return surfaceDataList;
+ }
+ }
+
+ ///
+ /// Gets the minimum geometry points x.
+ ///
+ ///
+ /// The minimum geometry points x.
+ ///
+ [XmlIgnore]
+ public double MinGeometryPointsX
+ {
+ get
+ {
+ return Points.Select(geometryPoint => geometryPoint.X).Concat(new[]
+ {
+ double.MaxValue
+ }).Min();
+ }
+ }
+
+ ///
+ /// Gets the minimum geometry points z.
+ ///
+ ///
+ /// The minimum geometry points z.
+ ///
+ [XmlIgnore]
+ public double MinGeometryPointsZ
+ {
+ get
+ {
+ return Points.Select(geometryPoint => geometryPoint.Z).Concat(new[]
+ {
+ double.MaxValue
+ }).Min();
+ }
+ }
+
+ ///
+ /// Gets the maximum geometry points x.
+ ///
+ ///
+ /// The maximum geometry points x.
+ ///
+ [XmlIgnore]
+ public double MaxGeometryPointsX
+ {
+ get
+ {
+ return Points.Select(geometryPoint => geometryPoint.X).Concat(new[]
+ {
+ double.MinValue
+ }).Max();
+ }
+ }
+
+ ///
+ /// Gets the maximum geometry points z.
+ ///
+ ///
+ /// The maximum geometry points z.
+ ///
+ [XmlIgnore]
+ public double MaxGeometryPointsZ
+ {
+ get
+ {
+ return Points.Select(geometryPoint => geometryPoint.Z).Concat(new[]
+ {
+ double.MinValue
+ }).Max();
+ }
+ }
+
+ ///
+ /// Gets or sets the left.
+ ///
+ ///
+ /// The left.
+ ///
+ public double Left
+ {
+ get
+ {
+ return left;
+ }
+ set
+ {
+ left = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the right.
+ ///
+ ///
+ /// The right.
+ ///
+ public double Right
+ {
+ get
+ {
+ return right;
+ }
+ set
+ {
+ right = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the bottom.
+ ///
+ ///
+ /// The bottom.
+ ///
+ public double Bottom
+ {
+ get
+ {
+ return bottom;
+ }
+ set
+ {
+ bottom = value;
+ }
+ }
+
+ ///
+ /// Gets all points on the Left boundary.
+ ///
+ ///
+ private List GetLeftPoints()
+ {
+ var geometryPoints = pointDataList.Where(gp => Math.Abs(gp.X - Left) < GeometryConstants.Accuracy).ToList();
+ return geometryPoints;
+ }
+
+ ///
+ /// Gets all points on the Right boundary.
+ ///
+ ///
+ private List GetRightPoints()
+ {
+ var geometryPoints = pointDataList.Where(point => Math.Abs(point.X - Right) < GeometryConstants.Accuracy).ToList();
+ return geometryPoints;
+ }
+
+ ///
+ /// Gets the geometry bounds.
+ ///
+ ///
+ public override GeometryBounds GetGeometryBounds()
+ {
+ return new GeometryBounds(Left, Right, Bottom,
+ Bottom + Math.Min(Right - Left, 20));
+ }
+
+ #endregion
+
+ #region Functions
+
+ #region create functions
+
+ ///
+ /// Adjust the Geometry Bottom, Left and Right properties to the currently contained surfaces
+ ///
+ public void Rebox()
+ {
+ double xMin = double.MaxValue;
+ double xMax = double.MinValue;
+ double zMin = double.MaxValue;
+ double zMax = double.MinValue;
+
+ foreach (var point in pointDataList)
+ {
+ xMin = Math.Min(point.X, xMin);
+ xMax = Math.Max(point.X, xMax);
+ zMin = Math.Min(point.Z, zMin);
+ zMax = Math.Max(point.Z, zMax);
+ }
+ bottom = zMin;
+ left = xMin;
+ right = xMax;
+ }
+
+ #endregion
+
+ #region remove functions
+
+ ///
+ /// deletes all the Loop from IGeometryLoop.
+ ///
+ private void DeleteAllLoops()
+ {
+ Loops.Clear();
+ }
+
+ #endregion
+
+ #region other functions
+
+ #region calculation function
+
+ ///
+ /// CheckIfIntersectStricktly
+ /// Determines if two lines intersect each other stricktly (so no extrapolated points).
+ ///
+ /// Line 1 GeometryPoint 1
+ /// Line 1 GeometryPoint 2
+ /// Line 2 GeometryPoint 1
+ /// Line 2 GeometryPoint 2
+ /// Intersection coordinates
+ /// True if lines intersect each other
+ private static bool CheckIfIntersectStricktly(Point2D beginPoint1, Point2D endPoint1,
+ Point2D beginPoint2, Point2D endPoint2,
+ ref Point2D intersect)
+ {
+ Point2D ip;
+ var res = Routines2D.DetermineIf2DLinesIntersectStrickly(beginPoint1.X, beginPoint1.Z, endPoint1.X, endPoint1.Z, beginPoint2.X,
+ beginPoint2.Z, endPoint2.X, endPoint2.Z, out ip);
+ if (ip != null)
+ {
+ intersect = ip;
+ }
+ return res == LineIntersection.Intersects;
+ }
+
+ ///
+ /// CheckIfIntersectStricktly
+ /// Determines if two lines intersect each other stricktly (so no extrapolated points).
+ ///
+ /// Line 1 GeometryPoint 1
+ /// Line 1 GeometryPoint 2
+ /// Line 2 GeometryPoint 1
+ /// Line 2 GeometryPoint 2
+ /// Intersection coordinates
+ /// True if lines intersect each other
+ public static bool CheckIfIntersect(double[] aL1P1, double[] aL1P2, double[] aL2P1, double[] aL2P2,
+ ref double[] aIntersect)
+ {
+ var p1 = new Point2D(aL1P1[0], aL1P1[1]);
+ var p2 = new Point2D(aL1P2[0], aL1P2[1]);
+ var p3 = new Point2D(aL2P1[0], aL2P1[1]);
+ var p4 = new Point2D(aL2P2[0], aL2P2[1]);
+ var ip = new Point2D();
+ var res = CheckIfIntersectStricktly(p1, p2, p3, p4, ref ip);
+ if (res)
+ {
+ aIntersect[0] = ip.X;
+ aIntersect[1] = ip.Z;
+ }
+ return res;
+ }
+
+ ///
+ /// Gets the height of the surface(s) intersected at the given x.
+ ///
+ /// The x.
+ ///
+ public double GetSurfaceHeight(double x)
+ {
+ double surfaceHeight = -Double.MaxValue;
+ double[] intersectionPoints = IntersectLayers(x, -9999);
+ for (int i = 0; i < intersectionPoints.Length; i++)
+ {
+ if (intersectionPoints[i] > surfaceHeight)
+ {
+ surfaceHeight = intersectionPoints[i];
+ }
+ }
+
+ return surfaceHeight;
+ }
+
+ ///
+ /// All the Intersection of layers in respect with a given vertical are detemined here.
+ ///
+ /// Startingpoint of the Vertical (X)
+ /// Startingpoint of the Vertical (Y)
+ /// List of Z intersection coordinates
+ private double[] IntersectLayers(double aXCoord, double aZCoord)
+ {
+ if (Surfaces == null)
+ {
+ throw new Exception("Empty Surfaces in IntersectLayers");
+ }
+
+ var beginPoint2 = new Point2D()
+ {
+ X = aXCoord, Z = aZCoord
+ };
+
+ var endPoint2 = new Point2D()
+ {
+ X = aXCoord, Z = 99999
+ };
+
+ var referencePoint = new Point2D();
+
+ var intersections = new List();
+
+ for (int surfaceIndexLocal = 0; surfaceIndexLocal < Surfaces.Count; surfaceIndexLocal++)
+ {
+ var outerLoopCurveList = Surfaces[surfaceIndexLocal].OuterLoop.CurveList;
+ for (int curveIndexLocal = 0; curveIndexLocal < outerLoopCurveList.Count; curveIndexLocal++)
+ {
+ //Check for each curve if it intersects with x coordinate
+ Point2D beginPoint1 = outerLoopCurveList[curveIndexLocal].GetHeadPoint(CurveDirection.Forward);
+ Point2D endPoint1 = outerLoopCurveList[curveIndexLocal].GetEndPoint(CurveDirection.Forward);
+
+ if (Math.Max(beginPoint1.X, endPoint1.X) >= aXCoord &&
+ Math.Min(beginPoint1.X, endPoint1.X) <= aXCoord)
+ {
+ if (CheckIfIntersectStricktly(beginPoint1, endPoint1, beginPoint2, endPoint2,
+ ref referencePoint))
+ {
+ if (referencePoint.Z > aZCoord && intersections.Contains(referencePoint.Z) == false)
+ {
+ intersections.Add(referencePoint.Z);
+ }
+ }
+ }
+ }
+ }
+
+ return intersections.ToArray();
+ }
+
+ ///
+ /// Returns a list of boundary curves. These are curves which are used in only one surface so they have to be on a boundary (inner or outer)
+ ///
+ ///
+ private List GetBoundaryCurves()
+ {
+ var curves = new List();
+ var loops = new List();
+ foreach (var surface in Surfaces)
+ {
+ loops.Add(surface.OuterLoop);
+ // Todo Ask Rob/Tom: when a real "doughnut" type surface (so hole in the center) is permitted, adding the innerloops here will
+ // result in a wrong list of curves (because it will include the inner loop curves defining the hole) for its actual purpose:
+ // the determination of the surfaceline. When there is always a surface defined within the "dougnut" (so no real hole),
+ // this code will work and the innerloop must even be added to prevent finding internal boundaries. So this depends on the specs!
+ loops.AddRange(surface.InnerLoops);
+ }
+
+ foreach (var loop in loops)
+ {
+ foreach (var curve in loop.CurveList)
+ {
+ if (curves.Contains(curve))
+ {
+ // Second appearance, remove
+ curves.Remove(curve);
+ }
+ else
+ {
+ curves.Add(curve);
+ }
+ }
+ }
+ return curves;
+ }
+
+ #endregion
+
+
+ #endregion
+
+ #endregion
+
+ ///
+ /// Ordered list of all geometry points at the surface
+ ///
+ public virtual GeometryPointString SurfaceLine
+ {
+ get
+ {
+ if (surfaceLine.CalcPoints.Count == 0 && pointDataList.Count > 0)
+ {
+ UpdateSurfaceLine();
+ }
+ return surfaceLine;
+ }
+ }
+
+ ///
+ /// Checks geometry for loose curves and AutoRegeneration
+ ///
+ ///
+ [Validate]
+ public ValidationResult[] ValidateGeometry()
+ {
+ var validationList = new List();
+ {
+ foreach (var point in Points)
+ {
+ foreach (var point1 in Points)
+ {
+ if (point != point1)
+ {
+ bool isValidated = false;
+ foreach (var validatedItem in validationList)
+ {
+ if (validatedItem.Subject == point)
+ {
+ isValidated = true;
+ }
+ }
+ if (!isValidated)
+ {
+ if (Math.Abs(point.X - point1.X) < GeometryConstants.Accuracy &&
+ Math.Abs(point.Z - point1.Z) < GeometryConstants.Accuracy)
+ {
+ validationList.Add(new ValidationResult(ValidationResultType.Error,
+ point + " and " +
+ point1 + " values are same.",
+ point1, sameStartAndEndPointRepairerPropertyName,
+ sameStartAndEndPointRepairerId));
+ }
+ }
+ }
+ }
+ }
+ }
+ if (Surfaces.Count < 1)
+ {
+ validationList.Add(new ValidationResult(ValidationResultType.Error, "No soil surface available.",
+ this, noSoilRepairerPropertyName, noSoilRepairerId));
+ }
+ return validationList.ToArray();
+ }
+
+ ///
+ /// Updates the line at the top of the geometry
+ ///
+ private void UpdateSurfaceLine()
+ {
+ if (updatingSurfaceLine)
+ {
+ return;
+ }
+
+ updatingSurfaceLine = true;
+
+ var bCurves = GetBoundaryCurves();
+ if (bCurves.Count == 0)
+ {
+ surfaceLine.CalcPoints.Clear();
+ }
+ var curvesCopy = GetCurvesCopy(bCurves);
+ var curves = GetTopCurves(curvesCopy);
+ CreateSurfaceLinePointString(curves);
+
+ updatingSurfaceLine = false;
+ }
+
+ ///
+ /// Removes the boundary curves from the given list of curves.
+ /// The boundaries themselves are determined from the given geometry
+ ///
+ /// The curves.
+ /// The geometry (as string).
+ private static void RemoveBoundaryCurves(List curves, GeometryPointString geometry)
+ {
+ var minX = geometry.GetMinX();
+ var maxX = geometry.GetMaxX();
+ var minZ = geometry.GetMinZ();
+ foreach (var curve in curves.ToArray())
+ {
+ if (IsBoundaryCurve(curve, minX, maxX, minZ))
+ {
+ curves.Remove(curve);
+ }
+ }
+ }
+
+ ///
+ /// get all geometrypoints from all geometrycurves
+ ///
+ ///
+ ///
+ private static GeometryPointString GetAllPointsFromCurveList(List curveList)
+ {
+ var result = new GeometryPointString();
+ foreach (var curve in curveList)
+ {
+ result.CalcPoints.Add(curve.EndPoint);
+ result.CalcPoints.Add(curve.HeadPoint);
+ }
+ return result;
+ }
+
+ ///
+ /// Gets next connected top curve in list of curves
+ ///
+ ///
+ ///
+ ///
+ ///
+ private GeometryCurve GetNextTopCurve(GeometryCurve curve, List boundaryCurves,
+ List excludedCurves)
+ {
+ // if current curve ends on right limit then that must have been the last one so stop the search
+ if (Math.Abs(curve.HeadPoint.X - Right) < GeometryConstants.Accuracy || Math.Abs(curve.EndPoint.X - Right) < GeometryConstants.Accuracy)
+ {
+ return null;
+ }
+ foreach (var geometryCurve in boundaryCurves)
+ {
+ if (geometryCurve != curve && !excludedCurves.Contains(geometryCurve))
+ {
+ if (AreConnected(curve, geometryCurve))
+ {
+ return geometryCurve;
+ }
+ }
+ }
+ return null;
+ }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ return LocalizationManager.GetTranslatedText(this, "GeometryData");
+ }
+
+ ///
+ /// Synchronizes the loops.
+ ///
+ public void SynchronizeLoops()
+ {
+ DeleteAllLoops();
+ foreach (var surface in Surfaces)
+ {
+ // #Bka: as real donuts (or holes in geom) are not allowed, there can be no innerloop that
+ // is NOT an outerloop for another surface. So no need to sync innerloops.
+ if (surface.OuterLoop != null && surface.OuterLoop.IsLoop())
+ {
+ loopDataList.Add(surface.OuterLoop);
+ }
+ }
+ }
+
+ ///
+ /// create a copy of the curves
+ ///
+ ///
+ ///
+ private List GetCurvesCopy(List bCurves)
+ {
+ var outerloopCurvesCopy = new List(bCurves);
+ return outerloopCurvesCopy;
+ }
+
+ ///
+ /// Create a surface line from points in curves
+ /// Precondition is that the curves start at the left boundary and are connected left to right
+ /// (not neccesarily neat head-end)
+ ///
+ ///
+ ///
+ private void CreateSurfaceLinePointString(List curves)
+ {
+ surfaceLine.CalcPoints.Clear();
+
+ if (curves.Count == 0)
+ {
+ return;
+ }
+
+ var reversed = false;
+ // The headpoint of the first curve must be on the left boundary otherwise the
+ // surface line will be in the wrong order. So make sure.
+ if (!(Math.Abs(curves[0].HeadPoint.X - Left) < GeometryConstants.Accuracy))
+ {
+ curves[0].Reverse();
+ reversed = true;
+ }
+
+ foreach (var curve in curves)
+ {
+ if (!surfaceLine.CalcPoints.Contains(curve.HeadPoint))
+ {
+ surfaceLine.CalcPoints.Add(curve.HeadPoint);
+ }
+ if (!surfaceLine.CalcPoints.Contains(curve.EndPoint))
+ {
+ surfaceLine.CalcPoints.Add(curve.EndPoint);
+ }
+ }
+
+ if (reversed)
+ {
+ curves[0].Reverse();
+ }
+ }
+
+ ///
+ /// get curves of the top side of the outerloop, vertical curves are omitted
+ ///
+ ///
+ ///
+ private List GetTopCurves(List curves)
+ {
+ GeometryCurve topCurve;
+ // Remove all curves on the geometry boundary
+ if (GetLeftPoints().Count > 0 && GetRightPoints().Count > 0)
+ {
+ foreach (var curve in curves.ToArray())
+ {
+ if (IsBoundaryCurve(curve, Left, Right, Bottom))
+ {
+ curves.Remove(curve);
+ }
+ }
+ // Make sure you start with topcurve = curve at the left top position
+ topCurve = curves.Where(g => Math.Abs(g.HeadPoint.X - Left) < GeometryConstants.Accuracy ||
+ Math.Abs(g.EndPoint.X - Left) < GeometryConstants.Accuracy)
+ .OrderByDescending(c => c.HeadPoint.Z)
+ .FirstOrDefault();
+ }
+ else
+ {
+ GeometryPointString gString = GetAllPointsFromCurveList(curves);
+ RemoveBoundaryCurves(curves, gString);
+ var minX = gString.GetMinX();
+ // Make sure you start with topcurve = curve at the left top position
+ topCurve =
+ curves.Where(g => Math.Abs(g.HeadPoint.X - minX) < GeometryConstants.Accuracy ||
+ Math.Abs(g.EndPoint.X - minX) < GeometryConstants.Accuracy).OrderByDescending(c => c.HeadPoint.Z).FirstOrDefault();
+ }
+ var topCurvesLocal = new List();
+ while (topCurve != null)
+ {
+ topCurvesLocal.Add(topCurve);
+ topCurve = GetNextTopCurve(topCurve, curves, topCurvesLocal);
+ }
+
+ return topCurvesLocal;
+ }
+
+ ///
+ /// Indicates whether a curve is on the boundary of the geometry
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static bool IsBoundaryCurve(GeometryCurve curve, double minX, double maxX, double minZ)
+ {
+ if (Math.Abs(curve.HeadPoint.X - minX) < GeometryConstants.Accuracy && Math.Abs(curve.EndPoint.X - minX) < GeometryConstants.Accuracy)
+ {
+ return true;
+ }
+
+ if (Math.Abs(curve.HeadPoint.X - maxX) < GeometryConstants.Accuracy && Math.Abs(curve.EndPoint.X - maxX) < GeometryConstants.Accuracy)
+ {
+ return true;
+ }
+
+ if (Math.Abs(curve.HeadPoint.Z - minZ) < GeometryConstants.Accuracy && Math.Abs(curve.EndPoint.Z - minZ) < GeometryConstants.Accuracy)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ private bool AreConnected(GeometryCurve curve1, GeometryCurve curve2)
+ {
+ return (curve1.HeadPoint == curve2.HeadPoint || curve1.HeadPoint == curve2.EndPoint ||
+ curve1.EndPoint == curve2.HeadPoint || curve1.EndPoint == curve2.EndPoint);
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilLayer2D.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilLayer2D.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilLayer2D.cs (revision 282)
@@ -0,0 +1,77 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.Geometry;
+using Deltares.DamEngine.Data.Standard.Language;
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// 2D Soil Layer Object
+ ///
+ [Serializable]
+ public class SoilLayer2D : SoilLayer
+ {
+ // 2 associated objects
+ private GeometrySurface geometrySurface;
+
+ ///
+ /// Gets and sets the GeometrySurface
+ ///
+ public GeometrySurface GeometrySurface
+ {
+ get
+ {
+ return geometrySurface;
+ }
+ set
+ {
+ geometrySurface = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the name.
+ ///
+ ///
+ /// The name.
+ ///
+ public override string Name
+ {
+ get
+ {
+ return Soil != null ? Soil.Name : LocalizationManager.GetTranslatedText(this, "NoSoilAssigned");
+ }
+ set{} // ignore
+ }
+
+ ///
+ /// Gets the geometry bounds.
+ ///
+ /// the geometry bounds
+ public override GeometryBounds GetGeometryBounds()
+ {
+ return GeometrySurface == null ?
+ base.GetGeometryBounds() : GeometrySurface.GetGeometryBounds();
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/NWO/NonWaterRetainingObject.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/NWO/NonWaterRetainingObject.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/NWO/NonWaterRetainingObject.cs (revision 282)
@@ -0,0 +1,147 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2011 Deltares. All rights reserved.
+//
+// J. Bokma
+// john.bokma@deltares.nl
+// 13-10-2011
+// n.a.
+//-----------------------------------------------------------------------
+
+using System;
+using Deltares.DamEngine.Data.Geometry;
+
+namespace Deltares.DamEngine.Data.General.NWO
+{
+
+ public class NonWaterRetainingObjectException : ApplicationException
+ {
+ public NonWaterRetainingObjectException(string message)
+ : base(message)
+ {
+ }
+ }
+
+ public class NonWaterRetainingObject
+ {
+ public virtual string NwoId { get; set; }
+ public virtual NonWaterRetainingObjectCategory Category { get; set; }
+ public virtual NonWaterRetainingObjectType Type { get; set; }
+ public virtual PhreaticAdaptionType PhreaticAdaption { get; set; }
+ public virtual double H1 { get; set; }
+ public virtual double H2 { get; set; }
+ public virtual double N1 { get; set; }
+ public virtual double N2 { get; set; }
+ public virtual double B { get; set; }
+ public virtual double StepSizeX { get; set; }
+ public virtual double MaxDistanceFromToe { get; set; }
+
+ public double Btotal ()
+ {
+ double bTotal = (H1 * N1) + (Math.Sqrt((B*B - (Math.Pow(H2-H1, 2))))) + (H2 * N2);
+ return bTotal;
+ }
+
+ public GeometryPoint Point1 { get; set; }
+ public GeometryPoint Point2 { get; set; }
+ public GeometryPoint Point3 { get; set; }
+ public GeometryPoint Point4 { get; set; }
+
+ ///
+ ///
+ ///
+ ///
+ public void GetDefaultValuesPerTreeType(NonWaterRetainingObjectType type)
+ {
+
+ switch (type)
+ {
+ case NonWaterRetainingObjectType.Oak:
+ H1 = 2;
+ H2 = 2;
+ N1 = 2;
+ N2 = 2;
+ B = 2;
+ break;
+ case NonWaterRetainingObjectType.Alder:
+ H1 = 2;
+ H2 = 2;
+ N1 = 2;
+ N2 = 2;
+ B = 2;
+ break;
+ case NonWaterRetainingObjectType.Poplar:
+ H1 = 2;
+ H2 = 2;
+ N1 = 2;
+ N2 = 2;
+ B = 2;
+ break;
+ default:
+ H1 = 2;
+ H2 = 2;
+ N1 = 2;
+ N2 = 2;
+ B = 2;
+ break;
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void GetDefaultValuesPerMainType(NonWaterRetainingObjectType type)
+ {
+
+ switch (type)
+ {
+ case NonWaterRetainingObjectType.GasMain:
+ H1 = 2;
+ H2 = 2;
+ N1 = 2;
+ N2 = 2;
+ B = 2;
+ break;
+ case NonWaterRetainingObjectType.WaterMain:
+ H1 = 2;
+ H2 = 2;
+ N1 = 2;
+ N2 = 2;
+ B = 2;
+ break;
+ default:
+ H1 = 2;
+ H2 = 2;
+ N1 = 2;
+ N2 = 2;
+ B = 2;
+ break;
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void GetDefaultValuesPerCategoryAndType(NonWaterRetainingObjectCategory category, NonWaterRetainingObjectType type)
+ {
+ switch (category)
+ {
+ case NonWaterRetainingObjectCategory.Tree: GetDefaultValuesPerTreeType(type);
+ break;
+ case NonWaterRetainingObjectCategory.Main: GetDefaultValuesPerMainType(type);
+ break;
+ }
+ }
+
+ public void Validate()
+ {
+ if (Btotal() <= 0)
+ throw new NonWaterRetainingObjectException("NonWaterReatiningObject is invalid. Its total width is smaller than or equal to 0.");
+ if (MaxDistanceFromToe <= Btotal())
+ throw new NonWaterRetainingObjectException("NonWaterReatiningObject is invalid. The required maximum distance from toe is smaller than or equal to the total width.");
+ }
+ }
+}
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Sensors/Group.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Sensors/Group.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Sensors/Group.cs (revision 282)
@@ -0,0 +1,224 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2009 Deltares. All rights reserved.
+//
+// B. Faassen
+// barry.faassen@deltares.nl
+// 1-8-2012
+// n.a.
+//-----------------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Xml.Serialization;
+using Deltares.DamEngine.Data.Standard.Validation;
+
+namespace Deltares.DamEngine.Data.General.Sensors
+{
+ public class Group
+ {
+ ///
+ /// Holds a reference to the set of selected sensors
+ ///
+ private readonly HashSet sensors;
+ private List pickSensors;
+ private int id;
+
+ ///
+ /// Holds a reference to a set of relative loctions along the profile
+ ///
+ private readonly IDictionary relativeLocationAlongProfileDictionary;
+
+ public Group()
+ {
+ sensors = new HashSet();
+ relativeLocationAlongProfileDictionary = new Dictionary();
+ ID = -1;
+ }
+
+ ///
+ /// Gets or sets the ID.
+ ///
+ ///
+ /// The ID value should be unique.
+ ///
+ public int ID
+ {
+ get { return id; }
+ set
+ {
+ id = value;
+ }
+ }
+
+ ///
+ /// Gets the selected sensors.
+ ///
+ [XmlIgnore]
+ public IEnumerable Selection
+ {
+ get { return sensors; }
+ }
+
+ ///
+ /// Gets or sets the selection as list for UI (table) purposes.
+ ///
+ ///
+ /// The selection as list.
+ ///
+ [XmlIgnore]
+ public string SelectionAsString
+ {
+ get
+ {
+ string res = "";
+ foreach (var sensor in sensors)
+ {
+ res = res + sensor.ID + "; ";
+ }
+ return res;
+ }
+ set
+ {
+ ClearSelection();
+ var locSensors = ParseStringToSensorIDs(value);
+ if (pickSensors != null)
+ {
+ foreach (var sensorID in locSensors)
+ {
+ var sensor = PickSensors.Find(x => x.ID == sensorID);
+ if (sensor != null)
+ {
+ Add(sensor);
+ }
+ }
+ }
+ }
+ }
+
+ private List ParseStringToSensorIDs(string value)
+ {
+ value = value.Trim();
+ var ids = new List();
+ var idsarr = value.Split(new Char [] {';'}, StringSplitOptions.RemoveEmptyEntries);
+ foreach (var s in idsarr)
+ {
+ try
+ {
+ var val = Int32.Parse(s);
+ ids.Add(val);
+ }
+ catch (Exception)
+ {
+ // surpress errors, just do not use value
+ }
+ }
+ return ids;
+ }
+
+ ///
+ /// Persistable sensor array. Only for internal use
+ ///
+ public Sensor[] SensorArray
+ {
+ get { return sensors.ToArray(); }
+ set {
+ ClearSelection();
+ foreach (var sensor in value)
+ {
+ Add(sensor);
+ }
+ }
+ }
+
+ ///
+ /// Gets the sensor count.
+ ///
+ public int SensorCount
+ {
+ get { return sensors.Count; }
+ }
+
+ [XmlIgnore]
+ public IEnumerable> SensorRelativeLocations
+ {
+ get { return relativeLocationAlongProfileDictionary; }
+ }
+
+ [XmlIgnore]
+ public List PickSensors
+ {
+ get { return pickSensors; }
+ set { pickSensors = value; }
+ }
+
+ ///
+ /// Determines whether this instance is valid.
+ ///
+ ///
+ public bool IsValid()
+ {
+ IEnumerable validationResults = Validator.Validate(this);
+ return !validationResults.Any();
+ }
+
+ ///
+ /// Determines whether this instance is transient (associated with an invalid ID).
+ ///
+ ///
+ /// true if this instance is transient; otherwise, false.
+ ///
+ public bool IsTransient()
+ {
+ return ID <= 0;
+ }
+
+ ///
+ /// Sets the relative location.
+ ///
+ /// The sensor.
+ /// The value.
+ public void SetRelativeLocation(Sensor sensor, double value)
+ {
+ relativeLocationAlongProfileDictionary[sensor] = value;
+ }
+
+ ///
+ /// Adds the specified sensor to the selected sensor list for this group.
+ ///
+ /// The sensor to add.
+ public void Add(Sensor sensor)
+ {
+ sensors.Add(sensor);
+ if (!relativeLocationAlongProfileDictionary.ContainsKey(sensor))
+ relativeLocationAlongProfileDictionary.Add(sensor, 0);
+
+ }
+
+ ///
+ /// Removes the specified sensor from the selected sensor list from this group.
+ ///
+ /// The sensor to remove.
+ public void Remove(Sensor sensor)
+ {
+ sensors.Remove(sensor);
+ if (relativeLocationAlongProfileDictionary.ContainsKey(sensor))
+ relativeLocationAlongProfileDictionary.Remove(sensor);
+ }
+
+ ///
+ /// Clears the sensor selection
+ ///
+ public void ClearSelection()
+ {
+ sensors.Clear();
+ relativeLocationAlongProfileDictionary.Clear();
+ }
+
+ public override string ToString()
+ {
+ return ID.ToString();
+ }
+ }
+}
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Sensors/Sensor.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Sensors/Sensor.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/General/Sensors/Sensor.cs (revision 282)
@@ -0,0 +1,323 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) 2012 Deltares. All rights reserved.
+//
+// B. Faassen
+// barry.faassen@deltares.nl
+// 1-8-2012
+// n.a.
+//-----------------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Deltares.DamEngine.Data.Standard;
+
+namespace Deltares.DamEngine.Data.General.Sensors
+{
+ ///
+ /// This class represents a sensor or monitoring point used in dikes.
+ /// This entity is created for Dam Live
+ ///
+ public class Sensor : IName
+ {
+ #region Business Rules
+
+ ///
+ /// Specication to test if the value of the candidate is valid
+ ///
+ internal class ContiansAtLeastOneItem : PredicateSpecification>
+ {
+ public ContiansAtLeastOneItem()
+ : base(x => x.Any())
+ {
+ Description = "The sensor should contain at least one PL Line mapping.";
+ }
+ }
+
+ #endregion
+
+ private readonly IGeometry geometry;
+ private double relativeLocation;
+ private readonly HashSet plLineTypes;
+ private int id;
+
+ public Sensor()
+ {
+ plLineTypes = new HashSet();
+ ID = -1;
+ geometry = new Point(0,0,0);
+ }
+
+ public Sensor(Point point) : this()
+ {
+ if (point == null) throw new ArgumentNullException("point");
+ this.geometry = point;
+
+ }
+
+ public Sensor(double x, double y, double z) : this(new Point(x, y, z))
+ {
+ }
+
+ ///
+ /// Gets or sets the ID.
+ ///
+ ///
+ /// The ID should be unique.
+ ///
+ public int ID
+ {
+ get { return id; }
+ set
+ {
+ id = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the name of this sensor.
+ ///
+ ///
+ /// The name string value should not be empty and unique.
+ ///
+ [Specification(typeof(NotEmptySpecification))]
+ public string Name { get; set; }
+
+ ///
+ /// Gets or sets the depth.
+ ///
+ ///
+ /// The depth.
+ ///
+ public double Depth
+ {
+ get { return ZRd; }
+ set
+ {
+ ZRd = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the relative location along the profile.
+ ///
+ ///
+ /// The relative location in meter.
+ ///
+ public double RelativeLocation
+ {
+ get { return relativeLocation; }
+ set
+ {
+ relativeLocation = value;
+ RelativeLocationSpecified = true;
+ }
+ }
+
+ ///
+ /// Gets or sets the X rd.
+ ///
+ ///
+ /// The X rd.
+ ///
+ public double XRd
+ {
+ get { return geometry.Coordinate.X; }
+ set { geometry.Coordinate.X = value; }
+ }
+
+ ///
+ /// Gets or sets the Y rd.
+ ///
+ ///
+ /// The Y rd.
+ ///
+ public double YRd
+ {
+ get { return geometry.Coordinate.Y; }
+ set { geometry.Coordinate.Y = value; }
+ }
+
+ ///
+ /// Gets or sets the Z rd. Same as Depth??
+ ///
+ ///
+ /// The Z rd.
+ ///
+ public double ZRd
+ {
+ get { return geometry.Coordinate.Z; }
+ set { geometry.Coordinate.Z = value; }
+ }
+
+ ///
+ /// Gets a value indicating whether the relative location is specified.
+ ///
+ ///
+ /// true if the relative location is specified; otherwise, false.
+ ///
+ public bool RelativeLocationSpecified { get; private set; }
+
+ private SensorType type;
+
+ ///
+ /// Gets or sets the type of this sensor.
+ ///
+ ///
+ /// The type. Default value is PiezoMetricHead.
+ ///
+ public SensorType Type
+ {
+ get { return type; }
+ set { type = value; }
+ }
+
+ ///
+ /// Gets or sets the PL line array. Used for serialization only.
+ ///
+ ///
+ /// The PL line array.
+ ///
+ [Specification(typeof(NotNullSpecification))]
+ [Specification(typeof(ContiansAtLeastOneItem))]
+ public PLLineType[] PLLineMappings
+ {
+ get { return plLineTypes.ToArray(); }
+ set
+ {
+ ClearPLLines();
+ foreach (var lineType in value)
+ {
+ Add(lineType);
+ }
+ }
+ }
+
+ public string PLLineMappingsAsString
+ {
+ get
+ {
+ string res = "";
+ foreach (var plLineType in plLineTypes)
+ {
+ switch (plLineType)
+ {
+ case PLLineType.PL1: res = res + "1; "; break;
+ case PLLineType.PL2: res = res + "2; "; break;
+ case PLLineType.PL3: res = res + "3; "; break;
+ case PLLineType.PL4: res = res + "4; "; break;
+ }
+ }
+ return res;
+ }
+ set
+ {
+ ClearPLLines();
+ var locPlLineTypes = ParseStringToPlLineTypes(value);
+ foreach (var plLineType in locPlLineTypes)
+ {
+ switch (plLineType)
+ {
+ case 1: plLineTypes.Add(PLLineType.PL1); break;
+ case 2: plLineTypes.Add(PLLineType.PL2); break;
+ case 3: plLineTypes.Add(PLLineType.PL3); break;
+ case 4: plLineTypes.Add(PLLineType.PL4); break;
+ }
+ }
+ }
+ }
+
+ private List ParseStringToPlLineTypes(string value)
+ {
+ value = value.Trim();
+ var ids = new List();
+ var idsarr = value.Split(new Char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
+ foreach (var s in idsarr)
+ {
+ try
+ {
+ var val = Int32.Parse(s);
+ ids.Add(val);
+ }
+ catch (Exception)
+ {
+ // surpress errors, just do not use value
+ }
+ }
+ return ids;
+ }
+
+ ///
+ /// Adds the specified PL line.
+ ///
+ /// The PL line.
+ public void Add(PLLineType plLine)
+ {
+ plLineTypes.Add(plLine);
+ }
+
+ ///
+ /// Removes the specified PL line.
+ ///
+ /// The PL line.
+ public void Remove(PLLineType plLine)
+ {
+ plLineTypes.Remove(plLine);
+ }
+
+ ///
+ /// Clears the PL lines list.
+ ///
+ public void ClearPLLines()
+ {
+ plLineTypes.Clear();
+ }
+
+ ///
+ /// Determines whether this instance is valid.
+ ///
+ ///
+ /// true if this instance is valid; otherwise, false.
+ ///
+ public bool IsValid()
+ {
+ return !Validator.Validate(this).Any();
+ }
+
+ ///
+ /// Determines whether this instance is transient (associated with a correct ID in the context of the repository).
+ ///
+ ///
+ /// true if this instance is transient; otherwise, false.
+ ///
+ public bool IsTransient()
+ {
+ return ID < 0;
+ }
+
+ public override string ToString()
+ {
+ var name = string.IsNullOrWhiteSpace(Name) ? "name_not_set" : Name;
+
+ return string.Format("[ID: {0}, Name: {1}, Depth: {2}, Type: {3}, RelativeLocation: {4}]",
+ ID, name, Depth, Type, RelativeLocation);
+ }
+
+ public bool IsVisible(string property)
+ {
+ switch (property)
+ {
+ case "XRd": return false;
+ case "YRd": return false;
+ case "ZRd": return false;
+ default: return true;
+ }
+ }
+
+ public bool IsEnabled(string property)
+ {
+ return true;
+ }
+ }
+}
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilList.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilList.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilList.cs (revision 282)
@@ -0,0 +1,138 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Delta Shell Light Library.
+//
+// The Delta Shell Light Library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Deltares.DamEngine.Data.Standard.Validation;
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// Holds the soils and provides some handy methods for them
+ ///
+ public class SoilList
+ {
+ private Dictionary aquiferDictionary = new Dictionary();
+ private List soils;
+
+ public SoilList()
+ {
+ soils = new List();
+ }
+
+ ///
+ /// Gets or sets the soils.
+ ///
+ ///
+ /// The soils.
+ ///
+ [Validate]
+ public virtual List Soils
+ {
+ get
+ {
+ return soils;
+ }
+ set
+ {
+ soils = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the aquifer dictionary.
+ /// This dictionary is used for the backward compatibility issue when aquifers still were part of
+ /// soil instead of the layer as it is now.
+ ///
+ ///
+ /// The aquifer dictionary.
+ ///
+ public Dictionary AquiferDictionary
+ {
+ get
+ {
+ return aquiferDictionary;
+ }
+ set
+ {
+ aquiferDictionary = value;
+ }
+ }
+
+ ///
+ /// Gets the index of the soil by its name.
+ ///
+ /// Name of the soil.
+ /// The index when found else -1
+ public virtual int GetSoilIndexByName(string soilName)
+ {
+ var soil = soils.FirstOrDefault(s => s.Name.Equals(
+ soilName, StringComparison.InvariantCultureIgnoreCase));
+
+ return soil == null ? -1 : soils.IndexOf(soil);
+ }
+
+ ///
+ /// Gets the soil by its name.
+ ///
+ /// Name of the soil.
+ /// Soil when found else null
+ public virtual Soil GetSoilByName(string soilName)
+ {
+ var soil = soils.FirstOrDefault(s => s.Name.Equals(
+ soilName, StringComparison.InvariantCultureIgnoreCase));
+
+ return soil;
+ }
+
+ ///
+ /// Adds the specified soil.
+ ///
+ /// The soil.
+ public void Add(Soil soil)
+ {
+ Soils.Add(soil);
+ }
+
+ ///
+ /// Removes the specified soil.
+ ///
+ /// The soil.
+ public void Remove(Soil soil)
+ {
+ Soils.Remove(soil);
+ if (aquiferDictionary.ContainsKey(soil))
+ {
+ aquiferDictionary.Remove(soil);
+ }
+ }
+
+ ///
+ /// Clears this instance (soils and AquiferDictionary).
+ ///
+ public void Clear()
+ {
+ Soils.Clear();
+ aquiferDictionary.Clear();
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilTypes.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilTypes.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SoilTypes.cs (revision 282)
@@ -0,0 +1,35 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Delta Shell Light Library.
+//
+// The Delta Shell Light Library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+namespace Deltares.DamEngine.Data.Geotechnics
+{
+ ///
+ /// Enumerator for commonly used major soil types (Sand, Peat, Loam, Clay, Gravel)
+ ///
+ public enum SoilType
+ {
+ Sand,
+ Peat,
+ Loam,
+ Clay,
+ Gravel
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometrySurface.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometrySurface.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geometry/GeometrySurface.cs (revision 282)
@@ -0,0 +1,185 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.Geometry
+{
+ ///
+ /// Class for geometry surfaces.
+ ///
+ ///
+ [Serializable]
+ public class GeometrySurface : GeometryObject
+ {
+ private readonly List innerLoops = new List();
+ private GeometryLoop outerLoop = new GeometryLoop();
+
+ ///
+ /// Empty constructor
+ ///
+ public GeometrySurface() { }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The loop.
+ public GeometrySurface(GeometryLoop loop)
+ {
+ outerLoop = loop;
+ }
+
+ ///
+ /// The circumference of the surface.
+ ///
+ public GeometryLoop OuterLoop
+ {
+ get
+ {
+ return outerLoop;
+ }
+ set
+ {
+ outerLoop = value;
+ }
+ }
+
+ ///
+ /// All internal loops encompassed by .
+ ///
+ public List InnerLoops
+ {
+ get
+ {
+ return innerLoops;
+ }
+ }
+
+ ///
+ /// determine top of geometry surface outerloop as GeometryPointString
+ ///
+ ///
+ public GeometryPointString DetermineTopGeometrySurface()
+ {
+ return DetermineTopCurves();
+ }
+
+ ///
+ /// determine bottom of geometry surface outerloop as GeometryPointString
+ ///
+ ///
+ public GeometryPointString DetermineBottomGeometrySurface()
+ {
+ return DetermineBottomCurves();
+ }
+
+ ///
+ /// Gets the geometry bounds.
+ ///
+ ///
+ public override GeometryBounds GetGeometryBounds()
+ {
+ return OuterLoop.GetGeometryBounds();
+ }
+
+ ///
+ /// Determine points at the top side of the geometry surface
+ ///
+ ///
+ private GeometryPointString DetermineTopCurves()
+ {
+ //TODO: Lot of similar code to DetermineBottomCurves; Refactoring recommended.
+ var minXPoints = OuterLoop.GetPointsAtX(OuterLoop.GetMinX());
+ var maxXPoints = OuterLoop.GetPointsAtX(OuterLoop.GetMaxX());
+
+ //verticals at start are omitted
+ Point2D startTopPoint = minXPoints.OrderByDescending(p => p.Z).First();
+
+ //verticals at end are omitted
+ Point2D endTopPoint = maxXPoints.OrderByDescending(p => p.Z).First();
+
+ var topPoints = new GeometryPointString();
+
+ int currentIndex = OuterLoop.CalcPoints.IndexOf(startTopPoint);
+
+ while (!topPoints.CalcPoints.Contains(endTopPoint))
+ {
+ topPoints.CalcPoints.Add(OuterLoop.CalcPoints[currentIndex++]);
+ if (currentIndex >= OuterLoop.CalcPoints.Count)
+ {
+ currentIndex = 0;
+ }
+ }
+
+ // Replace the points by clones
+ for (int i = 0; i < topPoints.CalcPoints.Count; i++)
+ {
+ topPoints.CalcPoints[i] = new Point2D(topPoints.CalcPoints[i].X, topPoints.CalcPoints[i].Z);
+ }
+
+ return topPoints;
+ }
+
+ ///
+ /// determine curves at the bottom side of the geometry surface
+ ///
+ ///
+ private GeometryPointString DetermineBottomCurves()
+ {
+ //TODO: Lot of similar code to DetermineTopCurves; Refactoring recommended.
+ //create copy, leave original
+ var minXPoints = OuterLoop.GetPointsAtX(OuterLoop.GetMinX());
+ var maxXPoints = OuterLoop.GetPointsAtX(OuterLoop.GetMaxX());
+
+ //verticals at start are omitted
+ var startBottomPoint = minXPoints.OrderBy(p => p.Z).First();
+
+ //verticals at end are omitted
+ var endBottomPoint = maxXPoints.OrderBy(p => p.Z).First();
+
+ var bottomPoints = new GeometryPointString();
+
+ int currentIndex = OuterLoop.CalcPoints.IndexOf(endBottomPoint);
+
+ while (!bottomPoints.CalcPoints.Contains(startBottomPoint))
+ {
+ bottomPoints.CalcPoints.Add(OuterLoop.CalcPoints[currentIndex++]);
+ if (currentIndex >= OuterLoop.CalcPoints.Count)
+ {
+ currentIndex = 0;
+ }
+ }
+
+ // Replace the points by clones
+ for (int i = 0; i < bottomPoints.CalcPoints.Count; i++)
+ {
+ bottomPoints.CalcPoints[i] = new Point2D(bottomPoints.CalcPoints[i].X, bottomPoints.CalcPoints[i].Z);
+ }
+
+ // As the curves are sorted clockwise, the bottomcurves are always orientated from right to left
+ // while this result of this method must be from left to right so reverse the curves
+ bottomPoints.CalcPoints.Reverse();
+ return bottomPoints;
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/ComputeDoubles.cs
===================================================================
diff -u
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/ComputeDoubles.cs (revision 0)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Standard/ComputeDoubles.cs (revision 282)
@@ -0,0 +1,100 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of the Macro Stability kernel.
+//
+// The Macro Stability kernel 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.Standard
+{
+ ///
+ /// Static helper class ComputeDoubles with static helper methods
+ ///
+ public static class ComputeDoubles
+ {
+ private const double cEpsilon = 1.0e-3;
+
+ ///
+ /// Determines whether two values are nearly the same.
+ ///
+ /// Uses a tolerance of 1e-3.
+ public static bool IsNearEqual(this double aValue1, double aValue2)
+ {
+ return aValue1.IsNearEqual(aValue2, cEpsilon);
+ }
+
+ ///
+ /// Determines whether the specified value is significantly greater than another value.
+ ///
+ /// Uses a tolerance of 1e-3.
+ private static bool IsGreaterThan(this double aValue1, double aValue2)
+ {
+ if (aValue1 - aValue2 > cEpsilon)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Determines whether the specified value is nearly equal to or is greater than
+ /// another value.
+ ///
+ /// Uses a tolerance of 1e-3.
+ public static bool IsGreaterThanOrEqualTo(this double aValue1, double aValue2)
+ {
+ if (aValue1 - aValue2 > -cEpsilon)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Determines whether a value is significantly less than another value.
+ ///
+ /// Uses a tolerance of 1e-3.
+ public static bool IsLessThan(this double aValue1, double aValue2)
+ {
+ return !IsGreaterThanOrEqualTo(aValue1, aValue2);
+ }
+
+ ///
+ /// Determines whether a value is insignificantly greater than, is equal to or is
+ /// less than another value.
+ ///
+ /// Uses a tolerance of 1e-3.
+ public static bool IsLessThanOrEqualTo(this double aValue1, double aValue2)
+ {
+ return !IsGreaterThan(aValue1, aValue2);
+ }
+
+ private static bool IsNearEqual(this double aValue1, double aValue2, double aTolerance)
+ {
+ if (Math.Abs(aValue1 - aValue2) < aTolerance)
+ {
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/CharacteristicPointSet.cs
===================================================================
diff -u -r278 -r282
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/CharacteristicPointSet.cs (.../CharacteristicPointSet.cs) (revision 278)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/CharacteristicPointSet.cs (.../CharacteristicPointSet.cs) (revision 282)
@@ -566,6 +566,6 @@
// Set new annotation definition:
typeCache[item.CharacteristicPointType] = item.GeometryPoint;
}
- }
+ }
}
}
\ No newline at end of file
Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2.cs
===================================================================
diff -u -r278 -r282
--- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2.cs (.../SurfaceLine2.cs) (revision 278)
+++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2.cs (.../SurfaceLine2.cs) (revision 282)
@@ -19,6 +19,7 @@
// 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.Geometry;