Index: DeltaShell.sln
===================================================================
diff -u -r1450c6e12cbd3358c66a9efec22203c988af78ed -rb3fa1606efddd3bed496c2844a495ff92347fa44
--- DeltaShell.sln (.../DeltaShell.sln) (revision 1450c6e12cbd3358c66a9efec22203c988af78ed)
+++ DeltaShell.sln (.../DeltaShell.sln) (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -126,7 +126,7 @@
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wti.Data", "src\Plugins\Ringtoets\Piping\src\Ringtoets.Piping.Data\Wti.Data.csproj", "{CE994CC9-6F6A-48AC-B4BE-02C30A21F4DB}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wti.IO", "src\Plugins\Wti\Wti.IO\Wti.IO.csproj", "{35B87B7A-7F50-4139-B563-589EE522B1ED}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wti.IO", "src\Plugins\Ringtoets\Piping\src\Ringtoets.Piping.IO\Wti.IO.csproj", "{35B87B7A-7F50-4139-B563-589EE522B1ED}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wti.Forms", "src\Plugins\Ringtoets\Piping\src\Ringtoets.Piping.Forms\Wti.Forms.csproj", "{7CD038E1-E111-4969-ACED-22C5BD2974E1}"
EndProject
@@ -140,7 +140,7 @@
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wti.Forms.Test", "src\Plugins\Ringtoets\Piping\test\Ringtoets.Piping.Forms.Test\Wti.Forms.Test.csproj", "{622A8282-D872-4DD5-8B70-578A403F74FF}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wti.IO.Test", "test\Plugins\Wti\Wti.IO.Test\Wti.IO.Test.csproj", "{E4B0E068-F1A3-47BA-965F-0EC1E78E530A}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wti.IO.Test", "src\Plugins\Ringtoets\Piping\test\Ringtoets.Piping.IO.Test\Wti.IO.Test.csproj", "{E4B0E068-F1A3-47BA-965F-0EC1E78E530A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ringtoets.Piping.Plugin.Test", "src\Plugins\Ringtoets\Piping\test\Ringtoets.Piping.Plugin.Test\Ringtoets.Piping.Plugin.Test.csproj", "{9A5C8069-520E-49D3-AA62-E8FB19614A27}"
EndProject
@@ -520,23 +520,23 @@
{07206938-9671-4DC7-BDE4-35B0F6E20DBC} = {A300D2BD-2E91-4EA7-A421-646EE7B5118B}
{4FDA4BD2-2C84-4C7C-9908-818884D52DBB} = {A300D2BD-2E91-4EA7-A421-646EE7B5118B}
{E0990383-FB2E-47D1-99CD-9B9FA2929E5B} = {A300D2BD-2E91-4EA7-A421-646EE7B5118B}
- {35B87B7A-7F50-4139-B563-589EE522B1ED} = {C9DA93BC-1034-4D15-AD4E-773E3F560179}
{F3A82DA4-A377-4009-A424-EFC8839913ED} = {5A029776-37C6-4622-A4E9-9DB9E8E935AB}
{0FA77E45-C347-4677-9DA0-4C330D1440D5} = {F3A82DA4-A377-4009-A424-EFC8839913ED}
{C2EEB390-385B-4471-ABB8-9C1F1A8D0C11} = {F3A82DA4-A377-4009-A424-EFC8839913ED}
+ {1D3D58B6-EF7E-401E-92A0-104067D222EE} = {0FA77E45-C347-4677-9DA0-4C330D1440D5}
{10B8D63D-87E8-46DF-ACA9-A8CF22EE8FB5} = {0FA77E45-C347-4677-9DA0-4C330D1440D5}
{CE994CC9-6F6A-48AC-B4BE-02C30A21F4DB} = {0FA77E45-C347-4677-9DA0-4C330D1440D5}
- {D64E4F0E-E341-496F-82B2-941AD202B4E3} = {0FA77E45-C347-4677-9DA0-4C330D1440D5}
- {1D3D58B6-EF7E-401E-92A0-104067D222EE} = {0FA77E45-C347-4677-9DA0-4C330D1440D5}
{7CD038E1-E111-4969-ACED-22C5BD2974E1} = {0FA77E45-C347-4677-9DA0-4C330D1440D5}
- {E4B0E068-F1A3-47BA-965F-0EC1E78E530A} = {BC862348-6B4E-49EA-9099-2E5BE6DC183A}
+ {D64E4F0E-E341-496F-82B2-941AD202B4E3} = {0FA77E45-C347-4677-9DA0-4C330D1440D5}
+ {35B87B7A-7F50-4139-B563-589EE522B1ED} = {0FA77E45-C347-4677-9DA0-4C330D1440D5}
+ {622A8282-D872-4DD5-8B70-578A403F74FF} = {C2EEB390-385B-4471-ABB8-9C1F1A8D0C11}
{9A5C8069-520E-49D3-AA62-E8FB19614A27} = {C2EEB390-385B-4471-ABB8-9C1F1A8D0C11}
{19EB1C52-D90B-40F2-A7AF-364CC5D89F68} = {C2EEB390-385B-4471-ABB8-9C1F1A8D0C11}
{D783543B-46A1-4848-A812-AF5A5259ED7E} = {C2EEB390-385B-4471-ABB8-9C1F1A8D0C11}
{27E0A5C9-3ABF-426A-A3DA-7D0B83A218C8} = {C2EEB390-385B-4471-ABB8-9C1F1A8D0C11}
{955E574D-67CE-4347-AA6B-7DF8A04ED754} = {C2EEB390-385B-4471-ABB8-9C1F1A8D0C11}
{91389DA2-3FF4-4559-90B3-4061549789DD} = {C2EEB390-385B-4471-ABB8-9C1F1A8D0C11}
- {622A8282-D872-4DD5-8B70-578A403F74FF} = {C2EEB390-385B-4471-ABB8-9C1F1A8D0C11}
+ {E4B0E068-F1A3-47BA-965F-0EC1E78E530A} = {C2EEB390-385B-4471-ABB8-9C1F1A8D0C11}
{3CCB05DB-C7B3-4EF7-B41D-22B6D2A3774E} = {C4E268AD-A25B-4F47-8F92-E5137FDF7CC7}
{4AD99020-8612-46E5-A313-F9ADA7B196E4} = {0D2E4E16-EE0A-4E50-9218-947B1D91C84D}
EndGlobalSection
Index: packages/repositories.config
===================================================================
diff -u -rd80c8343ac1824759a0c42c3347c3900b67004b1 -rb3fa1606efddd3bed496c2844a495ff92347fa44
--- packages/repositories.config (.../repositories.config) (revision d80c8343ac1824759a0c42c3347c3900b67004b1)
+++ packages/repositories.config (.../repositories.config) (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -15,8 +15,8 @@
+
-
Index: src/DeltaShell/DeltaShell.Gui/DeltaShell.Gui.csproj
===================================================================
diff -u -r53a2d662c6893cb7e63dc150aaab6c2b3e9db769 -rb3fa1606efddd3bed496c2844a495ff92347fa44
--- src/DeltaShell/DeltaShell.Gui/DeltaShell.Gui.csproj (.../DeltaShell.Gui.csproj) (revision 53a2d662c6893cb7e63dc150aaab6c2b3e9db769)
+++ src/DeltaShell/DeltaShell.Gui/DeltaShell.Gui.csproj (.../DeltaShell.Gui.csproj) (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -304,7 +304,7 @@
{ce994cc9-6f6a-48ac-b4be-02c30a21f4db}
Wti.Data
-
+
{7cd038e1-e111-4969-aced-22c5bd2974e1}
Wti.Forms
Index: src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilLayer2D.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilLayer2D.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilLayer2D.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,174 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using Wti.Data;
+using Wti.IO.Calculation;
+using Wti.IO.Properties;
+
+namespace Wti.IO.Builders
+{
+ ///
+ /// This class represents objects which were imported from a DSoilModel database. This class
+ ///
+ internal class SoilLayer2D
+ {
+ ///
+ /// Creates a new instance of .
+ ///
+ public SoilLayer2D()
+ {
+ InnerLoops = new Collection>();
+ }
+
+ ///
+ /// Gets the outer loop of the as a of .
+ ///
+ internal HashSet OuterLoop { get; set; }
+
+ ///
+ /// Gets the of inner loops (as of ) of the .
+ ///
+ internal Collection> InnerLoops { get; private set; }
+
+ ///
+ /// Constructs a (1D) based on the and set for the .
+ ///
+ /// The point from which to take a 1D profile.
+ /// The bottom level of the .
+ ///
+ internal IEnumerable AsPipingSoilLayers(double atX, out double bottom)
+ {
+ bottom = Double.MaxValue;
+ var result = new Collection();
+ if (OuterLoop != null)
+ {
+ Collection outerLoopIntersectionHeights = GetLoopIntersectionHeights(OuterLoop, atX);
+
+ if (outerLoopIntersectionHeights.Count > 0)
+ {
+ IEnumerable> innerLoopsIntersectionHeights = InnerLoops.Select(loop => GetLoopIntersectionHeights(loop, atX));
+ IEnumerable> innerLoopIntersectionHeightPairs = GetOrderedStartAndEndPairsIn1D(innerLoopsIntersectionHeights).ToList();
+ IEnumerable> outerLoopIntersectionHeightPairs = GetOrderedStartAndEndPairsIn1D(outerLoopIntersectionHeights).ToList();
+
+ var currentBottom = outerLoopIntersectionHeightPairs.First().Item1;
+ var heights = new List();
+ heights.AddRange(innerLoopIntersectionHeightPairs.Where(p => p.Item1 >= currentBottom).Select(p => p.Item1));
+ heights.AddRange(outerLoopIntersectionHeightPairs.Select(p => p.Item2));
+
+ foreach (var height in heights.Where(height => !innerLoopIntersectionHeightPairs.Any(tuple => HeightInInnerLoop(tuple, height))))
+ {
+ result.Add(new PipingSoilLayer(height));
+ }
+ bottom = EnsureBottomOutsideInnerLoop(innerLoopIntersectionHeightPairs, currentBottom);
+ }
+ }
+ return result;
+ }
+
+ private double EnsureBottomOutsideInnerLoop(IEnumerable> innerLoopIntersectionHeightPairs, double bottom)
+ {
+ var newBottom = bottom;
+ var heigthPairArray = innerLoopIntersectionHeightPairs.ToList();
+ var overlappingInnerLoop = heigthPairArray.FirstOrDefault(t => BottomInInnerLoop(t, newBottom));
+
+ while (overlappingInnerLoop != null)
+ {
+ newBottom = overlappingInnerLoop.Item2;
+ overlappingInnerLoop = heigthPairArray.FirstOrDefault(t => BottomInInnerLoop(t, newBottom));
+ }
+ return newBottom;
+ }
+
+ private bool HeightInInnerLoop(Tuple tuple, double height)
+ {
+ return height <= tuple.Item2 && height > tuple.Item1;
+ }
+
+ private bool BottomInInnerLoop(Tuple tuple, double height)
+ {
+ return height < tuple.Item2 && height >= tuple.Item1;
+ }
+
+ private IEnumerable> GetOrderedStartAndEndPairsIn1D(IEnumerable> innerLoopsIntersectionPoints)
+ {
+ Collection> result = new Collection>();
+ foreach (var innerLoopIntersectionPoints in innerLoopsIntersectionPoints)
+ {
+ foreach (var tuple in GetOrderedStartAndEndPairsIn1D(innerLoopIntersectionPoints))
+ {
+ result.Add(tuple);
+ }
+ }
+ return result;
+ }
+
+ private static Collection> GetOrderedStartAndEndPairsIn1D(IEnumerable innerLoopIntersectionPoints)
+ {
+ var result = new Collection>();
+ var orderedHeights = innerLoopIntersectionPoints.OrderBy(v => v).ToList();
+ for (int i = 0; i < orderedHeights.Count; i = i+2)
+ {
+ var first = orderedHeights[i];
+ var second = orderedHeights[i+1];
+ result.Add(new Tuple(first, second));
+ }
+ return result;
+ }
+
+ private Collection GetLoopIntersectionHeights(HashSet loop, double atX)
+ {
+ Collection intersectionPointY = new Collection(); ;
+ for (int segmentIndex = 0; segmentIndex < loop.Count; segmentIndex++)
+ {
+ var intersectionPoint = GetSegmentIntersectionAtX(loop, segmentIndex, atX);
+
+ if (intersectionPoint.Length > 0)
+ {
+ intersectionPointY.Add(intersectionPoint[1]);
+ }
+ else if (IsVerticalAtX(GetSegmentWithStartAtIndex(loop, segmentIndex), atX))
+ {
+ throw new SoilLayer2DConversionException(String.Format(Resources.Error_CanNotDetermine1DProfileWithVerticalSegmentsAtX, atX));
+ }
+ }
+ return intersectionPointY;
+ }
+
+ private bool IsVerticalAtX(Point3D[] segment, double atX)
+ {
+ 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[]
+ {
+ current,
+ next
+ };
+ }
+
+ private static double[] GetSegmentIntersectionAtX(HashSet loop, int segmentIndex, double atX)
+ {
+ Point3D[] segment = GetSegmentWithStartAtIndex(loop, segmentIndex);
+
+ return Math2D.LineSegmentIntersectionWithLine(new[]
+ {
+ segment[0].X,
+ segment[1].X,
+ atX,
+ atX
+ }, new[]
+ {
+ segment[0].Z,
+ segment[1].Z,
+ 0,
+ 1
+ });
+ }
+ }
+}
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilLayer2DConversionException.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilLayer2DConversionException.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilLayer2DConversionException.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,37 @@
+using System;
+using Wti.Data;
+
+namespace Wti.IO.Builders
+{
+ ///
+ /// Exception thrown when something went wrong while converting to .
+ ///
+ public class SoilLayer2DConversionException : Exception
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public SoilLayer2DConversionException()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ /// with a specified error message.
+ ///
+ /// The message that describes the error.
+ public SoilLayer2DConversionException(string message)
+ : base(message)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class with a specified error message
+ /// and a reference to the inner exception that is the cause of this exception.
+ ///
+ /// The error message that explains the reason for the exception.
+ /// The exception that is the cause of the current exception, or a
+ /// null reference if no inner exception is specified.
+ public SoilLayer2DConversionException(string message, Exception innerException) : base(message, innerException) { }
+ }
+}
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilProfileBuilder.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilProfileBuilder.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilProfileBuilder.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using Wti.Data;
+using Wti.IO.Properties;
+
+namespace Wti.IO.Builders
+{
+ ///
+ /// Constructs a 1d Soil Profile based on definitions of .
+ ///
+ internal class SoilProfileBuilder
+ {
+ private readonly ICollection layers = new Collection();
+
+ ///
+ /// Creates a new instance of with the supposed name for the new
+ /// and the point at which a 1D profile should be obtained from the 2D profile.
+ ///
+ /// The name for the constructed by the .
+ /// The x position from which to obtain a 1D profile.
+ internal SoilProfileBuilder(string profileName, double atX)
+ {
+ if (double.IsNaN(atX))
+ {
+ throw new ArgumentException(Resources.Error_SoilProfileBuilderCantDetermineIntersectAtDoubleNaN);
+ }
+ ProfileName = profileName;
+ AtX = atX;
+ Bottom = double.MaxValue;
+ }
+
+ ///
+ /// Adds a new to the profile.
+ ///
+ /// The to add to the profile.
+ /// The .
+ internal SoilProfileBuilder Add(SoilLayer2D soilLayer)
+ {
+ double bottom;
+ foreach (PipingSoilLayer layer in soilLayer.AsPipingSoilLayers(AtX, out bottom))
+ {
+ layers.Add(layer);
+ }
+ Bottom = Math.Min(Bottom, bottom);
+ return this;
+ }
+
+ ///
+ /// Creates a new instance of .
+ ///
+ /// A new .
+ internal PipingSoilProfile Build()
+ {
+ return new PipingSoilProfile(ProfileName, Bottom, layers);
+ }
+
+ private double Bottom { get; set; }
+
+ private double AtX { get; set; }
+
+ private string ProfileName { get; set; }
+ }
+}
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Calculation/Math2D.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Calculation/Math2D.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Calculation/Math2D.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,138 @@
+using System;
+
+namespace Wti.IO.Calculation
+{
+ ///
+ /// This class contains general mathematical routines for 2D lines.
+ ///
+ public static class Math2D
+ {
+ ///
+ /// Constant which is used to precision errors in comparisons.
+ ///
+ 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 .
+ ///
+ public static double[] LineSegmentIntersectionWithLineSegment(double[] segmentsX, double[] segmentsY)
+ {
+ var numberOfPoints = 4;
+ if (segmentsX.Length != numberOfPoints || segmentsY.Length != numberOfPoints)
+ {
+ throw new ArgumentException(String.Format("Collections of segments' x and y coordinates need to have length of {0}.", numberOfPoints));
+ }
+ 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 .
+ ///
+ 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/ .
+ private static double[] LineIntersectionWithLine(double[] linesX, double[] linesY)
+ {
+ var numberOfPoints = 4;
+ if (linesX.Length != numberOfPoints || linesY.Length != numberOfPoints)
+ {
+ throw new ArgumentException(String.Format("Collections of lines' x and y coordinates need to have length of {0}", numberOfPoints));
+ }
+
+ var aLine = linesY[1] - linesY[0];
+ var bLine = linesX[0] - linesX[1];
+ var cLine = aLine * linesX[0] + bLine * linesY[0];
+
+ 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;
+ if (Math.Abs(determinant) < EpsilonForComparisons)
+ {
+ return new double[0];
+ }
+
+ return new[]
+ {
+ (bOtherLine*cLine - bLine*cOtherLine)/determinant,
+ (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)
+ {
+ var crossProduct = (y[2] - y[0])*(x[1] - x[0]) - (x[2] - x[0])*(y[1] - y[0]);
+ if (Math.Abs(crossProduct) > EpsilonForComparisons)
+ {
+ return false;
+ }
+
+ var dotProduct = (x[2] - x[0])*(x[1] - x[0]) + (y[2] - y[0])*(y[1] - y[0]);
+ if (dotProduct < 0)
+ {
+ return false;
+ }
+
+ var squaredLengthSegment = (x[1] - x[0])*(x[1] - x[0]) + (y[1] - y[0])*(y[1] - y[0]);
+ return dotProduct <= squaredLengthSegment;
+ }
+ }
+}
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Exceptions/CriticalFileReadException.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Exceptions/CriticalFileReadException.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Exceptions/CriticalFileReadException.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,32 @@
+using System;
+
+namespace Wti.IO.Exceptions
+{
+ ///
+ /// The exception that is thrown when a file reader class encounters a critical error
+ /// during the read.
+ ///
+ public class CriticalFileReadException : Exception
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public CriticalFileReadException(){}
+
+ ///
+ /// Initializes a new instance of the class
+ /// with a specified error message.
+ ///
+ /// The error message that explains the reason for the exception.
+ public CriticalFileReadException(string message) : base(message){}
+
+ ///
+ /// Initializes a new instance of the class
+ /// with a specified error message and a reference to the inner exception that is
+ /// the cause of this exception.
+ ///
+ /// The error message that explains the reason for the exception.
+ /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.
+ public CriticalFileReadException(string message, Exception inner) : base(message, inner) { }
+ }
+}
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Exceptions/LineParseException.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Exceptions/LineParseException.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Exceptions/LineParseException.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,33 @@
+using System;
+
+namespace Wti.IO.Exceptions
+{
+ ///
+ /// The exception that is thrown when a file reader class encounters an error while
+ /// parsing a row/line during the read.
+ ///
+ public class LineParseException : Exception
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public LineParseException() { }
+
+ ///
+ /// Initializes a new instance of the class
+ /// with a specified error message.
+ ///
+ /// The error message that explains the reason for the exception.
+ public LineParseException(string message) : base(message) { }
+
+ ///
+ /// Initializes a new instance of the class
+ /// with a specified error message and a reference to the inner exception that is
+ /// the cause of this exception.
+ ///
+ /// The error message that explains the reason for the exception.
+ /// The exception that is the cause of the current exception,
+ /// or a null reference (Nothing in Visual Basic) if no inner exception is specified.
+ public LineParseException(string message, Exception inner) : base(message, inner) { }
+ }
+}
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Exceptions/PipingSoilProfileReadException.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Exceptions/PipingSoilProfileReadException.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Exceptions/PipingSoilProfileReadException.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,37 @@
+using System;
+using Wti.Data;
+
+namespace Wti.IO.Exceptions
+{
+ ///
+ /// Exception thrown when something went wrong while reading in .
+ ///
+ public class PipingSoilProfileReadException : Exception
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public PipingSoilProfileReadException()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ /// with a specified error message.
+ ///
+ /// The message that describes the error.
+ public PipingSoilProfileReadException(string message)
+ : base(message)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class with a specified error message
+ /// and a reference to the inner exception that is the cause of this exception.
+ ///
+ /// The error message that explains the reason for the exception.
+ /// The exception that is the cause of the current exception, or a
+ /// null reference if no inner exception is specified.
+ public PipingSoilProfileReadException(string message, Exception innerException) : base(message, innerException) { }
+ }
+}
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/PipingSoilLayer2DReader.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/PipingSoilLayer2DReader.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/PipingSoilLayer2DReader.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,173 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Xml;
+using Wti.Data;
+using Wti.IO.Builders;
+
+namespace Wti.IO
+{
+ ///
+ /// This class is responsible for reading an array of bytes and interpret this as a XML document, which contains information about
+ /// the geometry of a .
+ ///
+ internal class PipingSoilLayer2DReader
+ {
+ private const string outerLoopElementName = "OuterLoop";
+ private const string innerLoopElementName = "InnerLoop";
+ private const string endPointElementName = "EndPoint";
+ private const string headPointElementName = "HeadPoint";
+ private const string xElementName = "X";
+ private const string yElementName = "Y";
+ private const string zElementName = "Z";
+
+ private readonly XmlTextReader xmlTextReader;
+
+ ///
+ /// Constructs a new , which uses the as the source of the
+ /// geometry for a .
+ ///
+ /// An array of which contains the information of a
+ /// in an XML document.
+ /// Thrown when is null.
+ internal PipingSoilLayer2DReader(byte[] geometry)
+ {
+ xmlTextReader = new XmlTextReader(new MemoryStream(geometry));
+ }
+
+ ///
+ /// Reads the XML document and from this obtains the required information and constructs a based
+ /// on this information.
+ ///
+ /// A new with information taken from the XML document.
+ /// When reading from the XML document of the failed.
+ internal SoilLayer2D Read()
+ {
+ var pipingSoilLayer = new SoilLayer2D();
+
+ while (xmlTextReader.Read())
+ {
+ HashSet outerLoop;
+ HashSet innerLoop;
+ if (TryParseLoop(outerLoopElementName, out outerLoop))
+ {
+ pipingSoilLayer.OuterLoop = outerLoop;
+ }
+ if (TryParseLoop(innerLoopElementName, out innerLoop))
+ {
+ pipingSoilLayer.InnerLoops.Add(innerLoop);
+ }
+ }
+
+ return pipingSoilLayer;
+ }
+
+ ///
+ /// Tries to parse the element with the given , which the reader should be currently pointing at, as a loop.
+ ///
+ /// 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)
+ {
+ loop = null;
+
+ if (IsElementWithName(elementName))
+ {
+ loop = new HashSet();
+
+ if (!IsEmptyElement())
+ {
+ while (xmlTextReader.Read() && !IsEndElementWithName(elementName))
+ {
+ Point3D parsedPoint;
+ if (TryParsePoint(out parsedPoint))
+ {
+ loop.Add(parsedPoint);
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ ///
+ /// Finds out whether the element which the reader is currently pointing at is empty.
+ ///
+ /// True if the element is empty. False otherwise.
+ private bool IsEmptyElement()
+ {
+ return xmlTextReader.IsEmptyElement;
+ }
+
+ ///
+ /// Tries to parse the element which the reader is currently pointing at as a point.
+ ///
+ /// 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)
+ {
+ point = null;
+
+ if (IsElementWithName(headPointElementName) || IsElementWithName(endPointElementName))
+ {
+ var pointValues = ReadChildValues();
+ point = new Point3D
+ {
+ X = double.Parse(pointValues[xElementName], CultureInfo.InvariantCulture),
+ Y = double.Parse(pointValues[yElementName], CultureInfo.InvariantCulture),
+ Z = double.Parse(pointValues[zElementName], CultureInfo.InvariantCulture)
+ };
+ return true;
+ }
+ return false;
+ }
+
+ ///
+ /// Reads the name and values for the children of the current element and puts them in a name indexed dictionary.
+ ///
+ /// A . For each entry, key is equal to child element name and value is equal to the value of the child element's text node.
+ private Dictionary ReadChildValues()
+ {
+ string elementName = xmlTextReader.Name;
+ var nodeSibblings = new Dictionary();
+
+ while (xmlTextReader.Read() && !IsEndElementWithName(elementName))
+ {
+ if (xmlTextReader.NodeType == XmlNodeType.Element)
+ {
+ nodeSibblings[xmlTextReader.Name] = xmlTextReader.ReadString();
+ }
+ }
+
+ return nodeSibblings;
+ }
+
+ ///
+ /// Checks whether the element the reader is currently pointing at is of type and has a name equal to .
+ ///
+ /// The name which the element should have.
+ /// True if the current element has type and its name is equal to .
+ private bool IsElementWithName(string name)
+ {
+ var isElement = xmlTextReader.NodeType == XmlNodeType.Element;
+ var isPoint = xmlTextReader.Name == name;
+
+ return isElement && isPoint;
+ }
+ ///
+ /// Checks whether the element the reader is currently pointing at is of type and has a name equal to .
+ ///
+ /// The name which the end element should have.
+ /// True if the current element has type and its name is equal to .
+ private bool IsEndElementWithName(string name)
+ {
+ var isElement = xmlTextReader.NodeType == XmlNodeType.EndElement;
+ var isPoint = xmlTextReader.Name == name;
+
+ return isElement && isPoint;
+ }
+ }
+}
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/PipingSoilProfileReader.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/PipingSoilProfileReader.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/PipingSoilProfileReader.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,150 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Data.SQLite;
+using System.IO;
+using System.Linq;
+using System.Xml;
+using Wti.Data;
+using Wti.IO.Builders;
+using Wti.IO.Exceptions;
+using Wti.IO.Properties;
+
+namespace Wti.IO
+{
+ ///
+ /// This class reads a SqLite database file and constructs from this database.
+ /// The database is created with the DSoilModel application.
+ ///
+ public class PipingSoilProfileReader : IDisposable
+ {
+ private const int pipingMechanismId = 4;
+ private const int profileNameIndex = 0;
+ private const int profileLayerGeometryIndex = 1;
+ private const int intersectionXIndex = 3;
+
+ private SQLiteConnection connection;
+ private SQLiteDataReader dataReader;
+
+ ///
+ /// Creates a new instance of which will use the
+ /// as its source.
+ ///
+ ///
+ public PipingSoilProfileReader(string dbFile)
+ {
+ if (String.IsNullOrEmpty(dbFile))
+ {
+ throw new ArgumentException(Resources.Error_PathMustBeSpecified);
+ }
+ if (!File.Exists(dbFile))
+ {
+ throw new FileNotFoundException(String.Format(Resources.Error_File_0_does_not_exist, dbFile));
+ }
+
+ PrepareConnection(dbFile);
+ Connect();
+ }
+
+ ///
+ /// Creates instances of based on the database file of the .
+ ///
+ ///
+ /// Thrown when reading soil profile entries from the database failed.
+ /// Thrown when parsing the geometry of a soil layer failed.
+ public IEnumerable Read()
+ {
+ var pipingSoilProfiles = new Dictionary();
+
+ CreateDataReader();
+
+ while (dataReader.Read())
+ {
+ var profileName = (string) dataReader[profileNameIndex];
+ var intersectionX = (double) dataReader[intersectionXIndex];
+ if (!pipingSoilProfiles.ContainsKey(profileName))
+ {
+ pipingSoilProfiles.Add(profileName, new SoilProfileBuilder(profileName, intersectionX));
+ }
+
+ pipingSoilProfiles[profileName].Add(ReadPipingSoilLayer());
+ }
+
+ return pipingSoilProfiles.Select(keyValue => keyValue.Value.Build());
+ }
+
+ public void Dispose()
+ {
+ dataReader.Dispose();
+ connection.Dispose();
+ }
+
+ private void PrepareConnection(string dbFile)
+ {
+ var connectionStringBuilder = new SQLiteConnectionStringBuilder
+ {
+ FailIfMissing = true,
+ DataSource = dbFile,
+ ReadOnly = true,
+ ForeignKeys = true
+ };
+
+ connection = new SQLiteConnection(connectionStringBuilder.ConnectionString);
+ }
+
+ private void Connect()
+ {
+ try
+ {
+ connection.Open();
+ }
+ catch (SQLiteException)
+ {
+ connection.Dispose();
+ }
+ }
+
+ private SoilLayer2D ReadPipingSoilLayer()
+ {
+ var columnValue = dataReader[profileLayerGeometryIndex];
+ var geometry = (byte[]) columnValue;
+ return new PipingSoilLayer2DReader(geometry).Read();
+ }
+
+ ///
+ /// Creates a new data reader to use in this class, based on a query which returns all the known soil layers for which its profile has a X coordinate defined for piping.
+ ///
+ private void CreateDataReader()
+ {
+ var mechanismParameterName = "mechanism";
+ var query = new SQLiteCommand(connection)
+ {
+ CommandText = string.Format(
+ "SELECT p.SP2D_Name, l.GeometrySurface, mat.MA_Name, mpl.X " +
+ "FROM MechanismPointLocation as m " +
+ "JOIN MechanismPointLocation as mpl ON p.SP2D_ID = mpl.SP2D_ID " +
+ "JOIN SoilProfile2D as p ON m.SP2D_ID = p.SP2D_ID " +
+ "JOIN SoilLayer2D as l ON l.SP2D_ID = p.SP2D_ID " +
+ "JOIN Materials as mat ON mat.MA_ID = l.MA_ID " +
+ "WHERE m.ME_ID = @{0} " +
+ "ORDER BY p.SP2D_ID, l.SP2D_ID",
+ mechanismParameterName)
+ };
+ query.Parameters.Add(new SQLiteParameter
+ {
+ DbType = DbType.Int32,
+ Value = pipingMechanismId,
+ ParameterName = mechanismParameterName
+ });
+
+ try
+ {
+ dataReader = query.ExecuteReader();
+ }
+ catch (SQLiteException e)
+ {
+ throw new PipingSoilProfileReadException(string.Format(Resources.Error_SoilProfileReadFromDatabase, connection.DataSource), e);
+ }
+ }
+ }
+}
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/PipingSurfaceLinesCsvReader.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/PipingSurfaceLinesCsvReader.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/PipingSurfaceLinesCsvReader.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,404 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+
+using Wti.Data;
+using Wti.IO.Exceptions;
+using Wti.IO.Properties;
+
+namespace Wti.IO
+{
+ ///
+ /// File reader for a plain text file in comma-separated values format (*.csv), containing
+ /// data specifying surfacelines.
+ /// Expects data to be specified in the following format:
+ /// {ID};X1;Y1;Z1...;(Xn;Yn;Zn)
+ /// Where {ID} has to be a particular accepted text, and n triplets of doubles form the
+ /// 3D coordinates defining the geometric shape of the surfaceline..
+ ///
+ public class PipingSurfaceLinesCsvReader : IDisposable
+ {
+ private const char separator = ';';
+
+ private readonly string[] acceptableLowerCaseIdNames =
+ {
+ "profielnaam",
+ "locationid"
+ };
+
+ private readonly string filePath;
+
+ private readonly string[] expectedFirstCoordinateHeader =
+ {
+ "x1",
+ "y1",
+ "z1"
+ };
+
+ private StreamReader fileReader;
+ private int lineNumber;
+
+ ///
+ /// Initializes a new instance of the class
+ /// and opens a given file path.
+ ///
+ /// The path to the file to be read.
+ /// is invalid.
+ public PipingSurfaceLinesCsvReader(string path)
+ {
+ ValidateFilePath(path);
+
+ filePath = path;
+ }
+
+ ///
+ /// Reads the file to determine the number of available
+ /// data rows.
+ ///
+ /// A value greater than or equal to 0.
+ /// A critical error has occurred, which may be caused by:
+ ///
+ /// - File cannot be found at specified path.
+ /// - The specified path is invalid, such as being on an unmapped drive.
+ /// - Some other I/O related issue occurred, such as: path includes an incorrect
+ /// or invalid syntax for file name, directory name, or volume label.
+ /// - There is insufficient memory to allocate a buffer for the returned string.
+ /// - File incompatible for importing surface lines.
+ ///
+ ///
+ public int GetSurfaceLinesCount()
+ {
+ using (var reader = InitializeStreamReader(filePath))
+ {
+ ValidateHeader(reader, 1);
+
+ return CountNonEmptyLines(reader, 2);
+ }
+ }
+
+ ///
+ /// Reads and consumes the next data row, parsing the data to create an instance
+ /// of .
+ ///
+ /// Return the parse surfaceline, or null when at the end of the file.
+ /// A critical error has occurred, which may be caused by:
+ ///
+ /// - File cannot be found at specified path.
+ /// - The specified path is invalid, such as being on an unmapped drive.
+ /// - Some other I/O related issue occurred, such as: path includes an incorrect
+ /// or invalid syntax for file name, directory name, or volume label.
+ /// - There is insufficient memory to allocate a buffer for the returned string.
+ /// - File incompatible for importing surface lines.
+ ///
+ ///
+ /// A parse error has occurred for the current row, which may be caused by:
+ ///
+ /// - The row doesn't contain any supported separator character.
+ /// - The row contains a coordinate value that cannot be parsed as a double.
+ /// - The row contains a number that is too big or too small to be represented with a double.
+ /// - The row is missing an identifier value.
+ /// - The row is missing values to form a surface line point.
+ ///
+ ///
+ public RingtoetsPipingSurfaceLine ReadLine()
+ {
+ if (fileReader == null)
+ {
+ fileReader = InitializeStreamReader(filePath);
+
+ ValidateHeader(fileReader, 1);
+ lineNumber = 2;
+ }
+
+ var readText = ReadLineAndHandleIOExceptions(fileReader, lineNumber);
+ if (readText != null)
+ {
+ try
+ {
+ var tokenizedString = TokenizeString(readText);
+
+ var surfaceLineName = GetSurfaceLineName(tokenizedString);
+ var points = GetSurfaceLinePoints(tokenizedString);
+
+ var surfaceLine = new RingtoetsPipingSurfaceLine
+ {
+ Name = surfaceLineName
+ };
+ surfaceLine.SetGeometry(points);
+ return surfaceLine;
+ }
+ finally
+ {
+ lineNumber++;
+ }
+ }
+
+ return null;
+ }
+
+ public void Dispose()
+ {
+ if (fileReader != null)
+ {
+ fileReader.Dispose();
+ fileReader = null;
+ }
+ }
+
+ ///
+ /// Tokenizes a string using a separator character.
+ ///
+ /// The text.
+ /// The tokenized parts.
+ /// lacks separator character.
+ private string[] TokenizeString(string readText)
+ {
+ if (!readText.Contains(separator))
+ {
+ var message = string.Format(Resources.PipingSurfaceLinesCsvReader_ReadLine_File_0_Line_1_Lacks_separator_2_,
+ filePath, lineNumber, separator);
+ throw new LineParseException(message);
+ }
+ return readText.Split(separator);
+ }
+
+ ///
+ /// Gets the 3D surface line points.
+ ///
+ /// The tokenized string.
+ ///
+ /// A parse error has occurred for the current row, which may be caused by:
+ ///
+ /// - contains a coordinate value that cannot be parsed as a double.
+ /// - contains a number that is too big or too small to be represented with a double.
+ /// - is missing coordinate values to define a proper surface line point.
+ ///
+ ///
+ private Point3D[] GetSurfaceLinePoints(string[] tokenizedString)
+ {
+ const int expectedValuesForPoint = 3;
+
+ var worldCoordinateValues = ParseWorldCoordinateValuesAndHandleParseErrors(tokenizedString);
+ if (worldCoordinateValues.Length % expectedValuesForPoint != 0)
+ {
+ var message = string.Format(Resources.PipingSurfaceLinesCsvReader_ReadLine_File_0_Line_1_Lacks_values_for_coordinate_triplet,
+ filePath, lineNumber);
+ throw new LineParseException(message);
+ }
+
+ int coordinateCount = worldCoordinateValues.Length / expectedValuesForPoint;
+ var points = new Point3D[coordinateCount];
+ for (int i = 0; i < coordinateCount; i++)
+ {
+ points[i] = new Point3D
+ {
+ X = worldCoordinateValues[i * expectedValuesForPoint],
+ Y = worldCoordinateValues[i * expectedValuesForPoint + 1],
+ Z = worldCoordinateValues[i * expectedValuesForPoint + 2]
+ };
+ }
+ return points;
+ }
+
+ ///
+ /// Gets the name of the surface line.
+ ///
+ /// The tokenized string from which the name should be extrated.
+ /// The name of the surface line.
+ /// Id value is null or empty.
+ private string GetSurfaceLineName(IList tokenizedString)
+ {
+ var name = tokenizedString[0].Trim();
+ if (string.IsNullOrEmpty(name))
+ {
+ var message = string.Format(Resources.PipingSurfaceLinesCsvReader_ReadLine_File_0_Line_1_NoId,
+ filePath, lineNumber);
+ throw new LineParseException(message);
+ }
+ return name;
+ }
+
+ ///
+ /// Parses the world coordinate values and handles parse errors.
+ ///
+ /// The tokenized string.
+ ///
+ /// A parse error has occurred for the current row, which may be caused by:
+ ///
+ /// - The row contains a coordinate value that cannot be parsed as a double.
+ /// - The row contains a number that is too big or too small to be represented with a double.
+ ///
+ ///
+ private double[] ParseWorldCoordinateValuesAndHandleParseErrors(string[] tokenizedString)
+ {
+ try
+ {
+ return tokenizedString.Skip(1)
+ .Select(ts => Double.Parse(ts, CultureInfo.InvariantCulture))
+ .ToArray();
+ }
+ catch (FormatException e)
+ {
+ var message = string.Format(Resources.Error_File_0_has_not_double_Line_1_,
+ filePath, lineNumber);
+ throw new LineParseException(message, e);
+ }
+ catch (OverflowException e)
+ {
+ var message = string.Format(Resources.Error_File_0_Parsing_causes_overflow_Line_1_,
+ filePath, lineNumber);
+ throw new LineParseException(message, e);
+ }
+ }
+
+ ///
+ /// Initializes the stream reader for a UTF8 encoded file.
+ ///
+ /// The path to the file to be read.
+ /// A UTF8 encoding configured stream reader opened on .
+ /// File/directory cannot be found or
+ /// some other I/O related problem occurred.
+ private static StreamReader InitializeStreamReader(string path)
+ {
+ try
+ {
+ return new StreamReader(path);
+ }
+ catch (FileNotFoundException e)
+ {
+ var message = string.Format(Resources.Error_File_0_does_not_exist, path);
+ throw new CriticalFileReadException(message, e);
+ }
+ catch (DirectoryNotFoundException e)
+ {
+ var message = string.Format(Resources.Error_Directory_in_path_0_missing, path);
+ throw new CriticalFileReadException(message, e);
+ }
+ catch (IOException e)
+ {
+ var message = string.Format(Resources.Error_General_IO_File_0_ErrorMessage_1_, path, e.Message);
+ throw new CriticalFileReadException(message, e);
+ }
+ }
+
+ ///
+ /// Validates the header of the file.
+ ///
+ /// The reader, which is currently at the header row.
+ /// Row index used in error messaging.
+ /// The header is not in the required format.
+ private void ValidateHeader(TextReader reader, int currentLine)
+ {
+ var header = ReadLineAndHandleIOExceptions(reader, currentLine);
+ if (header != null)
+ {
+ if (!IsHeaderValid(header))
+ {
+ var expectedMessage = string.Format(Resources.PipingSurfaceLinesCsvReader_File_0_invalid_header, filePath);
+ throw new CriticalFileReadException(expectedMessage);
+ }
+ }
+ else
+ {
+ var expectedMessage = string.Format(Resources.Error_File_0_empty, filePath);
+ throw new CriticalFileReadException(expectedMessage);
+ }
+ }
+
+ ///
+ /// Counts the remaining non-empty lines.
+ ///
+ /// The reader at the row from which counting should start.
+ /// The current line, used for error messaging.
+ /// An integer greater than or equal to 0.
+ /// An I/O exception occurred.
+ private int CountNonEmptyLines(TextReader reader, int currentLine)
+ {
+ int count = 0, lineNumberForMessage = currentLine;
+ string line;
+ while ((line = ReadLineAndHandleIOExceptions(reader, lineNumberForMessage)) != null)
+ {
+ if (!String.IsNullOrWhiteSpace(line))
+ {
+ count++;
+ }
+ lineNumberForMessage++;
+ }
+ return count;
+ }
+
+ ///
+ /// Reads the next line and handles I/O exceptions.
+ ///
+ /// The opened text file reader.
+ /// Row number for error messaging.
+ /// The read line, or null when at the end of the file.
+ /// An critical I/O exception occurred.
+ private string ReadLineAndHandleIOExceptions(TextReader reader, int currentLine)
+ {
+ try
+ {
+ return reader.ReadLine();
+ }
+ catch (OutOfMemoryException e)
+ {
+ var message = string.Format(Resources.Error_File_0_contains_Line_1_too_big, filePath, currentLine);
+ throw new CriticalFileReadException(message, e);
+ }
+ catch (IOException e)
+ {
+ var message = string.Format(Resources.Error_General_IO_File_0_ErrorMessage_1_, filePath, e.Message);
+ throw new CriticalFileReadException(message, e);
+ }
+ }
+
+ private bool IsHeaderValid(string header)
+ {
+ var tokenizedHeader = header.Split(separator).Select(s => s.Trim().ToLowerInvariant()).ToArray();
+
+ // Check for valid id:
+ if (!acceptableLowerCaseIdNames.Contains(tokenizedHeader[0]))
+ {
+ return false;
+ }
+
+ // CHeck for valid 1st coordinate in header:
+ bool valid = true;
+ for (int i = 0; i < expectedFirstCoordinateHeader.Length && valid; i++)
+ {
+ valid = tokenizedHeader[1 + i].Equals(expectedFirstCoordinateHeader[i]);
+ }
+ return valid;
+ }
+
+ ///
+ /// Validates the file path.
+ ///
+ /// The file path to be validated.
+ /// is invalid.
+ private void ValidateFilePath(string path)
+ {
+ if (string.IsNullOrWhiteSpace(path))
+ {
+ throw new ArgumentException(Resources.Error_PathMustBeSpecified);
+ }
+
+ string name;
+ try
+ {
+ name = Path.GetFileName(path);
+ }
+ catch (ArgumentException e)
+ {
+ throw new ArgumentException(String.Format(Resources.Error_PathCannotContainCharacters_0_,
+ String.Join(", ", Path.GetInvalidFileNameChars())), e);
+ }
+ if (string.Empty == name)
+ {
+ throw new ArgumentException(Resources.Error_PathMustNotPointToFolder);
+ }
+ }
+ }
+}
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/AssemblyInfo.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/AssemblyInfo.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/AssemblyInfo.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,8 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Wti.IO")]
+[assembly: AssemblyProduct("Wti.IO")]
+[assembly: Guid("f5af3cbe-d10c-42a5-b625-95222648aeaf")]
+[assembly: InternalsVisibleTo("Wti.IO.Test")]
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.Designer.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.Designer.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.Designer.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,226 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.34209
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace Wti.IO.Properties {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ public class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ public static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Wti.IO.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ public static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Kan geen 1D profiel bepalen wanneer segmenten in een 2D laag verticaal lopen op de gekozen positie: x = {0}..
+ ///
+ public static string Error_CanNotDetermine1DProfileWithVerticalSegmentsAtX {
+ get {
+ return ResourceManager.GetString("Error_CanNotDetermine1DProfileWithVerticalSegmentsAtX", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Het bestandspad '{0}' verwijst naar een map die niet bestaat..
+ ///
+ public static string Error_Directory_in_path_0_missing {
+ get {
+ return ResourceManager.GetString("Error_Directory_in_path_0_missing", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Het bestand op '{0}' heeft op regel {1} teveel tekst om in het RAM geheugen opgeslagen te worden..
+ ///
+ public static string Error_File_0_contains_Line_1_too_big {
+ get {
+ return ResourceManager.GetString("Error_File_0_contains_Line_1_too_big", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Het bestand op '{0}' bestaat niet..
+ ///
+ public static string Error_File_0_does_not_exist {
+ get {
+ return ResourceManager.GetString("Error_File_0_does_not_exist", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Het bestand op '{0}' is leeg..
+ ///
+ public static string Error_File_0_empty {
+ get {
+ return ResourceManager.GetString("Error_File_0_empty", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Het bestand '{0}' heeft op regel {1} een waarde dat geen getal is..
+ ///
+ public static string Error_File_0_has_not_double_Line_1_ {
+ get {
+ return ResourceManager.GetString("Error_File_0_has_not_double_Line_1_", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Het bestand '{0}' heeft op regel {1} een waarde dat te groot/klein is om ingelezen te worden..
+ ///
+ public static string Error_File_0_Parsing_causes_overflow_Line_1_ {
+ get {
+ return ResourceManager.GetString("Error_File_0_Parsing_causes_overflow_Line_1_", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Er is een onverwachte inleesfout opgetreden tijdens het lezen van het bestand '{0}': {1}.
+ ///
+ public static string Error_General_IO_File_0_ErrorMessage_1_ {
+ get {
+ return ResourceManager.GetString("Error_General_IO_File_0_ErrorMessage_1_", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Bestandspad mag niet de volgende tekens bevatten: {0}.
+ ///
+ public static string Error_PathCannotContainCharacters_0_ {
+ get {
+ return ResourceManager.GetString("Error_PathCannotContainCharacters_0_", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Bestandspad mag niet leeg of ongedefinieerd zijn..
+ ///
+ public static string Error_PathMustBeSpecified {
+ get {
+ return ResourceManager.GetString("Error_PathMustBeSpecified", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Bestandspad mag niet naar een map verwijzen..
+ ///
+ public static string Error_PathMustNotPointToFolder {
+ get {
+ return ResourceManager.GetString("Error_PathMustNotPointToFolder", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Geen geldige X waarde gevonden om intersectie te maken uit 2D profiel '{0}'..
+ ///
+ public static string Error_SoilProfileBuilderCantDetermineIntersectAtDoubleNaN {
+ get {
+ return ResourceManager.GetString("Error_SoilProfileBuilderCantDetermineIntersectAtDoubleNaN", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Kon geen ondergrond profielen verkrijgen van de database '{0}'..
+ ///
+ public static string Error_SoilProfileReadFromDatabase {
+ get {
+ return ResourceManager.GetString("Error_SoilProfileReadFromDatabase", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Het bestand op '{0}' heeft op regel {1} teveel tekst om in het RAM geheugen opgeslagen te worden..
+ ///
+ public static string Error_Unexpected_IOError_File_0_Line_1_ {
+ get {
+ return ResourceManager.GetString("Error_Unexpected_IOError_File_0_Line_1_", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Het bestand op '{0}' is niet geschikt om dwarsdoorsneden uit te lezen (Verwachte header: locationid;X1;Y1;Z1)..
+ ///
+ public static string PipingSurfaceLinesCsvReader_File_0_invalid_header {
+ get {
+ return ResourceManager.GetString("PipingSurfaceLinesCsvReader_File_0_invalid_header", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Het bestand '{0}' heeft op regel {1} geen verwacht scheidingsteken (het karakter: {2})..
+ ///
+ public static string PipingSurfaceLinesCsvReader_ReadLine_File_0_Line_1_Lacks_separator_2_ {
+ get {
+ return ResourceManager.GetString("PipingSurfaceLinesCsvReader_ReadLine_File_0_Line_1_Lacks_separator_2_", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Het bestand '{0}' heeft op regel {1} ontbrekende waardes om een 3D (X,Y,Z) punt aan te maken..
+ ///
+ public static string PipingSurfaceLinesCsvReader_ReadLine_File_0_Line_1_Lacks_values_for_coordinate_triplet {
+ get {
+ return ResourceManager.GetString("PipingSurfaceLinesCsvReader_ReadLine_File_0_Line_1_Lacks_values_for_coordinate_tr" +
+ "iplet", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Het bestand '{0}' heeft op regel {1} heeft geen ID..
+ ///
+ public static string PipingSurfaceLinesCsvReader_ReadLine_File_0_Line_1_NoId {
+ get {
+ return ResourceManager.GetString("PipingSurfaceLinesCsvReader_ReadLine_File_0_Line_1_NoId", resourceCulture);
+ }
+ }
+ }
+}
Index: src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.resx
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.resx (revision 0)
+++ src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.resx (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,174 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Bestandspad mag niet leeg of ongedefinieerd zijn.
+
+
+ Bestandspad mag niet naar een map verwijzen.
+
+
+ Bestandspad mag niet de volgende tekens bevatten: {0}
+
+
+ Het bestand op '{0}' bestaat niet.
+
+
+ Het bestandspad '{0}' verwijst naar een map die niet bestaat.
+
+
+ Het bestand op '{0}' heeft op regel {1} teveel tekst om in het RAM geheugen opgeslagen te worden.
+
+
+ Het bestand op '{0}' heeft op regel {1} teveel tekst om in het RAM geheugen opgeslagen te worden.
+
+
+ Er is een onverwachte inleesfout opgetreden tijdens het lezen van het bestand '{0}': {1}
+
+
+ Het bestand op '{0}' is leeg.
+
+
+ Het bestand op '{0}' is niet geschikt om dwarsdoorsneden uit te lezen (Verwachte header: locationid;X1;Y1;Z1).
+
+
+ Kon geen ondergrond profielen verkrijgen van de database '{0}'.
+
+
+ Geen geldige X waarde gevonden om intersectie te maken uit 2D profiel '{0}'.
+
+
+ Het bestand '{0}' heeft op regel {1} een waarde dat geen getal is.
+
+
+ Het bestand '{0}' heeft op regel {1} een waarde dat te groot/klein is om ingelezen te worden.
+
+
+ Het bestand '{0}' heeft op regel {1} heeft geen ID.
+
+
+ Het bestand '{0}' heeft op regel {1} geen verwacht scheidingsteken (het karakter: {2}).
+
+
+ Het bestand '{0}' heeft op regel {1} ontbrekende waardes om een 3D (X,Y,Z) punt aan te maken.
+
+
+ Kan geen 1D profiel bepalen wanneer segmenten in een 2D laag verticaal lopen op de gekozen positie: x = {0}.
+
+
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Wti.IO.csproj
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Wti.IO.csproj (revision 0)
+++ src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/Wti.IO.csproj (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,123 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {35B87B7A-7F50-4139-B563-589EE522B1ED}
+ Library
+ Properties
+ Wti.IO
+ Wti.IO
+ v4.0
+ 512
+
+
+ true
+ bin\Debug\
+ 4
+ DEBUG;TRACE
+ full
+ x86
+ false
+ prompt
+ MinimumRecommendedRules.ruleset
+ bin\Debug\Wti.IO.XML
+
+
+ bin\Release\
+ 4
+ TRACE
+ true
+ pdbonly
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+ bin\Release\Wti.IO.XML
+
+
+
+ Properties\GlobalAssembly.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+ {82b61d20-fd4b-49be-9252-5bf6e3ee4666}
+ DelftTools.Shell.Core
+
+
+ {c90b77da-e421-43cc-b82e-529651bc21ac}
+ Wti.Base
+ False
+
+
+ {ce994cc9-6f6a-48ac-b4be-02c30a21f4db}
+ Wti.Data
+
+
+
+
+ PublicResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+
+
+ C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll
+
+
+
+ ..\..\..\..\..\..\packages\System.Data.SQLite.Core.1.0.98.1\lib\net40\System.Data.SQLite.dll
+ True
+
+
+ C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.XML.dll
+
+
+
+
+
+
+
+ SQLite.Interop.dll
+ Always
+
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/packages.config
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/packages.config (revision 0)
+++ src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.IO/packages.config (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.Plugin/Ringtoets.Piping.Plugin.csproj
===================================================================
diff -u -r1450c6e12cbd3358c66a9efec22203c988af78ed -rb3fa1606efddd3bed496c2844a495ff92347fa44
--- src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.Plugin/Ringtoets.Piping.Plugin.csproj (.../Ringtoets.Piping.Plugin.csproj) (revision 1450c6e12cbd3358c66a9efec22203c988af78ed)
+++ src/Plugins/Ringtoets/Piping/src/Ringtoets.Piping.Plugin/Ringtoets.Piping.Plugin.csproj (.../Ringtoets.Piping.Plugin.csproj) (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -111,6 +111,10 @@
{7cd038e1-e111-4969-aced-22c5bd2974e1}
Wti.Forms
+
+ {35b87b7a-7f50-4139-b563-589ee522b1ed}
+ Wti.IO
+
{10B8D63D-87E8-46DF-ACA9-A8CF22EE8FB5}
Ringtoets.Piping.Service
@@ -119,10 +123,6 @@
{ce994cc9-6f6a-48ac-b4be-02c30a21f4db}
Wti.Data
-
- {35b87b7a-7f50-4139-b563-589ee522b1ed}
- Wti.IO
-
Index: src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Builders/SoilLayer2DTest.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Builders/SoilLayer2DTest.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Builders/SoilLayer2DTest.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,539 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using NUnit.Framework;
+using Wti.Data;
+using Wti.Data.TestUtil;
+using Wti.IO.Builders;
+using Wti.IO.Properties;
+
+namespace Wti.IO.Test.Builders
+{
+ public class SoilLayer2DTest
+ {
+ [Test]
+ public void DefaultConstructor_Always_NotInstantiatedOuterLoopAndEmptyInnerLoops()
+ {
+ // Call
+ var result = new SoilLayer2D();
+
+ // Assert
+ Assert.IsNull(result.OuterLoop);
+ CollectionAssert.IsEmpty(result.InnerLoops);
+ }
+
+ [Test]
+ public void AsPipingSoilLayers_DefaultConstructed_ReturnsEmptyCollectionWithMaxValueBottom()
+ {
+ // Setup
+ var layer = new SoilLayer2D();
+ double bottom;
+
+ // Call
+ var result = layer.AsPipingSoilLayers(0.0, out bottom);
+
+ // Assert
+ CollectionAssert.IsEmpty(result);
+ Assert.AreEqual(double.MaxValue, bottom);
+ }
+
+ [Test]
+ public void AsPipingSoilLayers_WithOuterLoopNotIntersectingX_ReturnsEmptyCollectionWithMaxValueBottom()
+ {
+ // Setup
+ var layer = new SoilLayer2D
+ {
+ OuterLoop = new HashSet
+ {
+ new Point3D
+ {
+ X = 0.1, Z = new Random(22).NextDouble()
+ }
+ }
+ };
+ double bottom;
+
+ // Call
+ var result = layer.AsPipingSoilLayers(0.0, out bottom);
+
+ // Assert
+ CollectionAssert.IsEmpty(result);
+ Assert.AreEqual(double.MaxValue, bottom);
+ }
+
+ [Test]
+ public void AsPipingSoilLayers_WithOuterLoopIntersectingX_ReturnsBottomAndLayerWithTop()
+ {
+ // Setup
+ var expectedZ = new Random(22).NextDouble();
+ var layer = new SoilLayer2D
+ {
+ OuterLoop = new HashSet
+ {
+ new Point3D
+ {
+ X = -0.1, Z = expectedZ
+ },
+ new Point3D
+ {
+ X = 0.1, Z = expectedZ
+ }
+ }
+ };
+ double bottom;
+
+ // Call
+ var result = layer.AsPipingSoilLayers(0.0, out bottom).ToArray();
+
+ // Assert
+ Assert.AreEqual(1, result.Length);
+ Assert.AreEqual(expectedZ, bottom);
+ Assert.AreEqual(expectedZ, result[0].Top);
+ }
+
+ [Test]
+ public void AsPipingSoilLayers_OuterLoopComplex_ReturnsTwoLayers()
+ {
+ // Setup
+ var outerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "..1..2..",
+ "........",
+ "..8.7...",
+ "..5.6...",
+ "..4..3..",
+ "........"));
+
+ var layer = new SoilLayer2D
+ {
+ OuterLoop = outerLoop
+ };
+
+ // Call
+ double bottom;
+ var result = layer.AsPipingSoilLayers(3.5, out bottom).ToArray();
+
+ // Assert
+ Assert.AreEqual(2, result.Length);
+ Assert.AreEqual(1.0, bottom);
+ CollectionAssert.AreEquivalent(new[] { 5.0, 2.0 }, result.Select(rl => rl.Top));
+ }
+
+ [Test]
+ public void AsPipingSoilLayers_OuterLoopInnerLoopSimple_ReturnsTwoLayers()
+ {
+ // Setup
+ var outerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "..1..2..",
+ "........",
+ "........",
+ "........",
+ "........",
+ "..4..3.."));
+
+ var innerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "........",
+ "...12...",
+ "........",
+ "........",
+ "...43...",
+ "........"));
+
+ var layer = new SoilLayer2D
+ {
+ OuterLoop = outerLoop,
+ InnerLoops =
+ {
+ innerLoop
+ }
+ };
+
+ // Call
+ double bottom;
+ var result = layer.AsPipingSoilLayers(3.5, out bottom).ToArray();
+
+ // Assert
+ Assert.AreEqual(2, result.Length);
+ Assert.AreEqual(0, bottom);
+ CollectionAssert.AreEquivalent(new [] {5.0, 1.0}, result.Select(rl => rl.Top));
+ }
+
+ [Test]
+ public void AsPipingSoilLayers_OuterLoopInnerLoopComplex_ReturnsThreeLayers()
+ {
+ // Setup
+ var outerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "..1..2..",
+ "........",
+ "........",
+ "........",
+ "........",
+ "..4..3.."));
+
+ var innerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "........",
+ "...1.2..",
+ "...87...",
+ "...56...",
+ "...4.3..",
+ "........"));
+
+ var layer = new SoilLayer2D
+ {
+ OuterLoop = outerLoop,
+ InnerLoops =
+ {
+ innerLoop
+ }
+ };
+
+ // Call
+ double bottom;
+ var result = layer.AsPipingSoilLayers(3.5, out bottom).ToArray();
+
+ // Assert
+ Assert.AreEqual(3, result.Length);
+ Assert.AreEqual(0, bottom);
+ CollectionAssert.AreEquivalent(new[] { 5.0, 3.0, 1.0 }, result.Select(rl => rl.Top));
+ }
+
+ [Test]
+ public void AsPipingSoilLayers_OuterLoopMultipleInnerLoops_ReturnsThreeLayers()
+ {
+ // Setup
+ var outerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "..1..2..",
+ "........",
+ "........",
+ "........",
+ "........",
+ "..4..3.."));
+
+ var innerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "........",
+ "...12...",
+ "...43...",
+ "........",
+ "........",
+ "........"));
+
+ var innerLoop2 = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "........",
+ "........",
+ "........",
+ "........",
+ "...12...",
+ "........"));
+
+ var layer = new SoilLayer2D
+ {
+ OuterLoop = outerLoop,
+ InnerLoops =
+ {
+ innerLoop,
+ innerLoop2
+ }
+ };
+
+ // Call
+ double bottom;
+ var result = layer.AsPipingSoilLayers(3.5, out bottom).ToArray();
+
+ // Assert
+ Assert.AreEqual(3, result.Length);
+ Assert.AreEqual(0, bottom);
+ CollectionAssert.AreEquivalent(new[] { 5.0, 3.0, 1.0 }, result.Select(rl => rl.Top));
+ }
+
+ [Test]
+ public void AsPipingSoilLayers_OuterLoopOverlappingInnerLoop_ReturnsOneLayer()
+ {
+ // Setup
+ var outerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "..1..2..",
+ "........",
+ "........",
+ "........",
+ ".4....3.",
+ "........"));
+
+ var innerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "........",
+ "........",
+ "........",
+ "...12...",
+ "........",
+ "...43..."));
+
+ var layer = new SoilLayer2D
+ {
+ OuterLoop = outerLoop,
+ InnerLoops =
+ {
+ innerLoop
+ }
+ };
+
+ // Call
+ double bottom;
+ var result = layer.AsPipingSoilLayers(3.5, out bottom).ToArray();
+
+ // Assert
+ Assert.AreEqual(1, result.Length);
+ Assert.AreEqual(2.0, bottom);
+ CollectionAssert.AreEquivalent(new[] { 5.0 }, result.Select(rl => rl.Top));
+ }
+
+ [Test]
+ public void AsPipingSoilLayers_OuterLoopOverlappingInnerLoopsFirstInnerLoopNotOverBottom_ReturnsOneLayer()
+ {
+ // Setup
+ var outerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "..1..2..",
+ "........",
+ "........",
+ "........",
+ ".4....3.",
+ "........"));
+
+ var innerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "........",
+ "...12...",
+ "........",
+ "...43...",
+ "........",
+ "........"));
+
+ var innerLoop2 = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "........",
+ "........",
+ "...12...",
+ "........",
+ "........",
+ "...43..."));
+
+ var layer = new SoilLayer2D
+ {
+ OuterLoop = outerLoop,
+ InnerLoops =
+ {
+ innerLoop,
+ innerLoop2
+ }
+ };
+
+ // Call
+ double bottom;
+ var result = layer.AsPipingSoilLayers(3.5, out bottom).ToArray();
+
+ // Assert
+ Assert.AreEqual(1, result.Length);
+ Assert.AreEqual(4.0, bottom);
+ CollectionAssert.AreEquivalent(new[] { 5.0 }, result.Select(rl => rl.Top));
+ }
+
+ [Test]
+ public void AsPipingSoilLayers_OuterLoopInnerLoopOnBorderBottom_ReturnsTwoLayers()
+ {
+ // Setup
+ var outerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "..1..2..",
+ "........",
+ "........",
+ "........",
+ ".4....3.",
+ "........"));
+
+ var innerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "........",
+ "........",
+ "...12...",
+ "........",
+ "...43...",
+ "........"));
+
+ var layer = new SoilLayer2D
+ {
+ OuterLoop = outerLoop,
+ InnerLoops =
+ {
+ innerLoop
+ }
+ };
+
+ // Call
+ double bottom;
+ var result = layer.AsPipingSoilLayers(3.5, out bottom).ToArray();
+
+ // Assert
+ Assert.AreEqual(2, result.Length);
+ Assert.AreEqual(3.0, bottom);
+ CollectionAssert.AreEquivalent(new[] { 5.0, 1.0 }, result.Select(rl => rl.Top));
+ }
+
+ [Test]
+ public void AsPipingSoilLayers_OuterLoopInnerLoopOverlapTop_ReturnsOneLayer()
+ {
+ // Setup
+ var outerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "........",
+ "..1..2..",
+ "........",
+ "........",
+ ".4....3.",
+ "........"));
+
+ var innerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "...43...",
+ "........",
+ "...12...",
+ "........",
+ "........",
+ "........"));
+
+ var layer = new SoilLayer2D
+ {
+ OuterLoop = outerLoop,
+ InnerLoops =
+ {
+ innerLoop
+ }
+ };
+
+ // Call
+ double bottom;
+ var result = layer.AsPipingSoilLayers(3.5, out bottom).ToArray();
+
+ // Assert
+ Assert.AreEqual(1, result.Length);
+ Assert.AreEqual(1.0, bottom);
+ CollectionAssert.AreEquivalent(new[] { 3.0 }, result.Select(rl => rl.Top));
+ }
+
+ [Test]
+ public void AsPipingSoilLayers_OuterLoopInnerLoopOnBorderTop_ReturnsOneLayer()
+ {
+ // Setup
+ var outerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "..1..2..",
+ "........",
+ "........",
+ "........",
+ ".4....3.",
+ "........"));
+
+ var innerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "...43...",
+ "........",
+ "...12...",
+ "........",
+ "........",
+ "........"));
+
+ var layer = new SoilLayer2D
+ {
+ OuterLoop = outerLoop,
+ InnerLoops =
+ {
+ innerLoop
+ }
+ };
+
+ // Call
+ double bottom;
+ var result = layer.AsPipingSoilLayers(3.5, out bottom).ToArray();
+
+ // Assert
+ Assert.AreEqual(1, result.Length);
+ Assert.AreEqual(1.0, bottom);
+ CollectionAssert.AreEquivalent(new[] { 3.0 }, result.Select(rl => rl.Top));
+ }
+
+ [Test]
+ public void AsPipingSoilLayers_OuterLoopVerticalAtX_ThrowsException()
+ {
+ // Setup
+ var atX = 2.0;
+ var outerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "..1..2..",
+ "........",
+ "........",
+ "........",
+ "........",
+ "..4..3.."));
+
+ var layer = new SoilLayer2D
+ {
+ OuterLoop = outerLoop
+ };
+
+ // Call
+ double bottom;
+ TestDelegate test = () => layer.AsPipingSoilLayers(atX, out bottom);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual(String.Format(Resources.Error_CanNotDetermine1DProfileWithVerticalSegmentsAtX, atX), exception.Message);
+ }
+
+ [Test]
+ public void AsPipingSoilLayers_InnerLoopVerticalAtX_ThrowsException()
+ {
+ // Setup
+ var atX = 3.0;
+ var outerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "..1..2..",
+ "........",
+ "........",
+ "........",
+ "........",
+ "..4..3.."));
+
+ var innerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "6",
+ "........",
+ "...1.2..",
+ "........",
+ "........",
+ "...4.3..",
+ "........"));
+
+ var layer = new SoilLayer2D
+ {
+ OuterLoop = outerLoop,
+ InnerLoops =
+ {
+ innerLoop
+ }
+ };
+
+ // Call
+ double bottom;
+ TestDelegate test = () => layer.AsPipingSoilLayers(atX, out bottom);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual(String.Format(Resources.Error_CanNotDetermine1DProfileWithVerticalSegmentsAtX, atX), exception.Message);
+ }
+ }
+}
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Builders/SoilProfileBuilderTest.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Builders/SoilProfileBuilderTest.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Builders/SoilProfileBuilderTest.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,199 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using NUnit.Framework;
+using Wti.Data;
+using Wti.Data.TestUtil;
+using Wti.IO.Builders;
+using Wti.IO.Properties;
+
+namespace Wti.IO.Test.Builders
+{
+ public class SoilProfileBuilderTest
+ {
+ [Test]
+ [TestCase(null)]
+ [TestCase("name")]
+ public void Constructor_WithNameInvalidX_ThrowsArgumentExcpetion(string name)
+ {
+ // Call
+ TestDelegate test = () => new SoilProfileBuilder(name, double.NaN);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual(Resources.Error_SoilProfileBuilderCantDetermineIntersectAtDoubleNaN, exception.Message);
+ }
+
+ [Test]
+ [TestCase(null)]
+ [TestCase("name")]
+ public void Constructor_WithNameValidX_ReturnsNewInstance(string name)
+ {
+ // Call
+ var builder = new SoilProfileBuilder(name, 0.0);
+
+ // Assert
+ Assert.NotNull(builder);
+ }
+
+ [Test]
+ public void Build_WithOutLayers_ThrowsArgumentException()
+ {
+ // Setup
+ var profileName = "SomeProfile";
+ var builder = new SoilProfileBuilder(profileName, 0.0);
+
+ // Call
+ TestDelegate test = () => builder.Build();
+
+ // Assert
+ Assert.Throws(test);
+ }
+
+ [Test]
+ public void Build_WithSingleLayerOnlyOuterLoop_ReturnsProfileWithBottomAndALayer()
+ {
+ // Setup
+ var profileName = "SomeProfile";
+ var builder = new SoilProfileBuilder(profileName, 0.0);
+ builder.Add(new SoilLayer2D
+ {
+ OuterLoop = new HashSet
+ {
+ 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
+ }
+ }
+ });
+
+ // Call
+ PipingSoilProfile soilProfile = builder.Build();
+
+ // Assert
+ Assert.AreEqual(profileName, soilProfile.Name);
+ Assert.AreEqual(1, soilProfile.Layers.Count());
+ Assert.AreEqual(1.0, soilProfile.Layers.ToArray()[0].Top);
+ Assert.AreEqual(-1.0, soilProfile.Bottom);
+ }
+
+ [Test]
+ public void Build_WithMultipleLayersOnlyOuterLoop_ReturnsProfileWithBottomAndALayers()
+ {
+ // Setup
+ var profileName = "SomeProfile";
+ var builder = new SoilProfileBuilder(profileName, 1.0);
+ builder.Add(new SoilLayer2D
+ {
+ OuterLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "10",
+ "...",
+ "...",
+ "...",
+ "...",
+ "...",
+ "...",
+ "...",
+ "1.2",
+ "4.3",
+ "..."
+ ))
+ }).Add(new SoilLayer2D
+ {
+ OuterLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "10",
+ "...",
+ "...",
+ "...",
+ "...",
+ "...",
+ "4.3",
+ "...",
+ "1.2",
+ "...",
+ "..."
+ ))
+ }).Add(new SoilLayer2D
+ {
+ OuterLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "10",
+ "...",
+ "1.2",
+ "...",
+ "...",
+ "...",
+ "4.3",
+ "...",
+ "...",
+ "...",
+ "..."
+ ))
+ });
+
+ // Call
+ PipingSoilProfile soilProfile = builder.Build();
+
+ // Assert
+ Assert.AreEqual(profileName, soilProfile.Name);
+ Assert.AreEqual(3, soilProfile.Layers.Count());
+ CollectionAssert.AreEquivalent(new[] { 2.0, 4.0, 8.0 }, soilProfile.Layers.Select(rl => rl.Top));
+ Assert.AreEqual(1.0, soilProfile.Bottom);
+ }
+
+
+ [Test]
+ public void Build_WithLayerFilledWithOtherLayer_ReturnsProfileWithBottomAndALayers()
+ {
+ // Setup
+ var profileName = "SomeProfile";
+ var builder = new SoilProfileBuilder(profileName, 2.0);
+ var loopHole = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "5",
+ ".....",
+ ".4.1.",
+ ".3.2.",
+ ".....",
+ "....."
+ ));
+ builder.Add(new SoilLayer2D
+ {
+ OuterLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine,
+ "5",
+ "2...3",
+ ".....",
+ ".....",
+ ".....",
+ "1...4"
+ )),
+ InnerLoops =
+ {
+ loopHole
+ }
+ }).Add(new SoilLayer2D
+ {
+ OuterLoop = loopHole
+ });
+
+ // Call
+ PipingSoilProfile soilProfile = builder.Build();
+
+ // Assert
+ Assert.AreEqual(profileName, soilProfile.Name);
+ Assert.AreEqual(3, soilProfile.Layers.Count());
+ CollectionAssert.AreEquivalent(new[] { 4.0, 3.0, 2.0 }, soilProfile.Layers.Select(rl => rl.Top));
+ Assert.AreEqual(0.0, soilProfile.Bottom);
+ }
+ }
+}
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Calculation/Math2DTest.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Calculation/Math2DTest.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Calculation/Math2DTest.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,186 @@
+using NUnit.Framework;
+using Wti.IO.Calculation;
+
+namespace Wti.IO.Test.Calculation
+{
+ public class Math2DTest
+ {
+ private static readonly double[][] IntersectingSegments =
+ {
+ // \/
+ // /\
+ new[]
+ {
+ 0.0,
+ 0.0,
+ 1.0,
+ 1.0,
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 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[]
+ {
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 1.0,
+ 0.0,
+ 0.0
+ }
+ };
+
+ private static readonly double[][] ParallelSegments =
+ {
+ // __
+ // __
+ new[]
+ {
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 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
+ },
+ // __ (overlap)
+ new[]
+ {
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.5,
+ 0.0,
+ 1.5,
+ 0.0
+ }
+ };
+
+ private static readonly double[][] NonIntersectingSegments =
+ {
+ // |
+ // ___
+ new[]
+ {
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.5,
+ 1.0,
+ 0.5,
+ 0.5
+ }
+ };
+
+ [Test]
+ [TestCaseSource("IntersectingSegments")]
+ public void LineSegmentIntersectionWithLineSegment_DifferentLineSegmentsWithIntersections_ReturnsPoint(double[] coordinates)
+ {
+ // Setup
+ var segments = ToSegmentCoordinatesCollections(coordinates);
+
+ // Call
+ var result = Math2D.LineSegmentIntersectionWithLineSegment(segments[0], segments[1]);
+
+ // Assert
+ CollectionAssert.AreEqual(new[]
+ {
+ coordinates[8],
+ coordinates[9]
+ }, result);
+ }
+
+ [Test]
+ [TestCaseSource("ParallelSegments")]
+ public void LineSegmentIntersectionWithLineSegment_DifferentParallelLineSegments_ReturnsNoPoint(double[] coordinates)
+ {
+ // Setup
+ var segments = ToSegmentCoordinatesCollections(coordinates);
+
+ // Call
+ var result = Math2D.LineSegmentIntersectionWithLineSegment(segments[0], segments[1]);
+
+ // Assert
+ Assert.AreEqual(0, result.Length);
+ }
+
+ [Test]
+ [TestCaseSource("NonIntersectingSegments")]
+ public void LineSegmentIntersectionWithLineSegment_DifferentLineSegmentsWithNoIntersection_ReturnsNoPoint(double[] coordinates)
+ {
+ // Setup
+ var segments = ToSegmentCoordinatesCollections(coordinates);
+
+ // Call
+ var result = Math2D.LineSegmentIntersectionWithLineSegment(segments[0], segments[1]);
+
+ // Assert
+ Assert.AreEqual(0, result.Length);
+ }
+
+ 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: src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Exceptions/CriticalFileReadExceptionTest.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Exceptions/CriticalFileReadExceptionTest.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Exceptions/CriticalFileReadExceptionTest.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,72 @@
+using System;
+
+using NUnit.Framework;
+
+using Wti.IO.Exceptions;
+
+namespace Wti.IO.Test.Exceptions
+{
+ [TestFixture]
+ public class CriticalFileReadExceptionTest
+ {
+ [Test]
+ [SetCulture("en-US")]
+ public void DefaultConstructor_ExpectedValues()
+ {
+ // Call
+ var exception = new CriticalFileReadException();
+
+ // Assert
+ Assert.IsInstanceOf(exception);
+ var expectedMessage = string.Format("Exception of type '{0}' was thrown.", exception.GetType());
+ Assert.AreEqual(expectedMessage, exception.Message);
+ CollectionAssert.IsEmpty(exception.Data);
+ Assert.IsNull(exception.HelpLink);
+ Assert.IsNull(exception.InnerException);
+ Assert.IsNull(exception.Source);
+ Assert.IsNull(exception.StackTrace);
+ Assert.IsNull(exception.TargetSite);
+ }
+
+ [Test]
+ public void MessageConstructor_ExpectedValues()
+ {
+ // Setup
+ const string messageText = "";
+
+ // Call
+ var exception = new CriticalFileReadException(messageText);
+
+ // Assert
+ Assert.IsInstanceOf(exception);
+ Assert.AreEqual(messageText, exception.Message);
+ CollectionAssert.IsEmpty(exception.Data);
+ Assert.IsNull(exception.HelpLink);
+ Assert.IsNull(exception.InnerException);
+ Assert.IsNull(exception.Source);
+ Assert.IsNull(exception.StackTrace);
+ Assert.IsNull(exception.TargetSite);
+ }
+
+ [Test]
+ public void MessageAndInnerExceptionConstructor_ExpectedValues()
+ {
+ // Setup
+ var innerException = new Exception();
+ const string messageText = "";
+
+ // Call
+ var exception = new CriticalFileReadException(messageText, innerException);
+
+ // Assert
+ Assert.IsInstanceOf(exception);
+ Assert.AreEqual(messageText, exception.Message);
+ CollectionAssert.IsEmpty(exception.Data);
+ Assert.IsNull(exception.HelpLink);
+ Assert.AreEqual(innerException, exception.InnerException);
+ Assert.IsNull(exception.Source);
+ Assert.IsNull(exception.StackTrace);
+ Assert.IsNull(exception.TargetSite);
+ }
+ }
+}
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Exceptions/LineParseExceptionTest.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Exceptions/LineParseExceptionTest.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Exceptions/LineParseExceptionTest.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,72 @@
+using System;
+
+using NUnit.Framework;
+
+using Wti.IO.Exceptions;
+
+namespace Wti.IO.Test.Exceptions
+{
+ [TestFixture]
+ public class LineParseExceptionTest
+ {
+ [Test]
+ [SetCulture("en-US")]
+ public void DefaultConstructor_ExpectedValues()
+ {
+ // Call
+ var exception = new LineParseException();
+
+ // Assert
+ Assert.IsInstanceOf(exception);
+ var expectedMessage = string.Format("Exception of type '{0}' was thrown.", exception.GetType());
+ Assert.AreEqual(expectedMessage, exception.Message);
+ CollectionAssert.IsEmpty(exception.Data);
+ Assert.IsNull(exception.HelpLink);
+ Assert.IsNull(exception.InnerException);
+ Assert.IsNull(exception.Source);
+ Assert.IsNull(exception.StackTrace);
+ Assert.IsNull(exception.TargetSite);
+ }
+
+ [Test]
+ public void MessageConstructor_ExpectedValues()
+ {
+ // Setup
+ const string messageText = "";
+
+ // Call
+ var exception = new LineParseException(messageText);
+
+ // Assert
+ Assert.IsInstanceOf(exception);
+ Assert.AreEqual(messageText, exception.Message);
+ CollectionAssert.IsEmpty(exception.Data);
+ Assert.IsNull(exception.HelpLink);
+ Assert.IsNull(exception.InnerException);
+ Assert.IsNull(exception.Source);
+ Assert.IsNull(exception.StackTrace);
+ Assert.IsNull(exception.TargetSite);
+ }
+
+ [Test]
+ public void MessageAndInnerExceptionConstructor_ExpectedValues()
+ {
+ // Setup
+ var innerException = new Exception();
+ const string messageText = "";
+
+ // Call
+ var exception = new LineParseException(messageText, innerException);
+
+ // Assert
+ Assert.IsInstanceOf(exception);
+ Assert.AreEqual(messageText, exception.Message);
+ CollectionAssert.IsEmpty(exception.Data);
+ Assert.IsNull(exception.HelpLink);
+ Assert.AreEqual(innerException, exception.InnerException);
+ Assert.IsNull(exception.Source);
+ Assert.IsNull(exception.StackTrace);
+ Assert.IsNull(exception.TargetSite);
+ }
+ }
+}
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Exceptions/PipingSoilProfileReadExceptionTest.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Exceptions/PipingSoilProfileReadExceptionTest.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Exceptions/PipingSoilProfileReadExceptionTest.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,52 @@
+using System;
+using NUnit.Framework;
+using Wti.IO.Exceptions;
+
+namespace Wti.IO.Test.Exceptions
+{
+ public class PipingSoilProfileReadExceptionTest
+ {
+ [Test]
+ public void DefaultConstructor_InnerExceptionNullAndMessageDefault()
+ {
+ // Setup
+ var expectedMessage = String.Format("Exception of type '{0}' was thrown.", typeof(PipingSoilProfileReadException).FullName);
+
+ // Call
+ var exception = new PipingSoilProfileReadException();
+
+ // Assert
+ Assert.IsNull(exception.InnerException);
+ Assert.AreEqual(expectedMessage, exception.Message);
+ }
+
+ [Test]
+ public void Constructor_WithCustomMessage_InnerExceptionNullAndMessageSetToCustom()
+ {
+ // Setup
+ var expectedMessage ="Some exception message";
+
+ // Call
+ var exception = new PipingSoilProfileReadException(expectedMessage);
+
+ // Assert
+ Assert.IsNull(exception.InnerException);
+ Assert.AreEqual(expectedMessage, exception.Message);
+ }
+
+ [Test]
+ public void Constructor_WithCustomMessageAndInnerException_InnerExceptionSetAndMessageSetToCustom()
+ {
+ // Setup
+ var expectedMessage = "Some exception message";
+ var expectedInnerException = new Exception();
+
+ // Call
+ var exception = new PipingSoilProfileReadException(expectedMessage, expectedInnerException);
+
+ // Assert
+ Assert.AreSame(expectedInnerException, exception.InnerException);
+ Assert.AreEqual(expectedMessage, exception.Message);
+ }
+ }
+}
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSoilLayerReaderTest.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSoilLayerReaderTest.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSoilLayerReaderTest.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,184 @@
+using System.Collections.Generic;
+using System.Xml;
+using NUnit.Framework;
+using Wti.Data;
+
+namespace Wti.IO.Test
+{
+ public class PipingSoilLayerReaderTest
+ {
+ [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[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[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 xmlDoc = GetBytes("00.11.1");
+ var reader = new PipingSoilLayer2DReader(xmlDoc);
+
+ // Call
+ var result = reader.Read();
+
+ // Assert
+ Assert.NotNull(result);
+ CollectionAssert.AreEqual(new HashSet {new Point3D{X=0,Y=0.1,Z=1.1}}, result.OuterLoop);
+ }
+
+ [Test]
+ public void Read_XmlDocumentPointInInnerLoop_ReturnsLayerWithInnerLoopWithPoint()
+ {
+ // Setup
+ var xmlDoc = GetBytes("00.11.1");
+ var reader = new PipingSoilLayer2DReader(xmlDoc);
+
+ // Call
+ var result = reader.Read();
+
+ // Assert
+ Assert.NotNull(result);
+ Assert.AreEqual(1, result.InnerLoops.Count);
+ CollectionAssert.AreEqual(new HashSet { new Point3D { X = 0, Y = 0.1, Z = 1.1 } }, result.InnerLoops[0]);
+ }
+
+ [Test]
+ public void Read_XmlDocumentPointsInOuterLoop_ReturnsLayerWithOuterLoopWithPoints()
+ {
+ // Setup
+ var xmlDoc = GetBytes("00.11.110.11.1");
+ var reader = new PipingSoilLayer2DReader(xmlDoc);
+
+ // Call
+ var result = reader.Read();
+
+ // Assert
+ Assert.NotNull(result);
+ CollectionAssert.AreEqual(new HashSet { new Point3D { X = 0, Y = 0.1, Z = 1.1 }, new Point3D { X = 1.0, Y = 0.1, Z = 1.1 } }, result.OuterLoop);
+ }
+
+ [Test]
+ public void Read_XmlDocumentPointsInInnerLoop_ReturnsLayerWithInnerLoopWithPoints()
+ {
+ // Setup
+ var xmlDoc = GetBytes("00.11.110.11.1");
+ var reader = new PipingSoilLayer2DReader(xmlDoc);
+
+ // Call
+ var result = reader.Read();
+
+ // Assert
+ Assert.NotNull(result);
+ Assert.AreEqual(1, result.InnerLoops.Count);
+ CollectionAssert.AreEqual(new HashSet { new Point3D { X = 0, Y = 0.1, Z = 1.1 }, new Point3D { X = 1.0, Y = 0.1, Z = 1.1 } }, result.InnerLoops[0]);
+ }
+
+ static byte[] GetBytes(string str)
+ {
+ byte[] bytes = new byte[str.Length * sizeof(char)];
+ System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
+ return bytes;
+ }
+ }
+}
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSoilProfileReaderTest.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSoilProfileReaderTest.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSoilProfileReaderTest.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,132 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using DelftTools.TestUtils;
+using log4net.Core;
+using NUnit.Framework;
+using Wti.Data;
+using Wti.IO.Calculation;
+using Wti.IO.Exceptions;
+using Wti.IO.Properties;
+
+namespace Wti.IO.Test
+{
+ public class PipingSoilProfileReaderTest
+ {
+
+ private readonly string testDataPath = TestHelper.GetTestDataPath(TestDataPath.Plugins.Wti.WtiIOPath, "PipingSoilProfilesReader");
+
+ [Test]
+ public void Constructor_CorrectPath_ReturnsNewInstance()
+ {
+ // Setup
+ var testFile = "empty.soil";
+
+ // Call
+ var pipingSoilProfilesReader = new PipingSoilProfileReader(Path.Combine(testDataPath, testFile));
+
+ // Assert
+ Assert.NotNull(pipingSoilProfilesReader);
+ }
+
+ [Test]
+ public void Constructor_NonExistingPath_ThrowsFileNotFoundException()
+ {
+ // Setup
+ var testFile = Path.Combine(testDataPath, "none.soil");
+
+ // Call
+ TestDelegate test = () => new PipingSoilProfileReader(testFile);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual(String.Format(Resources.Error_File_0_does_not_exist, testFile), exception.Message);
+ }
+
+ [Test]
+ [TestCase(null)]
+ [TestCase("")]
+ public void ReadSoilProfiles_NullOrEmpty_ThrowsArgumentException(string fileName)
+ {
+ // Call
+ TestDelegate test = () => new PipingSoilProfileReader(fileName);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual(Resources.Error_PathMustBeSpecified, exception.Message);
+ }
+
+ [Test]
+ public void ReadSoilProfiles_IncorrectFormatFile_ThrowsSqLiteException()
+ {
+ // Setup
+ var dbName = "text";
+ var testFile = Path.Combine(testDataPath, dbName + ".txt");
+ var pipingSoilProfilesReader = new PipingSoilProfileReader(testFile);
+
+ // Call
+ TestDelegate test = () => pipingSoilProfilesReader.Read();
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual(String.Format(Resources.Error_SoilProfileReadFromDatabase, dbName), exception.Message);
+ }
+
+ [Test]
+ [SetCulture("nl-NL")]
+ public void ReadSoilProfiles_NLCompleteDatabase_Returns2ProfilesWithLayersAndGeometries()
+ {
+ ReadSoilProfiles_CompleteDatabase_Returns2ProfilesWithLayersAndGeometries();
+ }
+
+ [Test]
+ [SetCulture("en-US")]
+ public void ReadSoilProfiles_ENCompleteDatabase_Returns2ProfilesWithLayersAndGeometries()
+ {
+ ReadSoilProfiles_CompleteDatabase_Returns2ProfilesWithLayersAndGeometries();
+ }
+
+ private void ReadSoilProfiles_CompleteDatabase_Returns2ProfilesWithLayersAndGeometries()
+ {
+ // Setup
+ var testFile = "complete.soil";
+ var pipingSoilProfilesReader = new PipingSoilProfileReader(Path.Combine(testDataPath, testFile));
+
+ // Call
+ PipingSoilProfile[] result = pipingSoilProfilesReader.Read().ToArray();
+
+ // Assert
+ Assert.AreEqual(2, result.Length);
+ var firstProfile = result.SingleOrDefault(psp => psp.Name == "10Y_005_STBI");
+ Assert.NotNull(firstProfile);
+
+ Assert.AreEqual(-10, firstProfile.Bottom);
+ Assert.AreEqual(6, firstProfile.Layers.Count());
+ var expected = new[]
+ {
+ -3.5,
+ -1.2,
+ 0.63,
+ 1.088434916,
+ 1.947578092,
+ 2.473341176
+ };
+ CollectionAssert.AllItemsAreUnique(firstProfile.Layers.Select(l => l.Top));
+ Assert.AreEqual(6, firstProfile.Layers.Count(l => expected.Contains(l.Top, new DoubleComparer())));
+ }
+ }
+
+ internal class DoubleComparer : IEqualityComparer {
+ public bool Equals(double x, double y)
+ {
+ return Math.Abs(x - y) < Math2D.EpsilonForComparisons;
+ }
+
+ public int GetHashCode(double obj)
+ {
+ return obj.GetHashCode();
+ }
+ }
+}
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSurfaceLinesCsvReaderTest.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSurfaceLinesCsvReaderTest.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSurfaceLinesCsvReaderTest.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,569 @@
+using System;
+using System.IO;
+using System.Linq;
+
+using DelftTools.TestUtils;
+
+using NUnit.Framework;
+
+using Wti.IO.Exceptions;
+
+using IOResources = Wti.IO.Properties.Resources;
+
+namespace Wti.IO.Test
+{
+ [TestFixture]
+ public class PipingSurfaceLinesCsvReaderTest
+ {
+ private readonly string testDataPath = TestHelper.GetTestDataPath(TestDataPath.Plugins.Wti.WtiIOPath, "PipingSurfaceLinesCsvReader" + Path.DirectorySeparatorChar);
+
+ [Test]
+ [TestCase("")]
+ [TestCase(null)]
+ [TestCase(" ")]
+ public void ParameterdConstructor_InvalidStringArgument_ThrowsArgumentException(string path)
+ {
+ // Call
+ TestDelegate call = () => new PipingSurfaceLinesCsvReader(path);
+
+ // Assert
+ var exception = Assert.Throws(call);
+ Assert.AreEqual(IOResources.Error_PathMustBeSpecified, exception.Message);
+ }
+
+ [Test]
+ public void ParameterdConstructor_InvalidPathCharactersInPath_ThrowsArgumentException()
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, "TwoValidSurfaceLines.csv");
+
+ var invalidCharacters = Path.GetInvalidPathChars();
+
+ var corruptPath = path.Replace('V', invalidCharacters[0]);
+
+ // Call
+ TestDelegate call = () => new PipingSurfaceLinesCsvReader(corruptPath);
+
+ // Assert
+ var exception = Assert.Throws(call);
+ var expectedMessage = String.Format(IOResources.Error_PathCannotContainCharacters_0_,
+ String.Join(", ", Path.GetInvalidFileNameChars()));
+ Assert.AreEqual(expectedMessage, exception.Message);
+ }
+
+ [Test]
+ public void ParametersConstructor_PathToFolder_ThrowsArgumentException()
+ {
+ // Call
+ TestDelegate call = () => new PipingSurfaceLinesCsvReader(testDataPath);
+
+ // Assert
+ var exception = Assert.Throws(call);
+ Assert.AreEqual(IOResources.Error_PathMustNotPointToFolder, exception.Message);
+ }
+
+ [Test]
+ public void ParameterdConstructor_AnyPath_ExpectedValues()
+ {
+ // Setup
+ const string fakeFilePath = @"I\Dont\Really\Exist";
+
+ // Call
+ using (var reader = new PipingSurfaceLinesCsvReader(fakeFilePath))
+ {
+ // Assert
+ Assert.IsInstanceOf(reader);
+ }
+ }
+
+ [Test]
+ public void GetSurfaceLinesCount_OpenedValidFileWithHeaderAndTwoSurfaceLines_ReturnNumberOfSurfaceLines()
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, "TwoValidSurfaceLines.csv");
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ int linesCount = reader.GetSurfaceLinesCount();
+
+ // Assert
+ Assert.AreEqual(2, linesCount);
+ }
+ }
+
+ [Test]
+ public void GetSurfaceLinesCount_OpenedValidFileWithHeaderAndNoSurfaceLines_ReturnZero()
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, "ValidFileWithoutSurfaceLines.csv");
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ int linesCount = reader.GetSurfaceLinesCount();
+
+ // Assert
+ Assert.AreEqual(0, linesCount);
+ }
+ }
+
+ [Test]
+ public void GetSurfaceLinesCount_FileCannotBeFound_ThrowCriticalFileReadException()
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, "I_do_not_exist.csv");
+
+ // Precondition
+ Assert.IsFalse(File.Exists(path));
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ TestDelegate call = () => reader.GetSurfaceLinesCount();
+
+ // Assert
+ var exception = Assert.Throws(call);
+ var expectedMessage = string.Format(IOResources.Error_File_0_does_not_exist, path);
+ Assert.AreEqual(expectedMessage, exception.Message);
+ Assert.IsInstanceOf(exception.InnerException);
+ }
+ }
+
+ [Test]
+ public void GetSurfaceLinesCount_DirectoryCannotBeFound_ThrowCriticalFileReadException()
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, "..", "this_folder_does_not_exist", "I_do_not_exist.csv");
+
+ // Precondition
+ Assert.IsFalse(File.Exists(path));
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ TestDelegate call = () => reader.GetSurfaceLinesCount();
+
+ // Assert
+ var exception = Assert.Throws(call);
+ var expectedMessage = string.Format(IOResources.Error_Directory_in_path_0_missing, path);
+ Assert.AreEqual(expectedMessage, exception.Message);
+ Assert.IsInstanceOf(exception.InnerException);
+ }
+ }
+
+ [Test]
+ public void GetSurfaceLinesCount_EmptyFile_ThrowCriticalFileReadException()
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, "empty.csv");
+
+ // Precondition
+ Assert.IsTrue(File.Exists(path));
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ TestDelegate call = () => reader.GetSurfaceLinesCount();
+
+ // Assert
+ var exception = Assert.Throws(call);
+ var expectedMessage = string.Format(IOResources.Error_File_0_empty, path);
+ Assert.AreEqual(expectedMessage, exception.Message);
+ }
+ }
+
+ [Test]
+ public void GetSurfaceLinesCount_InvalidHeader1_ThrowCriticalFileReadException()
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, "InvalidHeader_UnsupportedId.csv");
+
+ // Precondition
+ Assert.IsTrue(File.Exists(path));
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ TestDelegate call = () => reader.GetSurfaceLinesCount();
+
+ // Assert
+ var exception = Assert.Throws(call);
+ var expectedMessage = string.Format(IOResources.PipingSurfaceLinesCsvReader_File_0_invalid_header, path);
+ Assert.AreEqual(expectedMessage, exception.Message);
+ }
+ }
+
+ [Test]
+ [TestCase("X")]
+ [TestCase("Y")]
+ [TestCase("Z")]
+ public void GetSurfaceLinesCount_InvalidHeader2_ThrowCriticalFileReadException(string missingVariableName)
+ {
+ // Setup
+ var filename = string.Format("InvalidHeader_Lacks{0}1.csv", missingVariableName);
+ string path = Path.Combine(testDataPath, filename);
+
+ // Precondition
+ Assert.IsTrue(File.Exists(path));
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ TestDelegate call = () => reader.GetSurfaceLinesCount();
+
+ // Assert
+ var exception = Assert.Throws(call);
+ var expectedMessage = string.Format("Het bestand op '{0}' is niet geschikt om dwarsdoorsneden uit te lezen (Verwachte header: locationid;X1;Y1;Z1).", path);
+ Assert.AreEqual(expectedMessage, exception.Message);
+ }
+ }
+
+ [Test]
+ [SetCulture("nl-NL")]
+ public void ReadLine_OpenedValidFileWithHeaderAndTwoSurfaceLinesWithCultureNL_ReturnCreatedSurfaceLine()
+ {
+ DoReadLine_OpenedValidFileWithHeaderAndTwoSurfaceLines_ReturnCreatedSurfaceLine();
+ }
+
+ [Test]
+ [SetCulture("en-US")]
+ public void ReadLine_OpenedValidFileWithHeaderAndTwoSurfaceLinesWithCultureEN_ReturnCreatedSurfaceLine()
+ {
+ DoReadLine_OpenedValidFileWithHeaderAndTwoSurfaceLines_ReturnCreatedSurfaceLine();
+ }
+
+ [Test]
+ public void ReadLine_OpenedValidFileWithoutHeaderAndTwoSurfaceLinesWhileAtTheEndOfFile_ReturnNull()
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, "TwoValidSurfaceLines.csv");
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ int surfaceLinesCount = reader.GetSurfaceLinesCount();
+ for (int i = 0; i < surfaceLinesCount; i++)
+ {
+ var pipingSurfaceLine = reader.ReadLine();
+ Assert.IsNotInstanceOf(pipingSurfaceLine,
+ "Fail Fast: Disposal logic required to be implemented in test.");
+ Assert.IsNotNull(pipingSurfaceLine);
+ }
+
+ // Call
+ var result = reader.ReadLine();
+
+ // Assert
+ Assert.IsNull(result);
+ }
+ }
+
+ [Test]
+ public void ReadLine_FileCannotBeFound_ThrowCriticalFileReadException()
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, "I_do_not_exist.csv");
+
+ // Precondition
+ Assert.IsFalse(File.Exists(path));
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ TestDelegate call = () => reader.ReadLine();
+
+ // Assert
+ var exception = Assert.Throws(call);
+ var expectedMessage = string.Format(IOResources.Error_File_0_does_not_exist, path);
+ Assert.AreEqual(expectedMessage, exception.Message);
+ Assert.IsInstanceOf(exception.InnerException);
+ }
+ }
+
+ [Test]
+ public void ReadLine_DirectoryCannotBeFound_ThrowCriticalFileReadException()
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, "..", "this_folder_does_not_exist", "I_do_not_exist.csv");
+
+ // Precondition
+ Assert.IsFalse(File.Exists(path));
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ TestDelegate call = () => reader.ReadLine();
+
+ // Assert
+ var exception = Assert.Throws(call);
+ var expectedMessage = string.Format(IOResources.Error_Directory_in_path_0_missing, path);
+ Assert.AreEqual(expectedMessage, exception.Message);
+ Assert.IsInstanceOf(exception.InnerException);
+ }
+ }
+
+ [Test]
+ public void ReadLine_EmptyFile_ThrowCriticalFileReadException()
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, "empty.csv");
+
+ // Precondition
+ Assert.IsTrue(File.Exists(path));
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ TestDelegate call = () => reader.ReadLine();
+
+ // Assert
+ var exception = Assert.Throws(call);
+ var expectedMessage = string.Format(IOResources.Error_File_0_empty, path);
+ Assert.AreEqual(expectedMessage, exception.Message);
+ }
+ }
+
+ [Test]
+ public void ReadLine_InvalidHeader1_ThrowCriticalFileReadException()
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, "InvalidHeader_UnsupportedId.csv");
+
+ // Precondition
+ Assert.IsTrue(File.Exists(path));
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ TestDelegate call = () => reader.ReadLine();
+
+ // Assert
+ var exception = Assert.Throws(call);
+ var expectedMessage = string.Format(IOResources.PipingSurfaceLinesCsvReader_File_0_invalid_header, path);
+ Assert.AreEqual(expectedMessage, exception.Message);
+ }
+ }
+
+ [Test]
+ [TestCase("X")]
+ [TestCase("Y")]
+ [TestCase("Z")]
+ public void ReadLine_InvalidHeader2_ThrowCriticalFileReadException(string missingVariableName)
+ {
+ // Setup
+ var filename = string.Format("InvalidHeader_Lacks{0}1.csv", missingVariableName);
+ string path = Path.Combine(testDataPath, filename);
+
+ // Precondition
+ Assert.IsTrue(File.Exists(path));
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ TestDelegate call = () => reader.ReadLine();
+
+ // Assert
+ var exception = Assert.Throws(call);
+ var expectedMessage = string.Format("Het bestand op '{0}' is niet geschikt om dwarsdoorsneden uit te lezen (Verwachte header: locationid;X1;Y1;Z1).", path);
+ Assert.AreEqual(expectedMessage, exception.Message);
+ }
+ }
+
+ [Test]
+ [TestCase("X")]
+ [TestCase("Y")]
+ [TestCase("Z")]
+ public void ReadLine_FileHasInvalidCoordinate_ThrowLineParseException(string malformattedVariableName)
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, string.Format("InvalidRow_{0}NotAValidNumber.csv", malformattedVariableName));
+
+ // Precondition
+ Assert.IsTrue(File.Exists(path));
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ TestDelegate call = () => reader.ReadLine();
+
+ // Assert
+ var exception = Assert.Throws(call);
+ var expectedMessage = string.Format(IOResources.Error_File_0_has_not_double_Line_1_, path, 2);
+ Assert.AreEqual(expectedMessage, exception.Message);
+ Assert.IsInstanceOf(exception.InnerException);
+ }
+ }
+
+ [Test]
+ [TestCase("XOver")]
+ [TestCase("YOver")]
+ [TestCase("ZOver")]
+ [TestCase("XUnder")]
+ [TestCase("YUnder")]
+ [TestCase("ZUnder")]
+ public void ReadLine_FileHasCoordinateCausingOverOrUnderflow_ThrowLineParseException(string malformattedVariableName)
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, string.Format("InvalidRow_{0}flowingNumber.csv", malformattedVariableName));
+
+ // Precondition
+ Assert.IsTrue(File.Exists(path));
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ TestDelegate call = () => reader.ReadLine();
+
+ // Assert
+ var exception = Assert.Throws(call);
+ var expectedMessage = string.Format(IOResources.Error_File_0_Parsing_causes_overflow_Line_1_, path, 2);
+ Assert.AreEqual(expectedMessage, exception.Message);
+ Assert.IsInstanceOf(exception.InnerException);
+ }
+ }
+
+ [Test]
+ public void ReadLine_FileLacksIds_ThrowLineParseException()
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, "TwoInvalidRows_LacksId.csv");
+
+ // Precondition
+ Assert.IsTrue(File.Exists(path));
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ TestDelegate call = () => reader.ReadLine();
+
+ // Assert
+ // 1st line has no text at all:
+ var exception = Assert.Throws(call);
+ var expectedMessage = string.Format(IOResources.PipingSurfaceLinesCsvReader_ReadLine_File_0_Line_1_NoId, path, 2);
+ Assert.AreEqual(expectedMessage, exception.Message);
+
+ // 2nd line has only whitespace text:
+ expectedMessage = string.Format(IOResources.PipingSurfaceLinesCsvReader_ReadLine_File_0_Line_1_NoId, path, 3);
+ exception = Assert.Throws(call);
+ Assert.AreEqual(expectedMessage, exception.Message);
+ }
+ }
+
+ [Test]
+ public void ReadLine_IncorrectValueSeparator_ThrowLineParseException()
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, "InvalidRow_IncorrectValueSeparator.csv");
+
+ // Precondition
+ Assert.IsTrue(File.Exists(path));
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ TestDelegate call = () => reader.ReadLine();
+
+ // Assert
+ var exception = Assert.Throws(call);
+ var expectedMessage = string.Format(IOResources.PipingSurfaceLinesCsvReader_ReadLine_File_0_Line_1_Lacks_separator_2_, path, 2, ';');
+ Assert.AreEqual(expectedMessage, exception.Message);
+ }
+ }
+
+ [Test]
+ public void ReadLine_FileLacksCoordinateValues_ThrowLineParseException()
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, "InvalidRow_LacksCoordinateValues.csv");
+
+ // Precondition
+ Assert.IsTrue(File.Exists(path));
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ TestDelegate call = () => reader.ReadLine();
+
+ // Assert
+ var exception = Assert.Throws(call);
+ var expectedMessage = string.Format(IOResources.PipingSurfaceLinesCsvReader_ReadLine_File_0_Line_1_Lacks_separator_2_, path, 2, ';');
+ Assert.AreEqual(expectedMessage, exception.Message);
+ }
+ }
+
+ [Test]
+ public void ReadLine_FileHasIncompleteCoordinateTriplets_ThrowLineParseException()
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, "TwoInvalidRows_IncompleteCoordinateTriplets.csv");
+
+ // Precondition
+ Assert.IsTrue(File.Exists(path));
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ TestDelegate call = () => reader.ReadLine();
+
+ // Assert
+ // 1st row lacks 1 coordinate value:
+ var exception = Assert.Throws(call);
+ var expectedMessage = string.Format(IOResources.PipingSurfaceLinesCsvReader_ReadLine_File_0_Line_1_Lacks_values_for_coordinate_triplet, path, 2);
+ Assert.AreEqual(expectedMessage, exception.Message);
+
+ // 2nd row lacks 2 coordinate values:
+ exception = Assert.Throws(call);
+ expectedMessage = string.Format(IOResources.PipingSurfaceLinesCsvReader_ReadLine_File_0_Line_1_Lacks_values_for_coordinate_triplet, path, 3);
+ Assert.AreEqual(expectedMessage, exception.Message);
+ }
+ }
+
+ private void DoReadLine_OpenedValidFileWithHeaderAndTwoSurfaceLines_ReturnCreatedSurfaceLine()
+ {
+ // Setup
+ string path = Path.Combine(testDataPath, "TwoValidSurfaceLines.csv");
+
+ // Precondition:
+ Assert.IsTrue(File.Exists(path));
+
+ using (var reader = new PipingSurfaceLinesCsvReader(path))
+ {
+ // Call
+ var surfaceLine1 = reader.ReadLine();
+ var surfaceLine2 = reader.ReadLine();
+
+ // Assert
+
+ #region 1st surfaceline
+
+ Assert.AreEqual("Rotterdam1", surfaceLine1.Name);
+ Assert.AreEqual(8, surfaceLine1.Points.Count());
+ Assert.AreEqual(94263.0026213, surfaceLine1.StartingWorldPoint.X);
+ Assert.AreEqual(427776.654093, surfaceLine1.StartingWorldPoint.Y);
+ Assert.AreEqual(-1.02, surfaceLine1.StartingWorldPoint.Z);
+ Assert.AreEqual(94331.1767309, surfaceLine1.EndingWorldPoint.X);
+ Assert.AreEqual(427960.112661, surfaceLine1.EndingWorldPoint.Y);
+ Assert.AreEqual(1.44, surfaceLine1.EndingWorldPoint.Z);
+ Assert.AreEqual(surfaceLine1.StartingWorldPoint, surfaceLine1.Points.First());
+ Assert.AreEqual(surfaceLine1.EndingWorldPoint, surfaceLine1.Points.Last());
+
+ #endregion
+
+ #region 2nd surfaceline
+
+ Assert.AreEqual("ArtificalLocal", surfaceLine2.Name);
+ Assert.AreEqual(3, surfaceLine2.Points.Count());
+ Assert.AreEqual(2.3, surfaceLine2.StartingWorldPoint.X);
+ Assert.AreEqual(0, surfaceLine2.StartingWorldPoint.Y);
+ Assert.AreEqual(1, surfaceLine2.StartingWorldPoint.Z);
+ Assert.AreEqual(4.4, surfaceLine2.EndingWorldPoint.X);
+ Assert.AreEqual(0, surfaceLine2.EndingWorldPoint.Y);
+ Assert.AreEqual(1.1, surfaceLine2.EndingWorldPoint.Z);
+ Assert.AreEqual(surfaceLine2.StartingWorldPoint, surfaceLine2.Points.First());
+ Assert.AreEqual(surfaceLine2.EndingWorldPoint, surfaceLine2.Points.Last());
+
+ #endregion
+ }
+ }
+ }
+}
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Properties/AssemblyInfo.cs
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Properties/AssemblyInfo.cs (revision 0)
+++ src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Properties/AssemblyInfo.cs (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,39 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("Wti.IO.Test")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("Wti.IO.Test")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("fdd7359e-075c-49b6-b792-056e46a28a57")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Wti.IO.Test.csproj
===================================================================
diff -u
--- src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Wti.IO.Test.csproj (revision 0)
+++ src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Wti.IO.Test.csproj (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -0,0 +1,84 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {E4B0E068-F1A3-47BA-965F-0EC1E78E530A}
+ Library
+ Properties
+ Wti.IO.Test
+ Wti.IO.Test
+ v4.0
+ 512
+
+
+ true
+ bin\Debug\
+ 4
+ DEBUG;TRACE
+ full
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+ bin\Release\
+ 4
+ TRACE
+ true
+ pdbonly
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+
+ ..\..\..\..\..\..\lib\log4net.dll
+
+
+ ..\..\..\..\..\..\lib\nunit.framework.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {ce994cc9-6f6a-48ac-b4be-02c30a21f4db}
+ Wti.Data
+
+
+ {EFA25023-CF6A-4FF7-8C42-B24D7F9509E1}
+ DelftTools.TestUtils
+
+
+ {35b87b7a-7f50-4139-b563-589ee522b1ed}
+ Wti.IO
+
+
+ {955E574D-67CE-4347-AA6B-7DF8A04ED754}
+ Wti.Data.TestUtil
+
+
+
+
+
\ No newline at end of file
Index: src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/Ringtoets.Piping.Plugin.Test.csproj
===================================================================
diff -u -r1450c6e12cbd3358c66a9efec22203c988af78ed -rb3fa1606efddd3bed496c2844a495ff92347fa44
--- src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/Ringtoets.Piping.Plugin.Test.csproj (.../Ringtoets.Piping.Plugin.Test.csproj) (revision 1450c6e12cbd3358c66a9efec22203c988af78ed)
+++ src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/Ringtoets.Piping.Plugin.Test.csproj (.../Ringtoets.Piping.Plugin.Test.csproj) (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -82,10 +82,6 @@
{ce994cc9-6f6a-48ac-b4be-02c30a21f4db}
Wti.Data
-
- {35b87b7a-7f50-4139-b563-589ee522b1ed}
- Wti.IO
-
{efa25023-cf6a-4ff7-8c42-b24d7f9509e1}
DelftTools.TestUtils
@@ -94,6 +90,10 @@
{7cd038e1-e111-4969-aced-22c5bd2974e1}
Wti.Forms
+
+ {35b87b7a-7f50-4139-b563-589ee522b1ed}
+ Wti.IO
+
{1d3d58b6-ef7e-401e-92a0-104067d222ee}
Ringtoets.Piping.Plugin
Index: src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.Service.Test/Ringtoets.Piping.Service.Test.csproj
===================================================================
diff -u -r53a2d662c6893cb7e63dc150aaab6c2b3e9db769 -rb3fa1606efddd3bed496c2844a495ff92347fa44
--- src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.Service.Test/Ringtoets.Piping.Service.Test.csproj (.../Ringtoets.Piping.Service.Test.csproj) (revision 53a2d662c6893cb7e63dc150aaab6c2b3e9db769)
+++ src/Plugins/Ringtoets/Piping/test/Ringtoets.Piping.Service.Test/Ringtoets.Piping.Service.Test.csproj (.../Ringtoets.Piping.Service.Test.csproj) (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -77,7 +77,7 @@
{CE994CC9-6F6A-48AC-B4BE-02C30A21F4DB}
Wti.Data
-
+
{7cd038e1-e111-4969-aced-22c5bd2974e1}
Wti.Forms
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `src/Plugins/Wti/Wti.IO/Builders/SoilLayer2D.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `src/Plugins/Wti/Wti.IO/Builders/SoilLayer2DConversionException.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `src/Plugins/Wti/Wti.IO/Builders/SoilProfileBuilder.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `src/Plugins/Wti/Wti.IO/Calculation/Math2D.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `src/Plugins/Wti/Wti.IO/Exceptions/CriticalFileReadException.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `src/Plugins/Wti/Wti.IO/Exceptions/LineParseException.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `src/Plugins/Wti/Wti.IO/Exceptions/PipingSoilProfileReadException.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `src/Plugins/Wti/Wti.IO/PipingSoilLayer2DReader.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `src/Plugins/Wti/Wti.IO/PipingSoilProfileReader.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `src/Plugins/Wti/Wti.IO/PipingSurfaceLinesCsvReader.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `src/Plugins/Wti/Wti.IO/Properties/AssemblyInfo.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `src/Plugins/Wti/Wti.IO/Properties/Resources.Designer.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `src/Plugins/Wti/Wti.IO/Properties/Resources.resx'.
Fisheye: No comparison available. Pass `N' to diff?
Index: src/Plugins/Wti/Wti.IO/SQLite.Interop.dll
===================================================================
diff -u -re5c186677d0ef8697eb04ea571b7c4ef8268183c -rb3fa1606efddd3bed496c2844a495ff92347fa44
Binary files differ
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `src/Plugins/Wti/Wti.IO/Wti.IO.csproj'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `src/Plugins/Wti/Wti.IO/packages.config'.
Fisheye: No comparison available. Pass `N' to diff?
Index: src/documentation/UML/UML.csproj
===================================================================
diff -u -r53a2d662c6893cb7e63dc150aaab6c2b3e9db769 -rb3fa1606efddd3bed496c2844a495ff92347fa44
--- src/documentation/UML/UML.csproj (.../UML.csproj) (revision 53a2d662c6893cb7e63dc150aaab6c2b3e9db769)
+++ src/documentation/UML/UML.csproj (.../UML.csproj) (revision b3fa1606efddd3bed496c2844a495ff92347fa44)
@@ -70,7 +70,7 @@
{ce994cc9-6f6a-48ac-b4be-02c30a21f4db}
Wti.Data
-
+
{7cd038e1-e111-4969-aced-22c5bd2974e1}
Wti.Forms
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `test/Plugins/Wti/Wti.IO.Test/Builders/SoilLayer2DTest.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `test/Plugins/Wti/Wti.IO.Test/Builders/SoilProfileBuilderTest.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `test/Plugins/Wti/Wti.IO.Test/Calculation/Math2DTest.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `test/Plugins/Wti/Wti.IO.Test/Exceptions/CriticalFileReadExceptionTest.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `test/Plugins/Wti/Wti.IO.Test/Exceptions/LineParseExceptionTest.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `test/Plugins/Wti/Wti.IO.Test/Exceptions/PipingSoilProfileReadExceptionTest.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `test/Plugins/Wti/Wti.IO.Test/PipingSoilLayerReaderTest.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `test/Plugins/Wti/Wti.IO.Test/PipingSoilProfileReaderTest.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `test/Plugins/Wti/Wti.IO.Test/PipingSurfaceLinesCsvReaderTest.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `test/Plugins/Wti/Wti.IO.Test/Properties/AssemblyInfo.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag b3fa1606efddd3bed496c2844a495ff92347fa44 refers to a dead (removed) revision in file `test/Plugins/Wti/Wti.IO.Test/Wti.IO.Test.csproj'.
Fisheye: No comparison available. Pass `N' to diff?