Index: Core/Common/test/Core.Common.Utils.Tests/Core.Common.Utils.Tests.csproj =================================================================== diff -u -r9fe57fedb75ef27ce331c15d17e55db233a1f4d6 -r2da86d14cee084c7d6bfa52136d387cdcdb0a025 --- Core/Common/test/Core.Common.Utils.Tests/Core.Common.Utils.Tests.csproj (.../Core.Common.Utils.Tests.csproj) (revision 9fe57fedb75ef27ce331c15d17e55db233a1f4d6) +++ Core/Common/test/Core.Common.Utils.Tests/Core.Common.Utils.Tests.csproj (.../Core.Common.Utils.Tests.csproj) (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -121,6 +121,10 @@ + + {CE994CC9-6F6A-48AC-B4BE-02C30A21F4DB} + Ringtoets.Piping.Data + {F49BD8B2-332A-4C91-A196-8CCE0A2C7D98} Core.Common.Utils Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/Point2D.cs =================================================================== diff -u -ra950714ad9510756331d862aa35695fa0b2ed03b -r2da86d14cee084c7d6bfa52136d387cdcdb0a025 --- Ringtoets/Piping/src/Ringtoets.Piping.Data/Point2D.cs (.../Point2D.cs) (revision a950714ad9510756331d862aa35695fa0b2ed03b) +++ Ringtoets/Piping/src/Ringtoets.Piping.Data/Point2D.cs (.../Point2D.cs) (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -1,5 +1,4 @@ using System; - using MathNet.Numerics.LinearAlgebra.Double; namespace Ringtoets.Piping.Data @@ -10,6 +9,24 @@ public class Point2D { /// + /// Creates a new instance of , with set to 0 + /// and set to 0. + /// + public Point2D() {} + + /// + /// Creates a new instance of , with set to + /// and set to . + /// + /// The x coordinate to set. + /// The y coordinate to set. + public Point2D(double x, double y) + { + X = x; + Y = y; + } + + /// /// Gets or sets the x coordinate. /// public double X { get; set; } @@ -47,15 +64,15 @@ { return false; } - return Equals((Point2D)obj); + return Equals((Point2D) obj); } public override int GetHashCode() { unchecked { var hashCode = X.GetHashCode(); - hashCode = (hashCode * 397) ^ Y.GetHashCode(); + hashCode = (hashCode*397) ^ Y.GetHashCode(); return hashCode; } } Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/Properties/Resources.Designer.cs =================================================================== diff -u -r5d53c93d9e66f38ca73d333f85855ec815f962c5 -r2da86d14cee084c7d6bfa52136d387cdcdb0a025 --- Ringtoets/Piping/src/Ringtoets.Piping.Data/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 5d53c93d9e66f38ca73d333f85855ec815f962c5) +++ Ringtoets/Piping/src/Ringtoets.Piping.Data/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.18444 +// Runtime Version:4.0.30319.34209 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -97,6 +97,15 @@ } /// + /// Looks up a localized string similar to Voor het maken van een segment zijn twee punten nodig.. + /// + internal static string Segment2D_Constructor_Segment_must_be_created_with_two_points { + get { + return ResourceManager.GetString("Segment2D_Constructor_Segment_must_be_created_with_two_points", resourceCulture); + } + } + + /// /// Looks up a localized string similar to Standaard afwijking (σ) moet groter zijn dan 0.. /// internal static string StandardDeviation_Should_be_greater_then_zero { Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/Properties/Resources.resx =================================================================== diff -u -r5d53c93d9e66f38ca73d333f85855ec815f962c5 -r2da86d14cee084c7d6bfa52136d387cdcdb0a025 --- Ringtoets/Piping/src/Ringtoets.Piping.Data/Properties/Resources.resx (.../Resources.resx) (revision 5d53c93d9e66f38ca73d333f85855ec815f962c5) +++ Ringtoets/Piping/src/Ringtoets.Piping.Data/Properties/Resources.resx (.../Resources.resx) (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -132,4 +132,7 @@ Een kansverdeling moet opgegeven zijn om op basis van die data een rekenwaarde te bepalen. + + Voor het maken van een segment zijn twee punten nodig. + \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/Ringtoets.Piping.Data.csproj =================================================================== diff -u -r5d53c93d9e66f38ca73d333f85855ec815f962c5 -r2da86d14cee084c7d6bfa52136d387cdcdb0a025 --- Ringtoets/Piping/src/Ringtoets.Piping.Data/Ringtoets.Piping.Data.csproj (.../Ringtoets.Piping.Data.csproj) (revision 5d53c93d9e66f38ca73d333f85855ec815f962c5) +++ Ringtoets/Piping/src/Ringtoets.Piping.Data/Ringtoets.Piping.Data.csproj (.../Ringtoets.Piping.Data.csproj) (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -69,6 +69,7 @@ True Resources.resx + Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/Segment2D.cs =================================================================== diff -u --- Ringtoets/Piping/src/Ringtoets.Piping.Data/Segment2D.cs (revision 0) +++ Ringtoets/Piping/src/Ringtoets.Piping.Data/Segment2D.cs (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -0,0 +1,94 @@ +using System; +using Ringtoets.Piping.Data.Properties; + +namespace Ringtoets.Piping.Data +{ + public class Segment2D + { + public Segment2D(Point2D first, Point2D second) + { + if (first == null || second == null) + { + throw new ArgumentException(Resources.Segment2D_Constructor_Segment_must_be_created_with_two_points); + } + FirstPoint = first; + SecondPoint = second; + } + + public Point2D FirstPoint { get; private set; } + + public Point2D SecondPoint { get; private set; } + + /// + /// This method determines whether is contained by the + /// and x coordinates. + /// + /// The x for which to find out whether it is contained by the + /// and . + /// true if x is on or between the points' x coordinates. false otherwise. + public bool ContainsX(double x) + { + var distanceFirstPoint = FirstPoint.X - x; + var distanceSecondPoint = SecondPoint.X - x; + + var onPoint = Math.Abs(FirstPoint.X - x) < 1e-8 || Math.Abs(SecondPoint.X - x) < 1e-8; + + return onPoint || Math.Sign(distanceFirstPoint) != Math.Sign(distanceSecondPoint); + } + + /// + /// Determines whether the is vertical. + /// + /// true if the is vertical. false otherwise. + public bool IsVertical() + { + return Math.Abs(FirstPoint.X - SecondPoint.X) < 1e-8; + } + + protected bool Equals(Segment2D other) + { + return FirstPoint.Equals(other.FirstPoint) && SecondPoint.Equals(other.SecondPoint) || + FirstPoint.Equals(other.SecondPoint) && SecondPoint.Equals(other.FirstPoint); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + if (ReferenceEquals(this, obj)) + { + return true; + } + if (obj.GetType() != this.GetType()) + { + return false; + } + return Equals((Segment2D) obj); + } + + public override int GetHashCode() + { + unchecked + { + return ((FirstPoint.X + SecondPoint.X).GetHashCode() * 397) ^ (FirstPoint.Y + SecondPoint.Y).GetHashCode(); + } + } + + /// + /// Determines whether two segments are connected by each other's + /// and . + /// + /// The segment which may be connected to the . + /// true if the segments are connected. false otherwise. + public bool IsConnected(Segment2D segment) + { + return + FirstPoint.Equals(segment.FirstPoint) || + FirstPoint.Equals(segment.SecondPoint) || + SecondPoint.Equals(segment.FirstPoint) || + SecondPoint.Equals(segment.SecondPoint); + } + } +} \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilLayer2D.cs =================================================================== diff -u -r97c9e382dffcf32dc34d2e05e6a8a475b833ebd4 -r2da86d14cee084c7d6bfa52136d387cdcdb0a025 --- Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilLayer2D.cs (.../SoilLayer2D.cs) (revision 97c9e382dffcf32dc34d2e05e6a8a475b833ebd4) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilLayer2D.cs (.../SoilLayer2D.cs) (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -14,12 +14,15 @@ /// internal class SoilLayer2D { + private readonly Collection> innerLoops; + private List outerLoop; + /// /// Creates a new instance of . /// public SoilLayer2D() { - InnerLoops = new Collection>(); + innerLoops = new Collection>(); } /// @@ -43,16 +46,53 @@ public double? DryUnitWeight { get; set; } /// - /// Gets the outer loop of the as a of . + /// Gets the outer loop of the as a of , + /// for which each of the segments are connected to the next. /// - internal HashSet OuterLoop { get; set; } + /// Thrown when the does not form a loop. + internal List OuterLoop + { + get + { + return outerLoop; + } + set + { + if (value.Count == 1 || !IsLoopConnected(value)) + { + throw new ArgumentException(Resources.SoilLayer2D_Error_Loop_contains_disconnected_segments); + } + outerLoop = value; + } + } /// - /// Gets the of inner loops (as of ) of the . + /// Gets the of inner loops (as of , + /// for which each of the segments are connected to the next) of the . /// - internal Collection> InnerLoops { get; private set; } + internal IEnumerable> InnerLoops + { + get + { + return innerLoops; + } + } /// + /// Adds an inner loop to the geometry. + /// + /// The innerloop to add. + /// Thrown when the does not form a loop. + internal void AddInnerLoop(List innerLoop) + { + if (innerLoop.Count == 1 || !IsLoopConnected(innerLoop)) + { + throw new ArgumentException(Resources.SoilLayer2D_Error_Loop_contains_disconnected_segments); + } + innerLoops.Add(innerLoop); + } + + /// /// Constructs a (1D) based on the and set for the . /// /// The point from which to take a 1D profile. @@ -95,6 +135,25 @@ return result; } + private static bool IsLoopConnected(List segments) + { + int segmentCount = segments.Count; + if (segmentCount == 2) + { + return segments[0].Equals(segments[1]); + } + for (int i = 0; i < segmentCount; i++) + { + var segmentA = segments[i]; + var segmentB = segments[(i + 1)%segmentCount]; + if (!segmentA.IsConnected(segmentB)) + { + return false; + } + } + return true; + } + private double EnsureBottomOutsideInnerLoop(IEnumerable> innerLoopIntersectionHeightPairs, double bottom) { var newBottom = bottom; @@ -155,60 +214,44 @@ /// intersects the vertical line at . /// Thrown when a segment is vertical at and thus /// no deterministic intersection points can be determined. - private Collection GetLoopIntersectionHeights(HashSet loop, double atX) + private Collection GetLoopIntersectionHeights(List loop, double atX) { Collection intersectionPointY = new Collection(); - for (int segmentIndex = 0; segmentIndex < loop.Count; segmentIndex++) + foreach (Segment2D segment in loop) { - var intersectionPoint = GetSegmentIntersectionAtX(loop, segmentIndex, atX); - - if (intersectionPoint.Length > 0) + if (!segment.ContainsX(atX)) { - intersectionPointY.Add(intersectionPoint[1]); + continue; } - else if (IsVerticalAtX(GetSegmentWithStartAtIndex(loop, segmentIndex), atX)) + if (segment.IsVertical()) { throw new SoilLayer2DConversionException(String.Format(Resources.Error_Can_not_determine_1D_profile_with_vertical_segments_at_x, atX)); } + + var intersectionPoint = GetSegmentIntersectionAtX(segment, atX); + + if (intersectionPoint != null) + { + intersectionPointY.Add(intersectionPoint.Y); + } } + return intersectionPointY; } - private bool IsVerticalAtX(Point3D[] segment, double atX) + private Point2D GetSegmentIntersectionAtX(Segment2D segment, double x) { - return Math.Abs(segment[0].X - atX) + Math.Abs(segment[1].X - atX) < Math2D.EpsilonForComparisons; - } - - private static Point3D[] GetSegmentWithStartAtIndex(HashSet loop, int i) - { - var current = loop.ElementAt(i); - var next = loop.ElementAt((i + 1)%loop.Count); - - return new[] + var verticalLineFirstPoint = new Point2D { - current, - next + X = x, Y = 0 }; - } - - private static double[] GetSegmentIntersectionAtX(HashSet loop, int segmentIndex, double atX) - { - Point3D[] segment = GetSegmentWithStartAtIndex(loop, segmentIndex); - - return Math2D.LineSegmentIntersectionWithLine(new[] + var verticalLineSecondPoint = new Point2D { - segment[0].X, - segment[1].X, - atX, - atX - }, new[] - { - segment[0].Z, - segment[1].Z, - 0, - 1 - }); + X = x, Y = 1 + }; + + return Math2D.LineIntersectionWithLine(segment.FirstPoint, segment.SecondPoint, verticalLineFirstPoint, verticalLineSecondPoint); } } } \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Calculation/Math2D.cs =================================================================== diff -u -r97c9e382dffcf32dc34d2e05e6a8a475b833ebd4 -r2da86d14cee084c7d6bfa52136d387cdcdb0a025 --- Ringtoets/Piping/src/Ringtoets.Piping.IO/Calculation/Math2D.cs (.../Math2D.cs) (revision 97c9e382dffcf32dc34d2e05e6a8a475b833ebd4) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Calculation/Math2D.cs (.../Math2D.cs) (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -1,4 +1,5 @@ using System; +using Ringtoets.Piping.Data; using Ringtoets.Piping.IO.Properties; namespace Ringtoets.Piping.IO.Calculation @@ -13,137 +14,30 @@ /// public const double EpsilonForComparisons = 1e-8; - /// - /// Tries to find the point where two line segments intersect with each other. Note that if the lines are parallel, no intersection point is returned. - /// - /// X coordinates of the segments. Should have matching y coordinates in . - /// Y coordinates of the segments. Should have matching x coordinates in . - /// An array of double representing the point where the line segments intersect ((x,y) = (array[0],array[1])). - /// Thrown when either or is not of length 4. - public static double[] LineSegmentIntersectionWithLineSegment(double[] segmentsX, double[] segmentsY) - { - var extraPolatedIntersectionPoint = LineSegmentIntersectionWithLine(segmentsX, segmentsY); - - if (extraPolatedIntersectionPoint.Length == 2) - { - var onSecondSegment = IsBetween(new[] - { - segmentsX[2], - segmentsX[3], - extraPolatedIntersectionPoint[0] - }, new[] - { - segmentsY[2], - segmentsY[3], - extraPolatedIntersectionPoint[1] - }); - if (onSecondSegment) - { - return extraPolatedIntersectionPoint; - } - } - return new double[0]; - } - - /// - /// Tries to find the point where the line segment intersects with the line. Note that if the segment and the line are parallel, no intersection point is returned. - /// - /// X coordinates of the segment and line. Should have matching y coordinates in . - /// Y coordinates of the segment and line. Should have matching x coordinates in . - /// An array of double representing the point where the line segment intersects with the line - /// ((x,y) = (array[0],array[1])). - /// Thrown when either or is not of length 4. - public static double[] LineSegmentIntersectionWithLine(double[] segmentsX, double[] segmentsY) - { - var extraPolatedIntersectionPoint = LineIntersectionWithLine(segmentsX, segmentsY); - - if (extraPolatedIntersectionPoint.Length == 2) - { - var onFirstSegment = IsBetween(new[] - { - segmentsX[0], - segmentsX[1], - extraPolatedIntersectionPoint[0] - }, new[] - { - segmentsY[0], - segmentsY[1], - extraPolatedIntersectionPoint[1] - }); - if (onFirstSegment) - { - return extraPolatedIntersectionPoint; - } - } - return new double[0]; - } - /// /// Taken from: https://www.topcoder.com/community/data-science/data-science-tutorials/geometry-concepts-line-intersection-and-its-applications/ /// Based on https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection /// - /// Thrown when either or is not of length 4. - private static double[] LineIntersectionWithLine(double[] linesX, double[] linesY) + public static Point2D LineIntersectionWithLine(Point2D firstPoint, Point2D secondPoint, Point2D verticalLineFirstPoint, Point2D verticalLineSecondPoint) { - var numberOfPoints = 4; - if (linesX.Length != numberOfPoints || linesY.Length != numberOfPoints) - { - throw new ArgumentException(String.Format(Resources.Error_Collections_of_lines_coordinates_need_length_of_0_, numberOfPoints)); - } + var aLine = secondPoint.Y - firstPoint.Y; + var bLine = firstPoint.X - secondPoint.X; + var cLine = aLine * firstPoint.X + bLine * firstPoint.Y; - var aLine = linesY[1] - linesY[0]; - var bLine = linesX[0] - linesX[1]; - var cLine = aLine * linesX[0] + bLine * linesY[0]; + var aOtherLine = verticalLineSecondPoint.Y - verticalLineFirstPoint.Y; + var bOtherLine = verticalLineFirstPoint.X - verticalLineSecondPoint.X; + var cOtherLine = aOtherLine * verticalLineFirstPoint.X + bOtherLine * verticalLineFirstPoint.Y; - var aOtherLine = linesY[3] - linesY[2]; - var bOtherLine = linesX[2] - linesX[3]; - var cOtherLine = aOtherLine * linesX[2] + bOtherLine * linesY[2]; - - var determinant = aLine*bOtherLine - aOtherLine*bLine; + var determinant = aLine * bOtherLine - aOtherLine * bLine; if (Math.Abs(determinant) < EpsilonForComparisons) { - return new double[0]; + return null; } - return new[] - { - (bOtherLine*cLine - bLine*cOtherLine)/determinant, - (aLine*cOtherLine - aOtherLine*cLine)/determinant + return new Point2D { + X = (bOtherLine*cLine - bLine*cOtherLine)/determinant, + Y = (aLine*cOtherLine - aOtherLine*cLine)/determinant }; } - - /// - /// Checks whether point [2],[2] lies between [0],[0] - /// and [1],[1]. - /// - /// X-coordinates of the 3 points. - /// Y-coordinates of the 3 points. - /// True if point [2],[2] lies between [0],[0] - /// and [1],[1]. False otherwise. - private static bool IsBetween(double[] x, double[] y) - { - if (Math.Abs(CrossProduct(x, y)) > EpsilonForComparisons) - { - return false; - } - - if (DotProduct(x, y) < 0) - { - return false; - } - - var squaredLengthSegment = (x[1] - x[0])*(x[1] - x[0]) + (y[1] - y[0])*(y[1] - y[0]); - return DotProduct(x, y) <= squaredLengthSegment; - } - - private static double DotProduct(double[] x, double[] y) - { - return (x[2] - x[0])*(x[1] - x[0]) + (y[2] - y[0])*(y[1] - y[0]); - } - - private static double CrossProduct(double[] x, double[] y) - { - return (y[2] - y[0])*(x[1] - x[0]) - (x[2] - x[0])*(y[1] - y[0]); - } } } \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/PipingSoilLayer2DReader.cs =================================================================== diff -u -ra950714ad9510756331d862aa35695fa0b2ed03b -r2da86d14cee084c7d6bfa52136d387cdcdb0a025 --- Ringtoets/Piping/src/Ringtoets.Piping.IO/PipingSoilLayer2DReader.cs (.../PipingSoilLayer2DReader.cs) (revision a950714ad9510756331d862aa35695fa0b2ed03b) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/PipingSoilLayer2DReader.cs (.../PipingSoilLayer2DReader.cs) (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Globalization; using System.IO; using System.Xml; @@ -20,8 +21,8 @@ private const string innerLoopElementName = "InnerLoop"; private const string endPointElementName = "EndPoint"; private const string headPointElementName = "HeadPoint"; + private const string geometryCurveElementName = "GeometryCurve"; private const string xElementName = "X"; - private const string yElementName = "Y"; private const string zElementName = "Z"; private readonly XmlTextReader xmlTextReader; @@ -50,15 +51,15 @@ while (xmlTextReader.Read()) { - HashSet outerLoop; - HashSet innerLoop; + List outerLoop; + List innerLoop; if (TryParseLoop(outerLoopElementName, out outerLoop)) { pipingSoilLayer.OuterLoop = outerLoop; } if (TryParseLoop(innerLoopElementName, out innerLoop)) { - pipingSoilLayer.InnerLoops.Add(innerLoop); + pipingSoilLayer.AddInnerLoop(innerLoop); } } @@ -71,22 +72,24 @@ /// The name of the element which the reader should be currently pointing at. /// The result of parsing the element as a loop. null if the current element's name does not match . /// True if the reader currently points to an element with name . False otherwise. - private bool TryParseLoop(String elementName, out HashSet loop) + /// Thrown when not both HeadPoint and EndPoint are defined in + /// the GeometryCurve XML element. + private bool TryParseLoop(string elementName, out List loop) { loop = null; if (IsElementWithName(elementName)) { - loop = new HashSet(); + loop = new List(); if (!IsEmptyElement()) { while (xmlTextReader.Read() && !IsEndElementWithName(elementName)) { - Point3D parsedPoint; - if (TryParsePoint(out parsedPoint)) + Segment2D segment; + if (TryParseSegment(out segment)) { - loop.Add(parsedPoint); + loop.Add(segment); } } } @@ -96,6 +99,42 @@ } /// + /// Tries to parse a GeometryCurve XML element to a . + /// + /// The segment reference in which to put the parsed . + /// true if a segment could be parsed. false otherwise. + /// Thrown when not both HeadPoint and EndPoint are defined in + /// the GeometryCurve XML element. + private bool TryParseSegment(out Segment2D segment) + { + segment = null; + if (IsElementWithName(geometryCurveElementName) || IsElementWithName(endPointElementName)) + { + var points = new Point2D[2]; + var index = 0; + while (xmlTextReader.Read() && !IsEndElementWithName(geometryCurveElementName)) + { + Point2D point; + if (TryParsePoint(out point)) + { + points[index] = point; + index++; + } + } + try + { + segment = new Segment2D(points[0], points[1]); + return true; + } + catch (ArgumentException e) + { + throw new XmlException(e.Message, e); + } + } + return false; + } + + /// /// Finds out whether the element which the reader is currently pointing at is empty. /// /// True if the element is empty. False otherwise. @@ -109,18 +148,17 @@ /// /// The result of parsing the element as a point. null if current element is not a head or end point. /// True if the reader currently points to an element with name or . False otherwise. - private bool TryParsePoint(out Point3D point) + private bool TryParsePoint(out Point2D point) { point = null; if (IsElementWithName(headPointElementName) || IsElementWithName(endPointElementName)) { var pointValues = ReadChildValues(); - point = new Point3D + point = new Point2D { X = double.Parse(pointValues[xElementName], CultureInfo.InvariantCulture), - Y = double.Parse(pointValues[yElementName], CultureInfo.InvariantCulture), - Z = double.Parse(pointValues[zElementName], CultureInfo.InvariantCulture) + Y = double.Parse(pointValues[zElementName], CultureInfo.InvariantCulture) }; return true; } Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.Designer.cs =================================================================== diff -u -r97c9e382dffcf32dc34d2e05e6a8a475b833ebd4 -r2da86d14cee084c7d6bfa52136d387cdcdb0a025 --- Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 97c9e382dffcf32dc34d2e05e6a8a475b833ebd4) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -205,7 +205,7 @@ } /// - /// Looks up a localized string similar to Kan de geometry van laag nummer '{0}' in profiel '{1}' niet interpreteren.. + /// Looks up a localized string similar to Kan de geometrie van laag nummer '{0}' in profiel '{1}' niet interpreteren.. /// public static string PipingSoilProfileReader_CouldNotParseGeometryOfLayer_0_InProfile_1_ { get { @@ -285,5 +285,14 @@ return ResourceManager.GetString("PipingSurfaceLinesCsvReader_ReadLine_File_0_Line_1_no_ID", resourceCulture); } } + + /// + /// Looks up a localized string similar to De segmenten van de geometrie van de laag vormen geen lus.. + /// + public static string SoilLayer2D_Error_Loop_contains_disconnected_segments { + get { + return ResourceManager.GetString("SoilLayer2D_Error_Loop_contains_disconnected_segments", resourceCulture); + } + } } } Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.resx =================================================================== diff -u -r97c9e382dffcf32dc34d2e05e6a8a475b833ebd4 -r2da86d14cee084c7d6bfa52136d387cdcdb0a025 --- Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.resx (.../Resources.resx) (revision 97c9e382dffcf32dc34d2e05e6a8a475b833ebd4) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.resx (.../Resources.resx) (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -181,7 +181,7 @@ Het bestand '{0}' heeft op regel {1} heeft geen ID. - Kan de geometry van laag nummer '{0}' in profiel '{1}' niet interpreteren. + Kan de geometrie van laag nummer '{0}' in profiel '{1}' niet interpreteren. De database heeft niet de vereiste versie informatie. Vereiste versie is: {0}. @@ -192,4 +192,7 @@ Kon profiel '{0}' niet opbouwen vanuit de gegevens uit de database. + + De segmenten van de geometrie van de laag vormen geen lus. + \ No newline at end of file Index: Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/Point2DTest.cs =================================================================== diff -u -r8df04aa7166563cc67a1b7e70f9f4b8867e454b7 -r2da86d14cee084c7d6bfa52136d387cdcdb0a025 --- Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/Point2DTest.cs (.../Point2DTest.cs) (revision 8df04aa7166563cc67a1b7e70f9f4b8867e454b7) +++ Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/Point2DTest.cs (.../Point2DTest.cs) (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -21,6 +21,21 @@ } [Test] + public void Constructor_WithXandY_SetPropeties() + { + // Setup + var random = new Random(22); + var x = random.NextDouble(); + var y = random.NextDouble(); + + // Call + var point = new Point2D(x,y); + + // Assert + Assert.AreEqual(x, point.X); + Assert.AreEqual(y, point.Y); + } + [Test] public void AutomaticProperties_SetAndGetValuesAgain_ReturnedValueShouldBeSameAsSetValue() { // Setup Index: Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/PointCollectionHelperTest.cs =================================================================== diff -u -r97c9e382dffcf32dc34d2e05e6a8a475b833ebd4 -r2da86d14cee084c7d6bfa52136d387cdcdb0a025 --- Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/PointCollectionHelperTest.cs (.../PointCollectionHelperTest.cs) (revision 97c9e382dffcf32dc34d2e05e6a8a475b833ebd4) +++ Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/PointCollectionHelperTest.cs (.../PointCollectionHelperTest.cs) (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -22,8 +22,8 @@ // Assert Assert.AreEqual(1, result.Length); - Assert.AreEqual(2, result[0].X); - Assert.AreEqual(2, result[0].Z); + Assert.AreEqual(2, result[0].FirstPoint.X); + Assert.AreEqual(2, result[0].FirstPoint.Y); } [Test] @@ -39,10 +39,10 @@ // Assert Assert.AreEqual(2, result.Length); - Assert.AreEqual(2, result[0].X); - Assert.AreEqual(2, result[0].Z); - Assert.AreEqual(4, result[1].X); - Assert.AreEqual(0, result[1].Z); + Assert.AreEqual(2, result[0].FirstPoint.X); + Assert.AreEqual(2, result[0].FirstPoint.Y); + Assert.AreEqual(4, result[0].SecondPoint.X); + Assert.AreEqual(0, result[0].SecondPoint.Y); } [Test] @@ -58,10 +58,10 @@ // Assert Assert.AreEqual(2, result.Length); - Assert.AreEqual(2, result[1].X); - Assert.AreEqual(2, result[1].Z); - Assert.AreEqual(4, result[0].X); - Assert.AreEqual(0, result[0].Z); + Assert.AreEqual(2, result[0].SecondPoint.X); + Assert.AreEqual(2, result[0].SecondPoint.Y); + Assert.AreEqual(4, result[0].FirstPoint.X); + Assert.AreEqual(0, result[0].FirstPoint.Y); } } } \ No newline at end of file Index: Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/Ringtoets.Piping.Data.Test.csproj =================================================================== diff -u -r5d53c93d9e66f38ca73d333f85855ec815f962c5 -r2da86d14cee084c7d6bfa52136d387cdcdb0a025 --- Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/Ringtoets.Piping.Data.Test.csproj (.../Ringtoets.Piping.Data.Test.csproj) (revision 5d53c93d9e66f38ca73d333f85855ec815f962c5) +++ Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/Ringtoets.Piping.Data.Test.csproj (.../Ringtoets.Piping.Data.Test.csproj) (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -62,6 +62,7 @@ + Index: Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/Segment2DTest.cs =================================================================== diff -u --- Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/Segment2DTest.cs (revision 0) +++ Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/Segment2DTest.cs (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -0,0 +1,278 @@ +using System; +using NUnit.Framework; + +namespace Ringtoets.Piping.Data.Test +{ + [TestFixture] + public class Segment2DTest + { + [Test] + public void Constructor_WithTwoPoints_ReturnsSegmentWithPointsSet() + { + // Call + var firstPoint = new Point2D(); + var secondPoint = new Point2D(); + var segment = new Segment2D(firstPoint, secondPoint); + + // Assert + Assert.AreSame(firstPoint, segment.FirstPoint); + Assert.AreSame(secondPoint, segment.SecondPoint); + } + + [Test] + [TestCase(1, 2, 1.5, true)] + [TestCase(1, 2, 1 + 1e-6, true)] + [TestCase(1, 2, 2 - 1e-6, true)] + [TestCase(1, 2, 2, true)] + [TestCase(1, 2, 1, true)] + [TestCase(1, 1, 1, true)] + [TestCase(1, 2, 0, false)] + [TestCase(1, 2, 3, false)] + [TestCase(1, 2, 2 + 1e-6, false)] + [TestCase(1, 2, 1 - 1e-6, false)] + public void ContainsX_DifferentSetsOfX_ReturnsTrue(double firstPointX, double secondPointX, double containedX, bool isContained) + { + // Setup + var random = new Random(22); + var firstPoint = new Point2D + { + X = firstPointX, + Y = random.NextDouble() + }; + var secondPoint = new Point2D + { + X = secondPointX, + Y = random.NextDouble() + }; + var segment = new Segment2D(firstPoint, secondPoint); + + // Call + var result = segment.ContainsX(containedX); + + // Assert + Assert.AreEqual(isContained, result); + } + + [Test] + [TestCase(1, 1, true)] + [TestCase(1, 2, false)] + [TestCase(1, 1 + 1e-6, false)] + [TestCase(1, 1 - 1e-6, false)] + [TestCase(1, 1 + 1e-9, true)] + [TestCase(1, 1 - 1e-9, true)] + public void IsVertical_DifferentSetsOfX_ReturnsFalse(double firstPointX, double secondPointX, bool isVertical) + { + // Setup + var random = new Random(22); + var firstPoint = new Point2D + { + X = firstPointX, + Y = random.NextDouble() + }; + var secondPoint = new Point2D + { + X = secondPointX, + Y = random.NextDouble() + }; + var segment = new Segment2D(firstPoint, secondPoint); + + // Call + var result = segment.IsVertical(); + + // Assert + Assert.AreEqual(isVertical, result); + } + + [Test] + public void Equals_SameSegment_ReturnsTrue() + { + // Setup + var random = new Random(22); + var x1 = random.NextDouble(); + var x2 = random.NextDouble(); + var y1 = random.NextDouble(); + var y2 = random.NextDouble(); + var point1 = new Point2D(x1, y1); + var point2 = new Point2D(x2, y2); + var segment = new Segment2D(point1, point2); + + // Call & Assert + Assert.IsTrue(segment.Equals(segment)); + } + + [Test] + public void Equals_WithNull_ReturnsFalse() + { + // Setup + var random = new Random(22); + var x1 = random.NextDouble(); + var x2 = random.NextDouble(); + var y1 = random.NextDouble(); + var y2 = random.NextDouble(); + var point1 = new Point2D(x1, y1); + var point2 = new Point2D(x2, y2); + var segment = new Segment2D(point1, point2); + + // Call & Assert + Assert.IsFalse(segment.Equals(null)); + } + + [Test] + public void Equals_SegmentWithTwoPointsWithSameXY_ReturnsTrue() + { + // Setup + var random = new Random(22); + var x1 = random.NextDouble(); + var x2 = random.NextDouble(); + var y1 = random.NextDouble(); + var y2 = random.NextDouble(); + var point1 = new Point2D(x1, y1); + var point2 = new Point2D(x2, y2); + var segment1 = new Segment2D(point1, point2); + var segment2 = new Segment2D(point1, point2); + var segment3 = new Segment2D(point2, point1); + + // Call & Assert + Assert.IsTrue(segment1.Equals(segment2)); + Assert.IsTrue(segment1.Equals(segment3)); + } + + [Test] + public void Equals_SegmentWithTwoPointsWithDifferentXY_ReturnsFalse() + { + // Setup + var random = new Random(22); + var x1 = random.NextDouble(); + var x2 = random.NextDouble(); + var x3 = random.NextDouble(); + var x4 = random.NextDouble(); + var y1 = random.NextDouble(); + var y2 = random.NextDouble(); + var y3 = random.NextDouble(); + var y4 = random.NextDouble(); + var point1 = new Point2D(x1, y1); + var point2 = new Point2D(x2, y2); + var point3 = new Point2D(x3, y3); + var point4 = new Point2D(x4, y4); + var segment1 = new Segment2D(point1, point2); + var segment2 = new Segment2D(point3, point4); + + // Call & Assert + Assert.IsFalse(segment1.Equals(segment2)); + Assert.IsFalse(segment2.Equals(segment1)); + } + + [Test] + public void GetHashCode_EqualSegments_AreEqual() + { + // Setup + var random = new Random(22); + var x1 = random.NextDouble(); + var x2 = random.NextDouble(); + var y1 = random.NextDouble(); + var y2 = random.NextDouble(); + var point1 = new Point2D(x1, y1); + var point2 = new Point2D(x2, y2); + var segment1 = new Segment2D(point1, point2); + var segment2 = new Segment2D(point1, point2); + var segment3 = new Segment2D(point2, point1); + + // Call & Assert + Assert.AreEqual(segment1.GetHashCode(), segment1.GetHashCode()); + Assert.AreEqual(segment1.GetHashCode(), segment2.GetHashCode()); + Assert.AreEqual(segment1.GetHashCode(), segment3.GetHashCode()); + } + + [Test] + public void IsConnected_SameSegment_True() + { + // Setup + var random = new Random(22); + var x1 = random.NextDouble(); + var x2 = random.NextDouble(); + var y1 = random.NextDouble(); + var y2 = random.NextDouble(); + var point1 = new Point2D(x1, y1); + var point2 = new Point2D(x2, y2); + var segment1 = new Segment2D(point1, point2); + + // Call & Assert + Assert.IsTrue(segment1.IsConnected(segment1)); + } + + [Test] + public void IsConnected_EqualSegments_True() + { + // Setup + var random = new Random(22); + var x1 = random.NextDouble(); + var x2 = random.NextDouble(); + var y1 = random.NextDouble(); + var y2 = random.NextDouble(); + var point1 = new Point2D(x1, y1); + var point2 = new Point2D(x2, y2); + var segment1 = new Segment2D(point1, point2); + var segment2 = new Segment2D(point1, point2); + + // Call & Assert + Assert.IsTrue(segment1.IsConnected(segment2)); + Assert.IsTrue(segment2.IsConnected(segment1)); + } + + [Test] + public void IsConnected_ThreeSegments_AreAllConnected() + { + // Setup + var random = new Random(22); + var x1 = random.NextDouble(); + var x2 = random.NextDouble(); + var x3 = random.NextDouble(); + var y1 = random.NextDouble(); + var y2 = random.NextDouble(); + var y3 = random.NextDouble(); + + var point1 = new Point2D(x1, y1); + var point2 = new Point2D(x2, y2); + var point3 = new Point2D(x3, y3); + var segment1 = new Segment2D(point1, point2); + var segment2 = new Segment2D(point2, point3); + var segment3 = new Segment2D(point1, point3); + + // Call & Assert + Assert.IsTrue(segment1.IsConnected(segment2)); + Assert.IsTrue(segment1.IsConnected(segment3)); + + Assert.IsTrue(segment2.IsConnected(segment1)); + Assert.IsTrue(segment2.IsConnected(segment3)); + + Assert.IsTrue(segment3.IsConnected(segment1)); + Assert.IsTrue(segment3.IsConnected(segment2)); + } + + [Test] + public void IsConnected_ThreeSegments_AreAllDisconnected() + { + // Setup + var random = new Random(22); + var x1 = random.NextDouble(); + var x2 = random.NextDouble(); + var x3 = random.NextDouble(); + var x4 = random.NextDouble(); + var y1 = random.NextDouble(); + var y2 = random.NextDouble(); + var y3 = random.NextDouble(); + var y4 = random.NextDouble(); + + var point1 = new Point2D(x1, y1); + var point2 = new Point2D(x2, y2); + var point3 = new Point2D(x3, y3); + var point4 = new Point2D(x4, y4); + var segment1 = new Segment2D(point1, point2); + var segment2 = new Segment2D(point3, point4); + + // Call & Assert + Assert.IsFalse(segment1.IsConnected(segment2)); + Assert.IsFalse(segment2.IsConnected(segment1)); + } + } +} \ No newline at end of file Index: Ringtoets/Piping/test/Ringtoets.Piping.Data.TestUtil/PointCollectionHelper.cs =================================================================== diff -u -r97c9e382dffcf32dc34d2e05e6a8a475b833ebd4 -r2da86d14cee084c7d6bfa52136d387cdcdb0a025 --- Ringtoets/Piping/test/Ringtoets.Piping.Data.TestUtil/PointCollectionHelper.cs (.../PointCollectionHelper.cs) (revision 97c9e382dffcf32dc34d2e05e6a8a475b833ebd4) +++ Ringtoets/Piping/test/Ringtoets.Piping.Data.TestUtil/PointCollectionHelper.cs (.../PointCollectionHelper.cs) (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using System.IO; +using System.Linq; using System.Text.RegularExpressions; namespace Ringtoets.Piping.Data.TestUtil @@ -11,25 +11,38 @@ /// public class PointCollectionHelper { - public static HashSet CreateFromString(string s) + public static List CreateFromString(string s) { - var points = new SortedDictionary(); + var points = new SortedDictionary(); var lines = s.Split(new [] { Environment.NewLine }, StringSplitOptions.None); var height = int.Parse(lines[0]); var lineIndex = 1; - for (int z = height - 1; z >= 0; z--, lineIndex++) + for (int y = height - 1; y >= 0; y--, lineIndex++) { foreach (var tuple in AllIndexesOfDigit(lines[lineIndex])) { - points.Add(tuple.Item1,new Point3D + points.Add(tuple.Item1,new Point2D { - X = tuple.Item2, Z = z + X = tuple.Item2, Y = y }); } } - return new HashSet(points.Values); + return CreateLoop(points); } + private static List CreateLoop(SortedDictionary points) + { + List loop = new List(points.Count); + var count = points.Values.Count; + for (int i = 0; i < count; i++) + { + var firstPoint = points.Values.ElementAt(i); + var secondPoint = points.Values.ElementAt((i+1)%count); + loop.Add(new Segment2D(firstPoint,secondPoint)); + } + return loop; + } + /// /// Returns a of if . /// The first item in the tuple contains the digit and the second item contains its index. Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Builders/SoilLayer2DTest.cs =================================================================== diff -u -r97c9e382dffcf32dc34d2e05e6a8a475b833ebd4 -r2da86d14cee084c7d6bfa52136d387cdcdb0a025 --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Builders/SoilLayer2DTest.cs (.../SoilLayer2DTest.cs) (revision 97c9e382dffcf32dc34d2e05e6a8a475b833ebd4) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Builders/SoilLayer2DTest.cs (.../SoilLayer2DTest.cs) (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -43,14 +43,33 @@ public void AsPipingSoilLayers_WithOuterLoopNotIntersectingX_ReturnsEmptyCollectionWithMaxValueBottom() { // Setup + var random = new Random(22); + var y1 = random.NextDouble(); + var y2 = random.NextDouble(); + var layer = new SoilLayer2D { - OuterLoop = new HashSet + OuterLoop = new List { - new Point3D - { - X = 0.1, Z = new Random(22).NextDouble() - } + new Segment2D( + new Point2D + { + X = 1.0, Y = y1 + }, + new Point2D + { + X = 1.2, Y = y2 + }), + + new Segment2D( + new Point2D + { + X = 1.2, Y = y2 + }, + new Point2D + { + X = 1.0, Y = y1 + }) } }; double bottom; @@ -70,16 +89,27 @@ var expectedZ = new Random(22).NextDouble(); var layer = new SoilLayer2D { - OuterLoop = new HashSet + OuterLoop = new List { - new Point3D - { - X = -0.1, Z = expectedZ - }, - new Point3D - { - X = 0.1, Z = expectedZ - } + new Segment2D( + new Point2D + { + X = -0.1, Y = expectedZ + }, + new Point2D + { + X = 0.1, Y = expectedZ + }), + + new Segment2D( + new Point2D + { + X = -0.1, Y = expectedZ + }, + new Point2D + { + X = 0.1, Y = expectedZ + }) } }; double bottom; @@ -146,11 +176,8 @@ var layer = new SoilLayer2D { OuterLoop = outerLoop, - InnerLoops = - { - innerLoop - } }; + layer.AddInnerLoop(innerLoop); // Call double bottom; @@ -187,11 +214,8 @@ var layer = new SoilLayer2D { OuterLoop = outerLoop, - InnerLoops = - { - innerLoop - } }; + layer.AddInnerLoop(innerLoop); // Call double bottom; @@ -237,12 +261,9 @@ var layer = new SoilLayer2D { OuterLoop = outerLoop, - InnerLoops = - { - innerLoop, - innerLoop2 - } }; + layer.AddInnerLoop(innerLoop); + layer.AddInnerLoop(innerLoop2); // Call double bottom; @@ -279,11 +300,8 @@ var layer = new SoilLayer2D { OuterLoop = outerLoop, - InnerLoops = - { - innerLoop - } }; + layer.AddInnerLoop(innerLoop); // Call double bottom; @@ -329,12 +347,9 @@ var layer = new SoilLayer2D { OuterLoop = outerLoop, - InnerLoops = - { - innerLoop, - innerLoop2 - } }; + layer.AddInnerLoop(innerLoop); + layer.AddInnerLoop(innerLoop2); // Call double bottom; @@ -371,11 +386,8 @@ var layer = new SoilLayer2D { OuterLoop = outerLoop, - InnerLoops = - { - innerLoop - } }; + layer.AddInnerLoop(innerLoop); // Call double bottom; @@ -412,11 +424,8 @@ var layer = new SoilLayer2D { OuterLoop = outerLoop, - InnerLoops = - { - innerLoop - } }; + layer.AddInnerLoop(innerLoop); // Call double bottom; @@ -453,11 +462,8 @@ var layer = new SoilLayer2D { OuterLoop = outerLoop, - InnerLoops = - { - innerLoop - } }; + layer.AddInnerLoop(innerLoop); // Call double bottom; @@ -523,11 +529,8 @@ var layer = new SoilLayer2D { OuterLoop = outerLoop, - InnerLoops = - { - innerLoop - } }; + layer.AddInnerLoop(innerLoop); // Call double bottom; Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Builders/SoilProfileBuilder2DTest.cs =================================================================== diff -u -r97c9e382dffcf32dc34d2e05e6a8a475b833ebd4 -r2da86d14cee084c7d6bfa52136d387cdcdb0a025 --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Builders/SoilProfileBuilder2DTest.cs (.../SoilProfileBuilder2DTest.cs) (revision 97c9e382dffcf32dc34d2e05e6a8a475b833ebd4) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Builders/SoilProfileBuilder2DTest.cs (.../SoilProfileBuilder2DTest.cs) (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -58,26 +58,30 @@ // Setup var profileName = "SomeProfile"; var builder = new SoilProfileBuilder2D(profileName, 0.0); + var firstPoint = new Point2D + { + X = -0.5, Y = 1.0 + }; + var secondPoint = new Point2D + { + X = 0.5, Y = 1.0 + }; + var thirdPoint = new Point2D + { + X = 0.5, Y = -1.0 + }; + var fourthPoint = new Point2D + { + X = -0.5, Y = -1.0 + }; builder.Add(new SoilLayer2D { - OuterLoop = new HashSet + OuterLoop = new List { - new Point3D - { - X = -0.5, Z = 1.0 - }, - new Point3D - { - X = 0.5, Z = 1.0 - }, - new Point3D - { - X = 0.5, Z = -1.0 - }, - new Point3D - { - X = -0.5, Z = -1.0 - } + new Segment2D(firstPoint,secondPoint), + new Segment2D(secondPoint,thirdPoint), + new Segment2D(thirdPoint,fourthPoint), + new Segment2D(fourthPoint,firstPoint) }, IsAquifer = 1.0 }); @@ -171,22 +175,20 @@ ".....", "....." )); - builder.Add(new SoilLayer2D + var soilLayer2D = new SoilLayer2D { OuterLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine, - "5", - "2...3", - ".....", - ".....", - ".....", - "1...4" - )), - InnerLoops = - { - loopHole - }, + "5", + "2...3", + ".....", + ".....", + ".....", + "1...4" + )), IsAquifer = 1.0 - }).Add(new SoilLayer2D + }; + soilLayer2D.AddInnerLoop(loopHole); + builder.Add(soilLayer2D).Add(new SoilLayer2D { OuterLoop = loopHole }); Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Calculation/Math2DTest.cs =================================================================== diff -u -r97c9e382dffcf32dc34d2e05e6a8a475b833ebd4 -r2da86d14cee084c7d6bfa52136d387cdcdb0a025 --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Calculation/Math2DTest.cs (.../Math2DTest.cs) (revision 97c9e382dffcf32dc34d2e05e6a8a475b833ebd4) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Calculation/Math2DTest.cs (.../Math2DTest.cs) (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -2,6 +2,7 @@ using System.Collections.ObjectModel; using System.Linq; using NUnit.Framework; +using Ringtoets.Piping.Data; using Ringtoets.Piping.IO.Calculation; namespace Ringtoets.Piping.IO.Test.Calculation @@ -15,225 +16,141 @@ /// which represent the coordinate of a point. Each pair of coordinates form a segment. /// The last 2 double values are the expected intersection points. /// - private static readonly double[][] IntersectingSegments = + private static readonly Point2D[][] IntersectingSegments = { // \/ // /\ - new[] + new [] { - 0.0,0.0, - 1.0,1.0, - 1.0,0.0, - 0.0,1.0, - 0.5,0.5 + new Point2D(0.0,0.0), + new Point2D(1.0,1.0), + new Point2D(1.0,0.0), + new Point2D(0.0,1.0), + new Point2D(0.5,0.5) }, // __ // / // / new[] { - 0.0,0.0, - 1.0,1.0, - 0.0,1.0, - 1.0,1.0, - 1.0,1.0 + new Point2D(0.0,0.0), + new Point2D(1.0,1.0), + new Point2D(0.0,1.0), + new Point2D(1.0,1.0), + new Point2D(1.0,1.0) }, // // / // /__ new[] { - 0.0,0.0, - 1.0,0.0, - 0.0,0.0, - 1.0,1.0, - 0.0,0.0 + new Point2D(0.0,0.0), + new Point2D(1.0,0.0), + new Point2D(0.0,0.0), + new Point2D(1.0,1.0), + new Point2D(0.0,0.0) } }; /// /// Test cases for parallel segments. The contains pairs of , /// which represent the coordinate of a point. Each pair of coordinates form a segment. /// - private static readonly double[][] ParallelSegments = + private static readonly Point2D[][] ParallelSegments = { // __ // __ new[] { - 0.0,0.0, - 1.0,0.0, - 0.0,1.0, - 1.0,1.0 + new Point2D(0.0,0.0), + new Point2D(1.0,0.0), + new Point2D(0.0,1.0), + new Point2D(1.0,1.0) }, // ____ (connected in single point) new[] { - 0.0,0.0, - 1.0,0.0, - 1.0,0.0, - 2.0,0.0 + new Point2D(0.0,0.0), + new Point2D(1.0,0.0), + new Point2D(1.0,0.0), + new Point2D(2.0,0.0) }, // __ (overlap) new[] { - 0.0,0.0, - 1.0,0.0, - 0.5,0.0, - 1.5,0.0 + new Point2D(0.0,0.0), + new Point2D(1.0,0.0), + new Point2D(0.5,0.0), + new Point2D(1.5,0.0) } }; /// /// Test cases for non intersecting segments. The contains pairs of , /// which represent the coordinate of a point. Each pair of coordinates form a segment. /// - private static readonly double[][] NonIntersectingSegments = + private static readonly Point2D[][] NonIntersectingSegments = { // | // ___ new[] { - 0.0, - 0.0, - 1.0, - 0.0, - 0.5, - 1.0, - 0.5, - 0.5 + new Point2D(0.0,0.0), + new Point2D(1.0,0.0), + new Point2D(0.5,1.0), + new Point2D(0.5,0.5), + new Point2D(0.5,0.0) } }; #endregion [Test] [TestCaseSource("IntersectingSegments")] - public void LineSegmentIntersectionWithLineSegment_DifferentLineSegmentsWithIntersections_ReturnsPoint(double[] coordinates) + public void LineIntersectionWithLine_DifferentLineSegmentsWithIntersections_ReturnsPoint(Point2D[] points) { - // Setup - var segments = ToSegmentCoordinatesCollections(coordinates); - // Call - var result = Math2D.LineSegmentIntersectionWithLineSegment(segments[0], segments[1]); + var result = Math2D.LineIntersectionWithLine(points[0], points[1], points[2], points[3]); // Assert - CollectionAssert.AreEqual(new[] - { - coordinates[8], - coordinates[9] - }, result); + Assert.AreEqual(points[4], result); } [Test] [TestCaseSource("ParallelSegments")] - public void LineSegmentIntersectionWithLineSegment_DifferentParallelLineSegments_ReturnsNoPoint(double[] coordinates) + public void LineIntersectionWithLine_DifferentParallelLineSegments_ReturnsNoPoint(Point2D[] points) { - // Setup - var segments = ToSegmentCoordinatesCollections(coordinates); - // Call - var result = Math2D.LineSegmentIntersectionWithLineSegment(segments[0], segments[1]); + var result = Math2D.LineIntersectionWithLine(points[0], points[1], points[2], points[3]); // Assert - Assert.AreEqual(0, result.Length); + Assert.IsNull(result); } [Test] [TestCaseSource("NonIntersectingSegments")] - public void LineSegmentIntersectionWithLineSegment_DifferentLineSegmentsWithNoIntersection_ReturnsNoPoint(double[] coordinates) + public void LineIntersectionWithLine_DifferentLineSegmentsWithNoIntersection_ReturnsPoint(Point2D[] points) { - // Setup - var segments = ToSegmentCoordinatesCollections(coordinates); - // Call - var result = Math2D.LineSegmentIntersectionWithLineSegment(segments[0], segments[1]); + var result = Math2D.LineIntersectionWithLine(points[0], points[1], points[2], points[3]); // Assert - Assert.AreEqual(0, result.Length); + Assert.AreEqual(points[4], result); } [Test] - [TestCase(3,2)] - [TestCase(2,3)] - [TestCase(3,3)] - [TestCase(1,1)] - [TestCase(1,2)] - [TestCase(2,1)] - public void LineSegmentIntersectionWithLineSegment_IncorrectLengthOfParameters_ThrowsArgumentException(int xLength, int yLength) + public void LineIntersectionWithLine_InterSectionsHigherUpX_ReturnsIntersectionWithTolerance() { // Setup - Collection xCollection = new Collection(); - Collection yCollection = new Collection(); - var random = new Random(22); - for (var i = 0; i < xLength; i++) - { - xCollection.Add(random.NextDouble()); - } - for (var i = 0; i < yLength; i++) - { - yCollection.Add(random.NextDouble()); - } + var y1 = 5.925; + var y2 = 5.890; + var start = 133; // Call - TestDelegate test = () => Math2D.LineSegmentIntersectionWithLineSegment(xCollection.ToArray(), yCollection.ToArray()); - - // Assert - var message = Assert.Throws(test); - Assert.AreEqual(message.Message, "Collecties van de x en y coordinaten van lijnen vereisen een lengte van 4."); - } + var result = Math2D.LineIntersectionWithLine(new Point2D(start, y1), new Point2D(start + 1, y2), new Point2D(start + 0.5, 0), new Point2D(start + 0.5, 1)); - [Test] - [TestCase(3, 2)] - [TestCase(2, 3)] - [TestCase(3, 3)] - [TestCase(1, 1)] - [TestCase(1, 2)] - [TestCase(2, 1)] - public void LineSegmentIntersectionWithLine_IncorrectLengthOfParameters_ThrowsArgumentException(int xLength, int yLength) - { - // Setup - Collection xCollection = new Collection(); - Collection yCollection = new Collection(); - var random = new Random(22); - for (var i = 0; i < xLength; i++) - { - xCollection.Add(random.NextDouble()); - } - for (var i = 0; i < yLength; i++) - { - yCollection.Add(random.NextDouble()); - } - - // Call - TestDelegate test = () => Math2D.LineSegmentIntersectionWithLine(xCollection.ToArray(), yCollection.ToArray()); - // Assert - var message = Assert.Throws(test); - Assert.AreEqual(message.Message, "Collecties van de x en y coordinaten van lijnen vereisen een lengte van 4."); + Assert.AreEqual((y1+y2)/2, result.Y, 1e-8); } - - private double[][] ToSegmentCoordinatesCollections(double[] coordinates) - { - double[] segmentX = - { - coordinates[0], - coordinates[2], - coordinates[4], - coordinates[6] - }; - double[] segmentY = - { - coordinates[1], - coordinates[3], - coordinates[5], - coordinates[7] - }; - return new[] - { - segmentX, - segmentY - }; - } } } \ No newline at end of file Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSoilLayer2DReaderTest.cs =================================================================== diff -u --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSoilLayer2DReaderTest.cs (revision 0) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSoilLayer2DReaderTest.cs (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -0,0 +1,258 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Globalization; +using System.Linq; +using System.Xml; +using NUnit.Framework; + +using Ringtoets.Piping.Data; + +namespace Ringtoets.Piping.IO.Test +{ + public class PipingSoilLayer2DReaderTest + { + [Test] + [TestCase(0)] + [TestCase(1)] + public void Constructor_AnyByteArray_ReturnsNewInstance(int size) + { + // Call + var result = new PipingSoilLayer2DReader(new byte[size]); + + // Assert + Assert.NotNull(result); + } + + [Test] + public void Read_MalformedXmlDocument_ThrowsXmlException() + { + // Setup + var xmlDoc = GetBytes("test"); + var reader = new PipingSoilLayer2DReader(xmlDoc); + + // Call + TestDelegate test = () => reader.Read(); + + // Assert + Assert.Throws(test); + } + + [Test] + public void Read_XmlDocumentWithoutSaneContent_ReturnsLayerWithoutOuterLoopAndEmptyInnerLoops() + { + // Setup + var xmlDoc = GetBytes(""); + var reader = new PipingSoilLayer2DReader(xmlDoc); + + // Call + var result = reader.Read(); + + // Assert + Assert.NotNull(result); + Assert.IsNull(result.OuterLoop); + CollectionAssert.IsEmpty(result.InnerLoops); + } + + [Test] + public void Read_XmlDocumentWithEmptyOuterLoop_ReturnsLayerWithEmptyOuterLoop() + { + // Setup + var xmlDoc = GetBytes(""); + var reader = new PipingSoilLayer2DReader(xmlDoc); + + // Call + var result = reader.Read(); + + // Assert + Assert.NotNull(result); + CollectionAssert.IsEmpty(result.OuterLoop); + CollectionAssert.IsEmpty(result.InnerLoops); + } + + [Test] + public void Read_XmlDocumentWithEmptyInnerLoop_ReturnsLayerWithOneEmptyInnerLoop() + { + // Setup + var xmlDoc = GetBytes(""); + var reader = new PipingSoilLayer2DReader(xmlDoc); + + // Call + var result = reader.Read(); + + // Assert + Assert.NotNull(result); + Assert.IsNull(result.OuterLoop); + Assert.AreEqual(1, result.InnerLoops.Count()); + CollectionAssert.IsEmpty(result.InnerLoops.ElementAt(0)); + } + + [Test] + public void Read_XmlDocumentWithEmptyInnerLoopAndOuterLoop_ReturnsLayerWithEmptyInnerLoopAndEmptyOuterLoop() + { + // Setup + var xmlDoc = GetBytes(""); + var reader = new PipingSoilLayer2DReader(xmlDoc); + + // Call + var result = reader.Read(); + + // Assert + Assert.NotNull(result); + CollectionAssert.IsEmpty(result.OuterLoop); + Assert.AreEqual(1, result.InnerLoops.Count()); + CollectionAssert.IsEmpty(result.InnerLoops.ElementAt(0)); + } + + [Test] + [SetCulture("nl-NL")] + public void Read_NLXmlDocumentPointInOuterLoop_ReturnsLayerWithOuterLoopWithPoint() + { + Read_XmlDocumentPointInOuterLoop_ReturnsLayerWithOuterLoopWithPoint(); + } + + [Test] + [SetCulture("en-US")] + public void Read_ENXmlDocumentPointInOuterLoop_ReturnsLayerWithOuterLoopWithPoint() + { + Read_XmlDocumentPointInOuterLoop_ReturnsLayerWithOuterLoopWithPoint(); + } + + private void Read_XmlDocumentPointInOuterLoop_ReturnsLayerWithOuterLoopWithPoint() + { + // Setup + var random = new Random(22); + var invariantCulture = CultureInfo.InvariantCulture; + + var x1 = random.NextDouble(); + var x2 = random.NextDouble(); + var y1 = random.NextDouble(); + var y2 = random.NextDouble(); + + var x1String = x1.ToString(invariantCulture); + var x2String = x2.ToString(invariantCulture); + var y1String = y1.ToString(invariantCulture); + var y2String = y2.ToString(invariantCulture); + var parsedX1 = double.Parse(x1String, invariantCulture); + var parsedX2 = double.Parse(x2String, invariantCulture); + var parsedY1 = double.Parse(y1String, invariantCulture); + var parsedY2 = double.Parse(y2String, invariantCulture); + var sometempvarforbassie = string.Format(invariantCulture, "" + + "{0}0.1{1}" + + "{2}0.1{3}" + + "" + + "{0}0.1{1}" + + "{2}0.1{3}" + + "", + x1String, y1String, x2String, y2String); + var bytes = GetBytes(sometempvarforbassie); + var xmlDoc = bytes; + var reader = new PipingSoilLayer2DReader(xmlDoc); + + // Call + var result = reader.Read(); + + // Assert + Assert.NotNull(result); + Segment2D expectedSegment = new Segment2D(new Point2D(parsedX1, parsedY1), new Point2D(parsedX2, parsedY2)); + CollectionAssert.AreEqual(new List {expectedSegment, expectedSegment}, result.OuterLoop); + } + + [Test] + public void Read_XmlDocumentPointsInInnerLoop_ReturnsLayerWithInnerLoopWithSegment() + { + // Setup + var random = new Random(22); + var invariantCulture = CultureInfo.InvariantCulture; + + var x1 = random.NextDouble(); + var x2 = random.NextDouble(); + var y1 = random.NextDouble(); + var y2 = random.NextDouble(); + + var x1String = x1.ToString(invariantCulture); + var x2String = x2.ToString(invariantCulture); + var y1String = y1.ToString(invariantCulture); + var y2String = y2.ToString(invariantCulture); + var parsedX1 = double.Parse(x1String, invariantCulture); + var parsedX2 = double.Parse(x2String, invariantCulture); + var parsedY1 = double.Parse(y1String, invariantCulture); + var parsedY2 = double.Parse(y2String, invariantCulture); + var xmlDoc = GetBytes(string.Format(invariantCulture, "" + + "{0}0.1{1}" + + "{2}0.1{3}" + + "" + + "{0}0.1{1}" + + "{2}0.1{3}" + + "", x1String, y1String, x2String, y2String)); + var reader = new PipingSoilLayer2DReader(xmlDoc); + + // Call + var result = reader.Read(); + + // Assert + Assert.NotNull(result); + Segment2D expectedSegment = new Segment2D(new Point2D(parsedX1, parsedY1), new Point2D(parsedX2, parsedY2)); + var expectedCollection = new Collection> { new List { expectedSegment, expectedSegment } }; + CollectionAssert.AreEqual(expectedCollection, result.InnerLoops); + } + + [Test] + public void Read_XmlDocumentSinglePointOuterLoopGeometryCurve_ThrowsXmlException() + { + // Setup + var xmlDoc = GetBytes("10.11.1"); + var reader = new PipingSoilLayer2DReader(xmlDoc); + + // Call + TestDelegate test = () => { reader.Read(); }; + + // Assert + Assert.Throws(test); + } + + [Test] + public void Read_XmlDocumentSinglePointInnerLoopGeometryCurve_ThrowsXmlException() + { + // Setup + var xmlDoc = GetBytes("00.11.1"); + var reader = new PipingSoilLayer2DReader(xmlDoc); + + // Call + TestDelegate test = () => { reader.Read(); }; + + // Assert + Assert.Throws(test); + } + + [Test] + public void Read_XmlDocumentEqualSegments_ReturnsTwoEqualSegments() + { + // Setup + var xmlDoc = GetBytes("" + + "" + + "001.1101.1" + + "" + + "" + + "001.1101.1" + + "" + + ""); + + var reader = new PipingSoilLayer2DReader(xmlDoc); + + // Call + var result = reader.Read(); + + // Assert + Assert.AreEqual(2, result.OuterLoop.Count); + Assert.AreEqual(result.OuterLoop[0], result.OuterLoop[1]); + } + + static byte[] GetBytes(string str) + { + byte[] bytes = new byte[str.Length * sizeof(char)]; + Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length); + return bytes; + } + } +} \ No newline at end of file Fisheye: Tag 2da86d14cee084c7d6bfa52136d387cdcdb0a025 refers to a dead (removed) revision in file `Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSoilLayerReaderTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSoilProfileReaderTest.cs =================================================================== diff -u -r97c9e382dffcf32dc34d2e05e6a8a475b833ebd4 -r2da86d14cee084c7d6bfa52136d387cdcdb0a025 --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSoilProfileReaderTest.cs (.../PipingSoilProfileReaderTest.cs) (revision 97c9e382dffcf32dc34d2e05e6a8a475b833ebd4) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSoilProfileReaderTest.cs (.../PipingSoilProfileReaderTest.cs) (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -1,10 +1,12 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; using Core.Common.TestUtils; using NUnit.Framework; +using NUnit.Framework.Constraints; using Ringtoets.Piping.Data; using Ringtoets.Piping.IO.Exceptions; using Ringtoets.Piping.IO.Properties; @@ -364,7 +366,6 @@ CollectionAssert.AreEqual(new[] { - -39.999943172545208, -45, -45, -45, @@ -382,6 +383,7 @@ -45, -45, -45, + -45, -52, -52, -52, @@ -395,8 +397,8 @@ CollectionAssert.AreEqual(new[] { 9, + 7, 8, - 8, 3, 6, 6, @@ -426,25 +428,24 @@ Assert.NotNull(firstProfile); var expectedFirstProfileLayersTops = new[] { - 5.9075002357930027, - 3.12499857931363, - 2.3749957379408912, - 1.1874992896568151, - 0.12499005519541202, - -5.1250298344137661, - -14.000011365490959, - -19.000022730981915, - -30.000056827454785, + 5.9075, + 3.250, + 2.750, + 1.250, + 1.0, + -2.5, + -13, + -17, + -25, }; CollectionAssert.AllItemsAreUnique(firstProfile.Layers.Select(l => l.Top)); - CollectionAssert.AreEqual(expectedFirstProfileLayersTops, firstProfile.Layers.Select(l => l.Top)); + CollectionAssert.AreEqual(expectedFirstProfileLayersTops, firstProfile.Layers.Select(l => l.Top), new DoubleWithToleranceComparer(1e-6)); var secondProfile = result.FirstOrDefault(l => l.Name == "AD640M00_Segment_36005_1D2"); Assert.NotNull(secondProfile); var expectedSecondProfileLayersTops = new[] { - 5.9075002357930053, - 4.3475186908270276, + 5.9075, 3.25, -0.5, -0.75, @@ -453,8 +454,38 @@ -25, }; CollectionAssert.AllItemsAreUnique(secondProfile.Layers.Select(l => l.Top)); - CollectionAssert.AreEqual(expectedSecondProfileLayersTops, secondProfile.Layers.Select(l => l.Top)); + CollectionAssert.AreEqual(expectedSecondProfileLayersTops, secondProfile.Layers.Select(l => l.Top), new DoubleWithToleranceComparer(1e-6)); } } } + + internal class DoubleWithToleranceComparer : IComparer + { + private double tolerance; + + public DoubleWithToleranceComparer(double tolerance) + { + this.tolerance = tolerance; + } + + public int Compare(double firstDouble, double secondDouble) + { + var diff = firstDouble - secondDouble; + + var tolerable = Math.Abs(diff) < tolerance; + + var nonTolerableDiff = !tolerable && diff < 0 ? -1 : 1; + + return tolerable ? 0 : nonTolerableDiff; + } + + public int Compare(object x, object y) + { + if (!(x is double) || !(y is double)) + { + throw new NotSupportedException(string.Format("Cannot compare objects other than {0} with this comparer.", typeof(Point2D))); + } + return Compare((double)x, (double)y); + } + } } \ No newline at end of file Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Ringtoets.Piping.IO.Test.csproj =================================================================== diff -u -r5462a7ee52b9491f269d489a094d359f4f02f270 -r2da86d14cee084c7d6bfa52136d387cdcdb0a025 --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Ringtoets.Piping.IO.Test.csproj (.../Ringtoets.Piping.IO.Test.csproj) (revision 5462a7ee52b9491f269d489a094d359f4f02f270) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Ringtoets.Piping.IO.Test.csproj (.../Ringtoets.Piping.IO.Test.csproj) (revision 2da86d14cee084c7d6bfa52136d387cdcdb0a025) @@ -53,7 +53,7 @@ - +