Index: Ringtoets/Common/src/Ringtoets.Common.IO/Properties/Resources.Designer.cs =================================================================== diff -u -re40a14c4d5b76ae6e2d9c13407e231b8929f800a -r7733b872eca9cfa426bc0979f25ae3f7e2f78453 --- Ringtoets/Common/src/Ringtoets.Common.IO/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision e40a14c4d5b76ae6e2d9c13407e231b8929f800a) +++ Ringtoets/Common/src/Ringtoets.Common.IO/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 7733b872eca9cfa426bc0979f25ae3f7e2f78453) @@ -1190,6 +1190,15 @@ } /// + /// Looks up a localized string similar to De segmenten van de geometrie van de laag vormen geen lus.. + /// + public static string Loop_contains_disconnected_segments { + get { + return ResourceManager.GetString("Loop_contains_disconnected_segments", resourceCulture); + } + } + + /// /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8"?><!-- ///Copyright (C) Stichting Deltares 2017. All rights reserved. /// @@ -1545,14 +1554,14 @@ } /// - /// Looks up a localized string similar to BEGIN TRANSACTION; - ///CREATE TABLE "TimeIntegrationSettings" ( - /// "LocationID" INTEGER NOT NULL, - /// "CalculationTypeID" INTEGER NOT NULL, - /// "TimeIntegrationSchemeID" INTEGER NOT NULL, - /// CONSTRAINT timeintegrationsettings_pk PRIMARY KEY ("LocationID", "CalculationTypeID"), - /// CONSTRAINT calculationtypes_timeintegrationsettings_fk FOREIGN KEY ("CalculationTypeID") REFERENCES CalculationTypes ("CalculationTypeID") ON DELETE NO ACTION ON UPDATE NO ACTION - ///); + /// Looks up a localized string similar to BEGIN TRANSACTION; + ///CREATE TABLE "TimeIntegrationSettings" ( + /// "LocationID" INTEGER NOT NULL, + /// "CalculationTypeID" INTEGER NOT NULL, + /// "TimeIntegrationSchemeID" INTEGER NOT NULL, + /// CONSTRAINT timeintegrationsettings_pk PRIMARY KEY ("LocationID", "CalculationTypeID"), + /// CONSTRAINT calculationtypes_timeintegrationsettings_fk FOREIGN KEY ("CalculationTypeID") REFERENCES CalculationTypes ("CalculationTypeID") ON DELETE NO ACTION ON UPDATE NO ACTION + ///); ///CREATE TABLE "Numeri [rest of string was truncated]";. /// public static string settings_schema { @@ -1649,15 +1658,6 @@ } /// - /// Looks up a localized string similar to De segmenten van de geometrie van de laag vormen geen lus.. - /// - public static string SoilLayer2D_CheckValidLoop_Loop_contains_disconnected_segments { - get { - return ResourceManager.GetString("SoilLayer2D_CheckValidLoop_Loop_contains_disconnected_segments", resourceCulture); - } - } - - /// /// Looks up a localized string similar to Coördinaat van een punt bevat ongeldige waarde.. /// public static string SoilLayer2DGeometryReader_Could_not_parse_point_location { Index: Ringtoets/Common/src/Ringtoets.Common.IO/Properties/Resources.resx =================================================================== diff -u -re40a14c4d5b76ae6e2d9c13407e231b8929f800a -r7733b872eca9cfa426bc0979f25ae3f7e2f78453 --- Ringtoets/Common/src/Ringtoets.Common.IO/Properties/Resources.resx (.../Resources.resx) (revision e40a14c4d5b76ae6e2d9c13407e231b8929f800a) +++ Ringtoets/Common/src/Ringtoets.Common.IO/Properties/Resources.resx (.../Resources.resx) (revision 7733b872eca9cfa426bc0979f25ae3f7e2f78453) @@ -821,7 +821,7 @@ Ondergrondschematisatie bevat geen geldige waarde in kolom '{0}'. - + De segmenten van de geometrie van de laag vormen geen lus. Index: Ringtoets/Common/src/Ringtoets.Common.IO/SoilProfile/SoilLayer2D.cs =================================================================== diff -u -r9d56d6d370c1a05eebb62ca4cc58aa9036c27bf1 -r7733b872eca9cfa426bc0979f25ae3f7e2f78453 --- Ringtoets/Common/src/Ringtoets.Common.IO/SoilProfile/SoilLayer2D.cs (.../SoilLayer2D.cs) (revision 9d56d6d370c1a05eebb62ca4cc58aa9036c27bf1) +++ Ringtoets/Common/src/Ringtoets.Common.IO/SoilProfile/SoilLayer2D.cs (.../SoilLayer2D.cs) (revision 7733b872eca9cfa426bc0979f25ae3f7e2f78453) @@ -96,16 +96,16 @@ } /// - /// Validates that forms a loop. + /// Validates that forms a loop. /// - /// The inner loop to validate. - /// Thrown when the in + /// The loop to validate. + /// Thrown when the in /// do not form a loop. - private static void CheckValidLoop(Segment2D[] innerLoop) + private static void CheckValidLoop(Segment2D[] loop) { - if (innerLoop.Length == 1 || !IsLoopConnected(innerLoop)) + if (loop.Length == 1 || !IsLoopConnected(loop)) { - throw new ArgumentException(Resources.SoilLayer2D_CheckValidLoop_Loop_contains_disconnected_segments); + throw new ArgumentException(Resources.Loop_contains_disconnected_segments); } } Index: Ringtoets/Common/src/Ringtoets.Common.IO/SoilProfile/SoilLayer2DGeometryReader.cs =================================================================== diff -u -r436939c3c30807a14460394b369f2fb7e984720d -r7733b872eca9cfa426bc0979f25ae3f7e2f78453 --- Ringtoets/Common/src/Ringtoets.Common.IO/SoilProfile/SoilLayer2DGeometryReader.cs (.../SoilLayer2DGeometryReader.cs) (revision 436939c3c30807a14460394b369f2fb7e984720d) +++ Ringtoets/Common/src/Ringtoets.Common.IO/SoilProfile/SoilLayer2DGeometryReader.cs (.../SoilLayer2DGeometryReader.cs) (revision 7733b872eca9cfa426bc0979f25ae3f7e2f78453) @@ -68,7 +68,7 @@ /// Thrown when is null. /// Thrown when: /// - /// is not valid XML. + /// is not valid XML; /// does not pass schema validation. /// /// @@ -101,7 +101,7 @@ /// Thrown when is null. /// Thrown when: /// - /// is not valid XML. + /// is not valid XML; /// does not pass schema validation. /// /// @@ -166,60 +166,108 @@ } /// - /// Parses the XML element to create a collection of describing + /// Parses the XML element to create a collection of sorted describing /// a geometric loop. /// /// The geometric loop element. - /// Thrown when - /// XML for any geometry curve is invalid. + /// Thrown when the XML: + /// + /// for any geometry curve is invalid; + /// only contains one curve; + /// contains disconnected curves. + /// + /// + /// As the description states, the returned segments are sorted. The sorting is + /// necessary for hiding some insufficiencies in D-Soilmodel. private static IEnumerable ParseGeometryLoop(XElement loop) { IEnumerable curves = loop.XPathSelectElements($".//{geometryCurveElementName}"); - return SortCurves(curves.Select(ParseGeometryCurve).ToArray()); + + Segment2D[] unsortedSegments = curves.Select(ParseGeometryCurve).ToArray(); + + if (unsortedSegments.Length == 1) + { + throw new SoilLayerConversionException(Resources.Loop_contains_disconnected_segments); + } + + return CreateSortedSegments(unsortedSegments); } - private static IEnumerable SortCurves(Segment2D[] curves) + /// + /// Creates sorted segments from . + /// + /// The unsorted segments to get the sorted segments from. + /// An array of sorted segments. + /// Thrown when + /// contains disconnected segments. + private static IEnumerable CreateSortedSegments(Segment2D[] unsortedSegments) { - if (!curves.Any()) + Point2D[] sortedPoints = GetSortedPoints(unsortedSegments); + int sortedPointsLength = sortedPoints.Length; + + for (var i = 0; i < sortedPointsLength; i++) { - yield break; + yield return new Segment2D(sortedPoints[i], + i == sortedPointsLength - 1 + ? sortedPoints[0] + : sortedPoints[i + 1]); } + } - Segment2D firstCurve = curves.First(); - yield return firstCurve; + /// + /// Gets sorted points from . + /// + /// The segments to get the sorted points from. + /// An array of sorted points. + /// Thrown when + /// contains disconnected segments. + private static Point2D[] GetSortedPoints(Segment2D[] segments) + { + var sortedPoints = new List(); - Point2D startPoint = firstCurve.FirstPoint; - Segment2D currentCurve = firstCurve; - Point2D currentPoint = currentCurve.SecondPoint; - - List availableCurves = curves.ToList(); - availableCurves.Remove(firstCurve); - while (!Equals(currentPoint, startPoint)) + for (var index = 0; index < segments.Length; ++index) { - if (!availableCurves.Any()) + if (index == 0) { - throw new SoilLayerConversionException(Resources.SoilLayer2DGeometryReader_Geometry_contains_no_valid_xml); + sortedPoints.Add(segments[index].FirstPoint); + sortedPoints.Add(segments[index].SecondPoint); } - - Segment2D nextCurve = availableCurves.FirstOrDefault(c => !ReferenceEquals(c, currentCurve) - && (Equals(c.FirstPoint, currentPoint) - || Equals(c.SecondPoint, currentPoint))); - - if (nextCurve == null) + else if (segments[index].FirstPoint.Equals(sortedPoints[sortedPoints.Count - 1])) { - throw new SoilLayerConversionException(Resources.SoilLayer2DGeometryReader_Geometry_contains_no_valid_xml); + sortedPoints.Add(segments[index].SecondPoint); } + else if (segments[index].SecondPoint.Equals(sortedPoints[sortedPoints.Count - 1])) + { + sortedPoints.Add(segments[index].FirstPoint); + } + else + { + if (sortedPoints.Count == 2) + { + sortedPoints.Reverse(); + } + if (segments[index].FirstPoint.Equals(sortedPoints[sortedPoints.Count - 1])) + { + sortedPoints.Add(segments[index].SecondPoint); + } + else if (segments[index].SecondPoint.Equals(sortedPoints[sortedPoints.Count - 1])) + { + sortedPoints.Add(segments[index].FirstPoint); + } + else + { + throw new SoilLayerConversionException(Resources.Loop_contains_disconnected_segments); + } + } + } + if (sortedPoints.Count <= 0 || !sortedPoints[0].Equals(sortedPoints[sortedPoints.Count - 1])) + { + return sortedPoints.ToArray(); + } - availableCurves.Remove(nextCurve); + sortedPoints.RemoveAt(sortedPoints.Count - 1); - currentCurve = Equals(nextCurve.FirstPoint, currentPoint) - ? nextCurve - : new Segment2D(nextCurve.SecondPoint, nextCurve.FirstPoint); - - yield return currentCurve; - - currentPoint = currentCurve.SecondPoint; - } + return sortedPoints.ToArray(); } /// @@ -246,7 +294,7 @@ /// The 2D point element. /// Thrown when any of the following occurs: /// - /// A coordinate value cannot be parsed. + /// A coordinate value cannot be parsed; /// XML for 2D point is invalid. /// private static Point2D ParsePoint(XElement point) Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/SoilProfile/SoilLayer2DGeometryReaderTest.cs =================================================================== diff -u -r9cdab8b57c9731d15b8bbcf494fc9ca27fcb5312 -r7733b872eca9cfa426bc0979f25ae3f7e2f78453 --- Ringtoets/Common/test/Ringtoets.Common.IO.Test/SoilProfile/SoilLayer2DGeometryReaderTest.cs (.../SoilLayer2DGeometryReaderTest.cs) (revision 9cdab8b57c9731d15b8bbcf494fc9ca27fcb5312) +++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/SoilProfile/SoilLayer2DGeometryReaderTest.cs (.../SoilLayer2DGeometryReaderTest.cs) (revision 7733b872eca9cfa426bc0979f25ae3f7e2f78453) @@ -91,7 +91,7 @@ } [Test] - public void Read_XmlDocumentWithNoInnerLoops_ThrowsSoilLayerConversionException() + public void Read_XmlDocumentWithoutInnerLoopsTag_ThrowsSoilLayerConversionException() { // Setup XDocument xmlDoc = GetXmlDocument(""); @@ -106,10 +106,10 @@ } [Test] - public void Read_XmlDocumentWithNoOuterLoop_ThrowsSoilLayerConversionException() + public void Read_XmlDocumentWithoutOuterLoopTag_ThrowsSoilLayerConversionException() { // Setup - XDocument xmlDoc = GetXmlDocument(""); + XDocument xmlDoc = GetXmlDocument(""); var reader = new SoilLayer2DGeometryReader(); // Call @@ -121,9 +121,25 @@ } [Test] - public void Read_XmlDocumentWithEmptyInnerLoopAndOuterLoop_ReturnsLayerWithEmptyInnerLoopAndEmptyOuterLoop() + public void Read_XmlDocumentWithEmptyInnerLoopsAndEmptyOuterLoop_ReturnsLayerWithoutInnerLoopsAndWithEmptyOuterLoop() { // Setup + XDocument xmlDoc = GetXmlDocument(""); + var reader = new SoilLayer2DGeometryReader(); + + // Call + SoilLayer2D result = reader.Read(xmlDoc); + + // Assert + Assert.NotNull(result); + CollectionAssert.IsEmpty(result.OuterLoop); + Assert.AreEqual(0, result.InnerLoops.Count()); + } + + [Test] + public void Read_XmlDocumentWithEmptyInnerLoopAndEmptyOuterLoop_ReturnsLayerWithEmptyInnerLoopAndEmptyOuterLoop() + { + // Setup XDocument xmlDoc = GetXmlDocument(""); var reader = new SoilLayer2DGeometryReader(); @@ -138,6 +154,42 @@ } [Test] + public void Read_XmlDocumentNoHeadPoint_ThrowsSoilLayerConversionException() + { + // Setup + XDocument xmlDoc = GetXmlDocument( + "" + + "10.11.1" + + ""); + var reader = new SoilLayer2DGeometryReader(); + + // Call + TestDelegate test = () => reader.Read(xmlDoc); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("Het XML-document dat de geometrie beschrijft voor de laag is niet geldig.", exception.Message); + } + + [Test] + public void Read_XmlDocumentNoEndPoint_ThrowsSoilLayerConversionException() + { + // Setup + XDocument xmlDoc = GetXmlDocument( + "" + + "00.11.1" + + ""); + var reader = new SoilLayer2DGeometryReader(); + + // Call + TestDelegate test = () => reader.Read(xmlDoc); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("Het XML-document dat de geometrie beschrijft voor de laag is niet geldig.", exception.Message); + } + + [Test] [TestCase("x")] [TestCase("")] public void Read_XmlDocumentWithInvalidPointCoordinate_ThrowsSoilLayerConversionException(string incorrectNumber) @@ -178,231 +230,332 @@ } [Test] + public void Read_XmlDocumentWithOneSegment_ThrowSoilLayerConversionException() + { + // Setup + XDocument xmlDoc = GetXmlDocument( + "" + + "" + + "001.2511101.25" + + "" + + ""); + + var reader = new SoilLayer2DGeometryReader(); + + // Call + TestDelegate test = () => reader.Read(xmlDoc); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("De segmenten van de geometrie van de laag vormen geen lus.", exception.Message); + } + + [Test] [SetCulture("nl-NL")] - public void Read_NLXmlDocumentPointInOuterLoop_ReturnsLayerWithOuterLoopWithPoint() + public void Read_NLXmlDocumentWithSegmentsInOuterLoop_ReturnsLayerWithOuterLoopWithSegments() { - Read_XmlDocumentPointInOuterLoop_ReturnsLayerWithOuterLoopWithPoint(); + Read_XmlDocumentWithSegmentsInOuterLoop_ReturnsLayerWithOuterLoopWithSegments(); } [Test] [SetCulture("en-US")] - public void Read_ENXmlDocumentPointInOuterLoop_ReturnsLayerWithOuterLoopWithPoint() + public void Read_ENXmlDocumentWithSegmentsInOuterLoop_ReturnsLayerWithOuterLoopWithSegments() { - Read_XmlDocumentPointInOuterLoop_ReturnsLayerWithOuterLoopWithPoint(); + Read_XmlDocumentWithSegmentsInOuterLoop_ReturnsLayerWithOuterLoopWithSegments(); } [Test] - public void Read_XmlDocumentPointsInInnerLoop_ReturnsLayerWithInnerLoopWithSegment() + [SetCulture("nl-NL")] + public void Read_NLXmlDocumentWithSegmentsInInnerLoop_ReturnsLayerWithInnerLoopWithSegments() { + Read_XmlDocumentWithSegmentsInInnerLoop_ReturnsLayerWithInnerLoopWithSegments(); + } + + [Test] + [SetCulture("en-US")] + public void Read_ENXmlDocumentWithSegmentsInInnerLoop_ReturnsLayerWithInnerLoopWithSegments() + { + Read_XmlDocumentWithSegmentsInInnerLoop_ReturnsLayerWithInnerLoopWithSegments(); + } + + [Test] + public static void Read_XmlDocumentWithTwoEqualSegmentsInOuterLoop_ReturnsLayerWithOuterLoopWithSegments() + { // Setup - var random = new Random(22); CultureInfo invariantCulture = CultureInfo.InvariantCulture; - double x1 = random.NextDouble(); - double x2 = random.NextDouble(); - double y1 = random.NextDouble(); - double y2 = random.NextDouble(); + const double point1 = 1.1; + const double point2 = 2.2; - string x1String = XmlConvert.ToString(x1); - string x2String = XmlConvert.ToString(x2); - string y1String = XmlConvert.ToString(y1); - string y2String = XmlConvert.ToString(y2); - XDocument xmlDoc = GetXmlDocument( + string pointString1 = XmlConvert.ToString(point1); + string pointString2 = XmlConvert.ToString(point2); + XDocument bytes = GetXmlDocument( string.Format(invariantCulture, - "" + - "{0}0.1{1}" + - "{2}0.1{3}" + + "" + + "{0}0.1{0}" + + "{1}0.1{1}" + "" + - "{0}0.1{1}" + - "{2}0.1{3}" + - "", - x1String, y1String, x2String, y2String)); + "{0}0.1{0}" + + "{1}0.1{1}" + + "", + pointString1, pointString2)); + var reader = new SoilLayer2DGeometryReader(); // Call - SoilLayer2D result = reader.Read(xmlDoc); + SoilLayer2D result = reader.Read(bytes); // Assert Assert.NotNull(result); - - var expectedSegment = new Segment2D(new Point2D(x1, y1), new Point2D(x2, y2)); - var expectedCollection = new[] + CollectionAssert.AreEqual(new List { - new List - { - expectedSegment, - expectedSegment - } - }; - CollectionAssert.AreEqual(expectedCollection, result.InnerLoops); + new Segment2D(new Point2D(point1, point1), new Point2D(point2, point2)), + new Segment2D(new Point2D(point2, point2), new Point2D(point1, point1)) + }, result.OuterLoop); } [Test] - public void Read_XmlDocumentSinglePointOuterLoopGeometryCurve_ThrowsSoilLayerConversionException() + public static void Read_XmlDocumentWithTwoEqualSegmentsInInnerLoop_ReturnsLayerWithInnerLoopWithSegments() { // Setup - XDocument xmlDoc = GetXmlDocument( - "" + - "10.11.1" + - ""); - var reader = new SoilLayer2DGeometryReader(); + CultureInfo invariantCulture = CultureInfo.InvariantCulture; - // Call - TestDelegate test = () => reader.Read(xmlDoc); + const double point1 = 1.1; + const double point2 = 2.2; - // Assert - Assert.Throws(test); - } + string pointString1 = XmlConvert.ToString(point1); + string pointString2 = XmlConvert.ToString(point2); + XDocument bytes = GetXmlDocument( + string.Format(invariantCulture, + "" + + "" + + "{0}0.1{0}" + + "{1}0.1{1}" + + "" + + "{0}0.1{0}" + + "{1}0.1{1}" + + "", + pointString1, pointString2)); - [Test] - public void Read_XmlDocumentSinglePointInnerLoopGeometryCurve_ThrowsSoilLayerConversionException() - { - // Setup - XDocument xmlDoc = GetXmlDocument( - "" + - "00.11.1" + - ""); var reader = new SoilLayer2DGeometryReader(); // Call - TestDelegate test = () => reader.Read(xmlDoc); + SoilLayer2D result = reader.Read(bytes); // Assert - Assert.Throws(test); + Assert.NotNull(result); + CollectionAssert.AreEqual(new List + { + new Segment2D(new Point2D(point1, point1), new Point2D(point2, point2)), + new Segment2D(new Point2D(point2, point2), new Point2D(point1, point1)) + }, result.InnerLoops.ElementAt(0)); } [Test] - public void Read_XmlDocumentEqualSegments_ReturnsTwoEqualSegments() + public static void Read_XmlDocumentWithScrambledSegmentsInOuterLoop_ReturnsLayerWithOuterLoopWithSortedSegments( + [Values(true, false)] bool firstSegmentInverted, + [Values(true, false)] bool secondSegmentInverted) { // Setup - XDocument xmlDoc = GetXmlDocument( - "" + - "" + - "001.1101.1" + - "" + - "" + - "001.1101.1" + - "" + - ""); + CultureInfo invariantCulture = CultureInfo.InvariantCulture; + double point1 = firstSegmentInverted ? 2.2 : 1.1; + double point2 = firstSegmentInverted ? 1.1 : 2.2; + double point3 = secondSegmentInverted ? 3.3 : 2.2; + double point4 = secondSegmentInverted ? 2.2 : 3.3; + const double point5 = 3.3; + const double point6 = 1.1; + + string pointString1 = XmlConvert.ToString(point1); + string pointString2 = XmlConvert.ToString(point2); + string pointString3 = XmlConvert.ToString(point3); + string pointString4 = XmlConvert.ToString(point4); + string pointString5 = XmlConvert.ToString(point5); + string pointString6 = XmlConvert.ToString(point6); + + XDocument bytes = GetXmlDocument( + string.Format(invariantCulture, + "" + + "" + + "{0}0.1{0}" + + "{1}0.1{1}" + + "" + + "{2}0.1{2}" + + "{3}0.1{3}" + + "" + + "{4}0.1{4}" + + "{5}0.1{5}" + + "", + pointString1, pointString2, pointString3, pointString4, pointString5, pointString6)); + var reader = new SoilLayer2DGeometryReader(); // Call - SoilLayer2D result = reader.Read(xmlDoc); + SoilLayer2D result = reader.Read(bytes); // Assert - Assert.AreEqual(2, result.OuterLoop.Count()); - Assert.AreEqual(result.OuterLoop.ElementAt(0), result.OuterLoop.ElementAt(1)); + Assert.NotNull(result); + CollectionAssert.AreEqual(new List + { + new Segment2D(new Point2D(1.1, 1.1), new Point2D(2.2, 2.2)), + new Segment2D(new Point2D(2.2, 2.2), new Point2D(3.3, 3.3)), + new Segment2D(new Point2D(3.3, 3.3), new Point2D(1.1, 1.1)) + }, result.OuterLoop); } [Test] - public void Read_XmlDocumentSegmentsNotConnectedAndReversed_ReturnsSegmentsConnectedInSameDirection() + public static void Read_XmlDocumentWithScrambledSegmentsInInnerLoop_ReturnsLayerWithInnerLoopWithSortedSegments( + [Values(true, false)] bool firstSegmentInverted, + [Values(true, false)] bool secondSegmentInverted) { // Setup - XDocument xmlDoc = GetXmlDocument( - "" + - "" + - "001.2511101.25" + - "" + - "" + - "002.92001.25" + - "" + - "" + - "002.924203.23" + - "" + - "" + - "11101.254203.23" + - "" + - ""); + CultureInfo invariantCulture = CultureInfo.InvariantCulture; + double point1 = firstSegmentInverted ? 2.2 : 1.1; + double point2 = firstSegmentInverted ? 1.1 : 2.2; + double point3 = secondSegmentInverted ? 3.3 : 2.2; + double point4 = secondSegmentInverted ? 2.2 : 3.3; + const double point5 = 3.3; + const double point6 = 1.1; + + string pointString1 = XmlConvert.ToString(point1); + string pointString2 = XmlConvert.ToString(point2); + string pointString3 = XmlConvert.ToString(point3); + string pointString4 = XmlConvert.ToString(point4); + string pointString5 = XmlConvert.ToString(point5); + string pointString6 = XmlConvert.ToString(point6); + + XDocument bytes = GetXmlDocument( + string.Format(invariantCulture, + "" + + "" + + "{0}0.1{0}" + + "{1}0.1{1}" + + "" + + "{2}0.1{2}" + + "{3}0.1{3}" + + "" + + "{4}0.1{4}" + + "{5}0.1{5}" + + "", + pointString1, pointString2, pointString3, pointString4, pointString5, pointString6)); + var reader = new SoilLayer2DGeometryReader(); // Call - SoilLayer2D result = reader.Read(xmlDoc); + SoilLayer2D result = reader.Read(bytes); // Assert Assert.NotNull(result); - var expectedSegments = new[] + CollectionAssert.AreEqual(new List { - new Segment2D(new Point2D(0, 1.25), new Point2D(111, 1.25)), - new Segment2D(new Point2D(111, 1.25), new Point2D(42, 3.23)), - new Segment2D(new Point2D(42, 3.23), new Point2D(0, 2.92)), - new Segment2D(new Point2D(0, 2.92), new Point2D(0, 1.25)) - }; - - CollectionAssert.AreEqual(expectedSegments, result.OuterLoop); + new Segment2D(new Point2D(1.1, 1.1), new Point2D(2.2, 2.2)), + new Segment2D(new Point2D(2.2, 2.2), new Point2D(3.3, 3.3)), + new Segment2D(new Point2D(3.3, 3.3), new Point2D(1.1, 1.1)) + }, result.InnerLoops.ElementAt(0)); } [Test] - public void Read_XmlDocumentOneSegment_ThrowSoilLayerConversionException() + public static void Read_XmlDocumentWithSegmentsInOuterLoopThatAreNotConnected_ThrowSoilLayerConversionException() { // Setup - XDocument xmlDoc = GetXmlDocument( - "" + - "" + - "001.2511101.25" + - "" + - ""); + CultureInfo invariantCulture = CultureInfo.InvariantCulture; + const double point1 = 1.1; + const double point2 = 2.2; + const double point3 = 3.3; + const double point4 = 4.4; + + string pointString1 = XmlConvert.ToString(point1); + string pointString2 = XmlConvert.ToString(point2); + string pointString3 = XmlConvert.ToString(point3); + string pointString4 = XmlConvert.ToString(point4); + + XDocument bytes = GetXmlDocument( + string.Format(invariantCulture, + "" + + "" + + "{0}0.1{0}" + + "{1}0.1{1}" + + "" + + "{2}0.1{2}" + + "{3}0.1{3}" + + "", + pointString1, pointString2, pointString3, pointString4)); + var reader = new SoilLayer2DGeometryReader(); // Call - TestDelegate test = () => reader.Read(xmlDoc); + TestDelegate test = () => reader.Read(bytes); // Assert var exception = Assert.Throws(test); - Assert.AreEqual("Het XML-document dat de geometrie beschrijft voor de laag is niet geldig.", exception.Message); + Assert.AreEqual("De segmenten van de geometrie van de laag vormen geen lus.", exception.Message); } [Test] - public void Read_XmlDocumentSegmentsNotConnected_ThrowSoilLayerConversionException() + public static void Read_XmlDocumentWithSegmentsInInnerLoopThatAreNotConnected_ThrowSoilLayerConversionException() { // Setup - XDocument xmlDoc = GetXmlDocument( - "" + - "" + - "001.2511101.25" + - "" + - "" + - "002.924203.23" + - "" + - ""); + CultureInfo invariantCulture = CultureInfo.InvariantCulture; + const double point1 = 1.1; + const double point2 = 2.2; + const double point3 = 3.3; + const double point4 = 4.4; + + string pointString1 = XmlConvert.ToString(point1); + string pointString2 = XmlConvert.ToString(point2); + string pointString3 = XmlConvert.ToString(point3); + string pointString4 = XmlConvert.ToString(point4); + + XDocument bytes = GetXmlDocument( + string.Format(invariantCulture, + "" + + "" + + "{0}0.1{0}" + + "{1}0.1{1}" + + "" + + "{2}0.1{2}" + + "{3}0.1{3}" + + "", + pointString1, pointString2, pointString3, pointString4)); + var reader = new SoilLayer2DGeometryReader(); // Call - TestDelegate test = () => reader.Read(xmlDoc); + TestDelegate test = () => reader.Read(bytes); // Assert var exception = Assert.Throws(test); - Assert.AreEqual("Het XML-document dat de geometrie beschrijft voor de laag is niet geldig.", exception.Message); + Assert.AreEqual("De segmenten van de geometrie van de laag vormen geen lus.", exception.Message); } - private static void Read_XmlDocumentPointInOuterLoop_ReturnsLayerWithOuterLoopWithPoint() + private static void Read_XmlDocumentWithSegmentsInOuterLoop_ReturnsLayerWithOuterLoopWithSegments() { // Setup - var random = new Random(22); CultureInfo invariantCulture = CultureInfo.InvariantCulture; - double x1 = random.NextDouble(); - double x2 = random.NextDouble(); - double y1 = random.NextDouble(); - double y2 = random.NextDouble(); + const double point1 = 1.1; + const double point2 = 2.2; + const double point3 = 3.3; - string x1String = XmlConvert.ToString(x1); - string x2String = XmlConvert.ToString(x2); - string y1String = XmlConvert.ToString(y1); - string y2String = XmlConvert.ToString(y2); + string pointString1 = XmlConvert.ToString(point1); + string pointString2 = XmlConvert.ToString(point2); + string pointString3 = XmlConvert.ToString(point3); XDocument bytes = GetXmlDocument( string.Format(invariantCulture, "" + - "{0}0.1{1}" + - "{2}0.1{3}" + + "{0}0.1{0}" + + "{1}0.1{1}" + "" + - "{0}0.1{1}" + - "{2}0.1{3}" + + "{1}0.1{1}" + + "{2}0.1{2}" + + "" + + "{2}0.1{2}" + + "{0}0.1{0}" + "", - x1String, y1String, x2String, y2String)); + pointString1, pointString2, pointString3)); var reader = new SoilLayer2DGeometryReader(); @@ -411,14 +564,58 @@ // Assert Assert.NotNull(result); - var expectedSegment = new Segment2D(new Point2D(x1, y1), new Point2D(x2, y2)); CollectionAssert.AreEqual(new List { - expectedSegment, - expectedSegment + new Segment2D(new Point2D(point1, point1), new Point2D(point2, point2)), + new Segment2D(new Point2D(point2, point2), new Point2D(point3, point3)), + new Segment2D(new Point2D(point3, point3), new Point2D(point1, point1)) }, result.OuterLoop); } + private static void Read_XmlDocumentWithSegmentsInInnerLoop_ReturnsLayerWithInnerLoopWithSegments() + { + // Setup + CultureInfo invariantCulture = CultureInfo.InvariantCulture; + + const double point1 = 1.1; + const double point2 = 2.2; + const double point3 = 3.3; + + string pointString1 = XmlConvert.ToString(point1); + string pointString2 = XmlConvert.ToString(point2); + string pointString3 = XmlConvert.ToString(point3); + XDocument bytes = GetXmlDocument( + string.Format(invariantCulture, + "" + + "" + + "" + + "{0}0.1{0}" + + "{1}0.1{1}" + + "" + + "{1}0.1{1}" + + "{2}0.1{2}" + + "" + + "{2}0.1{2}" + + "{0}0.1{0}" + + "" + + "", + pointString1, pointString2, pointString3)); + + var reader = new SoilLayer2DGeometryReader(); + + // Call + SoilLayer2D result = reader.Read(bytes); + + // Assert + Assert.NotNull(result); + CollectionAssert.AreEqual(new List + { + new Segment2D(new Point2D(point1, point1), new Point2D(point2, point2)), + new Segment2D(new Point2D(point2, point2), new Point2D(point3, point3)), + new Segment2D(new Point2D(point3, point3), new Point2D(point1, point1)) + }, result.InnerLoops.ElementAt(0)); + } + /// /// Takes a which describes an XML document and returns /// an from this. Index: Ringtoets/MacroStabilityInwards/src/Ringtoets.MacroStabilityInwards.IO/SoilProfiles/MacroStabilityInwardsSoilLayerTransformer.cs =================================================================== diff -u -r90a9502badff5788374461a1b2179a5dd0e866a2 -r7733b872eca9cfa426bc0979f25ae3f7e2f78453 --- Ringtoets/MacroStabilityInwards/src/Ringtoets.MacroStabilityInwards.IO/SoilProfiles/MacroStabilityInwardsSoilLayerTransformer.cs (.../MacroStabilityInwardsSoilLayerTransformer.cs) (revision 90a9502badff5788374461a1b2179a5dd0e866a2) +++ Ringtoets/MacroStabilityInwards/src/Ringtoets.MacroStabilityInwards.IO/SoilProfiles/MacroStabilityInwardsSoilLayerTransformer.cs (.../MacroStabilityInwardsSoilLayerTransformer.cs) (revision 7733b872eca9cfa426bc0979f25ae3f7e2f78453) @@ -92,8 +92,8 @@ throw new ImportedDataTransformException(); } - Ring outerRing = TransformSegmentToRing(soilLayer.OuterLoop); - Ring[] innerRings = soilLayer.InnerLoops.Select(TransformSegmentToRing).ToArray(); + Ring outerRing = TransformSegmentsToRing(soilLayer.OuterLoop); + Ring[] innerRings = soilLayer.InnerLoops.Select(TransformSegmentsToRing).ToArray(); var layer = new MacroStabilityInwardsSoilLayer2D(outerRing, innerRings); SetProperties(soilLayer, layer.Data); @@ -239,20 +239,11 @@ /// A based on . /// Thrown when /// could not be transformed to a . - private static Ring TransformSegmentToRing(IEnumerable segments) + private static Ring TransformSegmentsToRing(IEnumerable segments) { try { - var points = new List(); - foreach (Segment2D segment in segments) - { - points.AddRange(new[] - { - segment.FirstPoint, - segment.SecondPoint - }); - } - return new Ring(points.Distinct()); + return new Ring(segments.Select(s => s.FirstPoint)); } catch (ArgumentException e) {