Index: Application/Ringtoets/src/Application.Ringtoets.Storage/Read/Piping/SurfaceLineEntityReadExtensions.cs =================================================================== diff -u -r3fb0df0ed6e64657154700ee7706e035d5bf99f5 -r8e717411be3a9f6947737321832ec2ffe06f43dd --- Application/Ringtoets/src/Application.Ringtoets.Storage/Read/Piping/SurfaceLineEntityReadExtensions.cs (.../SurfaceLineEntityReadExtensions.cs) (revision 3fb0df0ed6e64657154700ee7706e035d5bf99f5) +++ Application/Ringtoets/src/Application.Ringtoets.Storage/Read/Piping/SurfaceLineEntityReadExtensions.cs (.../SurfaceLineEntityReadExtensions.cs) (revision 8e717411be3a9f6947737321832ec2ffe06f43dd) @@ -112,7 +112,7 @@ surfaceLine.SetDitchPolderSideAt(geometryPoint); break; default: - throw new InvalidEnumArgumentException("type", + throw new InvalidEnumArgumentException(nameof(type), (int) type, typeof(CharacteristicPointType)); } Index: Core/Common/src/Core.Common.Base/Geometry/Point2DCollectionExtensions.cs =================================================================== diff -u -rb8976a5e3cf525e419227e409e44ac69a430711a -r8e717411be3a9f6947737321832ec2ffe06f43dd --- Core/Common/src/Core.Common.Base/Geometry/Point2DCollectionExtensions.cs (.../Point2DCollectionExtensions.cs) (revision b8976a5e3cf525e419227e409e44ac69a430711a) +++ Core/Common/src/Core.Common.Base/Geometry/Point2DCollectionExtensions.cs (.../Point2DCollectionExtensions.cs) (revision 8e717411be3a9f6947737321832ec2ffe06f43dd) @@ -25,6 +25,9 @@ namespace Core.Common.Base.Geometry { + /// + /// Extension methods for collections of . + /// public static class Point2DCollectionExtensions { /// Index: Core/Common/src/Core.Common.Base/Geometry/Point3DCollectionExtensions.cs =================================================================== diff -u -rb8976a5e3cf525e419227e409e44ac69a430711a -r8e717411be3a9f6947737321832ec2ffe06f43dd --- Core/Common/src/Core.Common.Base/Geometry/Point3DCollectionExtensions.cs (.../Point3DCollectionExtensions.cs) (revision b8976a5e3cf525e419227e409e44ac69a430711a) +++ Core/Common/src/Core.Common.Base/Geometry/Point3DCollectionExtensions.cs (.../Point3DCollectionExtensions.cs) (revision 8e717411be3a9f6947737321832ec2ffe06f43dd) @@ -25,6 +25,9 @@ namespace Core.Common.Base.Geometry { + /// + /// Extension methods for collections of . + /// public static class Point3DCollectionExtensions { /// Index: Ringtoets/Common/src/Ringtoets.Common.IO/Properties/Resources.Designer.cs =================================================================== diff -u -rb8976a5e3cf525e419227e409e44ac69a430711a -r8e717411be3a9f6947737321832ec2ffe06f43dd --- Ringtoets/Common/src/Ringtoets.Common.IO/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision b8976a5e3cf525e419227e409e44ac69a430711a) +++ Ringtoets/Common/src/Ringtoets.Common.IO/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 8e717411be3a9f6947737321832ec2ffe06f43dd) @@ -2020,6 +2020,36 @@ } /// + /// Looks up a localized string similar to Profielschematisatie {0} doorkruist de huidige referentielijn niet of op meer dan één punt en kan niet worden geïmporteerd.. + /// + public static string SurfaceLineExtensions_CheckReferenceLineInterSections_Surfaceline_0_does_not_correspond_to_current_referenceline { + get { + return ResourceManager.GetString("SurfaceLineExtensions_CheckReferenceLineInterSections_Surfaceline_0_does_not_corr" + + "espond_to_current_referenceline", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Profielschematisatie {0} doorkruist de huidige referentielijn niet of op meer dan één punt en kan niet worden geïmporteerd. {1}. + /// + public static string SurfaceLineExtensions_CheckReferenceLineInterSections_Surfaceline_0_does_not_correspond_to_current_referenceline_1_ { + get { + return ResourceManager.GetString("SurfaceLineExtensions_CheckReferenceLineInterSections_Surfaceline_0_does_not_corr" + + "espond_to_current_referenceline_1_", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Dit kan komen doordat de profielschematisatie een lokaal coördinaatsysteem heeft.. + /// + public static string SurfaceLineExtensions_CheckReferenceLineInterSections_This_could_be_caused_coordinates_being_local_coordinate_system { + get { + return ResourceManager.GetString("SurfaceLineExtensions_CheckReferenceLineInterSections_This_could_be_caused_coordi" + + "nates_being_local_coordinate_system", resourceCulture); + } + } + + /// /// Looks up a localized string similar to Karakteristieke punten gevonden zonder bijbehorende profielschematisatie voor locatie '{0}'.. /// public static string SurfaceLinesCsvImporter_AddImportedDataToModel_Characteristic_points_found_for_unknown_SurfaceLine_0_ { @@ -2079,36 +2109,6 @@ } /// - /// Looks up a localized string similar to Profielschematisatie {0} doorkruist de huidige referentielijn niet of op meer dan één punt en kan niet worden geïmporteerd.. - /// - public static string SurfaceLinesCsvImporter_CheckReferenceLineInterSections_Surfaceline_0_does_not_correspond_to_current_referenceline { - get { - return ResourceManager.GetString("SurfaceLinesCsvImporter_CheckReferenceLineInterSections_Surfaceline_0_does_not_co" + - "rrespond_to_current_referenceline", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Profielschematisatie {0} doorkruist de huidige referentielijn niet of op meer dan één punt en kan niet worden geïmporteerd. {1}. - /// - public static string SurfaceLinesCsvImporter_CheckReferenceLineInterSections_Surfaceline_0_does_not_correspond_to_current_referenceline_1_ { - get { - return ResourceManager.GetString("SurfaceLinesCsvImporter_CheckReferenceLineInterSections_Surfaceline_0_does_not_co" + - "rrespond_to_current_referenceline_1_", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Dit kan komen doordat de profielschematisatie een lokaal coördinaatsysteem heeft.. - /// - public static string SurfaceLinesCsvImporter_CheckReferenceLineInterSections_This_could_be_caused_coordinates_being_local_coordinate_system { - get { - return ResourceManager.GetString("SurfaceLinesCsvImporter_CheckReferenceLineInterSections_This_could_be_caused_coor" + - "dinates_being_local_coordinate_system", resourceCulture); - } - } - - /// /// Looks up a localized string similar to {0} ///Het bestand wordt overgeslagen.. /// Index: Ringtoets/Common/src/Ringtoets.Common.IO/Properties/Resources.resx =================================================================== diff -u -rb8976a5e3cf525e419227e409e44ac69a430711a -r8e717411be3a9f6947737321832ec2ffe06f43dd --- Ringtoets/Common/src/Ringtoets.Common.IO/Properties/Resources.resx (.../Resources.resx) (revision b8976a5e3cf525e419227e409e44ac69a430711a) +++ Ringtoets/Common/src/Ringtoets.Common.IO/Properties/Resources.resx (.../Resources.resx) (revision 8e717411be3a9f6947737321832ec2ffe06f43dd) @@ -764,13 +764,13 @@ Meerdere definities gevonden voor profielschematisatie '{0}'. Alleen de eerste definitie wordt geïmporteerd. - + Profielschematisatie {0} doorkruist de huidige referentielijn niet of op meer dan één punt en kan niet worden geïmporteerd. - + Profielschematisatie {0} doorkruist de huidige referentielijn niet of op meer dan één punt en kan niet worden geïmporteerd. {1} - + Dit kan komen doordat de profielschematisatie een lokaal coördinaatsysteem heeft. Index: Ringtoets/Common/src/Ringtoets.Common.IO/Ringtoets.Common.IO.csproj =================================================================== diff -u -ra940166534b3dd6e778de2e7c8e7e5241f3d3381 -r8e717411be3a9f6947737321832ec2ffe06f43dd --- Ringtoets/Common/src/Ringtoets.Common.IO/Ringtoets.Common.IO.csproj (.../Ringtoets.Common.IO.csproj) (revision a940166534b3dd6e778de2e7c8e7e5241f3d3381) +++ Ringtoets/Common/src/Ringtoets.Common.IO/Ringtoets.Common.IO.csproj (.../Ringtoets.Common.IO.csproj) (revision 8e717411be3a9f6947737321832ec2ffe06f43dd) @@ -133,6 +133,7 @@ + Index: Ringtoets/Common/src/Ringtoets.Common.IO/SurfaceLines/SurfaceLineExtensions.cs =================================================================== diff -u --- Ringtoets/Common/src/Ringtoets.Common.IO/SurfaceLines/SurfaceLineExtensions.cs (revision 0) +++ Ringtoets/Common/src/Ringtoets.Common.IO/SurfaceLines/SurfaceLineExtensions.cs (revision 8e717411be3a9f6947737321832ec2ffe06f43dd) @@ -0,0 +1,161 @@ +// Copyright (C) Stichting Deltares 2017. All rights reserved. +// +// This file is part of Ringtoets. +// +// Ringtoets is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// All names, logos, and references to "Deltares" are registered trademarks of +// Stichting Deltares and remain full property of Stichting Deltares at all times. +// All rights reserved. + +using System; +using System.Collections.Generic; +using System.Linq; +using Core.Common.Base.Geometry; +using log4net; +using Ringtoets.Common.Data.AssessmentSection; +using Ringtoets.Common.IO.Properties; + +namespace Ringtoets.Common.IO.SurfaceLines +{ + /// + /// Extension methods for the . + /// + public static class SurfaceLineExtensions + { + private static readonly ILog log = LogManager.GetLogger(typeof(SurfaceLineExtensions)); + + /// + /// The type of the intersection possible with a reference line. + /// + public enum ReferenceLineIntersectionsResult + { + NoIntersections, + OneIntersection, + MultipleIntersectionsOrOverlap + } + + /// + /// Finds out if there is an intersection of the and + /// the + /// + /// The surface line. + /// The reference line. + /// A new with a type of intersection and + /// possibly an intersection point, if there was only one found. + /// Thrown when any parameter is null. + public static ReferenceLineIntersectionResult CheckReferenceLineInterSections(this SurfaceLine surfaceLine, ReferenceLine referenceLine) + { + if (surfaceLine == null) + { + throw new ArgumentNullException(nameof(surfaceLine)); + } + if (referenceLine == null) + { + throw new ArgumentNullException(nameof(referenceLine)); + } + ReferenceLineIntersectionResult result = GetReferenceLineIntersections(referenceLine, surfaceLine); + + if (result.TypeOfIntersection == ReferenceLineIntersectionsResult.NoIntersections) + { + log.ErrorFormat(Resources.SurfaceLineExtensions_CheckReferenceLineInterSections_Surfaceline_0_does_not_correspond_to_current_referenceline_1_, + surfaceLine.Name, + Resources.SurfaceLineExtensions_CheckReferenceLineInterSections_This_could_be_caused_coordinates_being_local_coordinate_system); + } + if (result.TypeOfIntersection == ReferenceLineIntersectionsResult.MultipleIntersectionsOrOverlap) + { + log.ErrorFormat(Resources.SurfaceLineExtensions_CheckReferenceLineInterSections_Surfaceline_0_does_not_correspond_to_current_referenceline, surfaceLine.Name); + } + + return result; + } + + private static ReferenceLineIntersectionResult GetReferenceLineIntersections(ReferenceLine referenceLine, SurfaceLine surfaceLine) + { + IEnumerable surfaceLineSegments = Math2D.ConvertLinePointsToLineSegments(surfaceLine.Points.Select(p => new Point2D(p.X, p.Y))); + Segment2D[] referenceLineSegments = Math2D.ConvertLinePointsToLineSegments(referenceLine.Points).ToArray(); + + return GetReferenceLineIntersectionsResult(surfaceLineSegments, referenceLineSegments); + } + + private static ReferenceLineIntersectionResult GetReferenceLineIntersectionsResult(IEnumerable surfaceLineSegments, Segment2D[] referenceLineSegments) + { + Point2D intersectionPoint = null; + foreach (Segment2D surfaceLineSegment in surfaceLineSegments) + { + foreach (Segment2D referenceLineSegment in referenceLineSegments) + { + Segment2DIntersectSegment2DResult result = Math2D.GetIntersectionBetweenSegments(surfaceLineSegment, referenceLineSegment); + + if (result.IntersectionType == Intersection2DType.Intersects) + { + if (intersectionPoint != null) + { + // Early exit as multiple intersections is a return result: + return ReferenceLineIntersectionResult.CreateMultipleIntersectionsOrOverlapResult(); + } + intersectionPoint = result.IntersectionPoints[0]; + } + + if (result.IntersectionType == Intersection2DType.Overlaps) + { + // Early exit as overlap is a return result: + return ReferenceLineIntersectionResult.CreateMultipleIntersectionsOrOverlapResult(); + } + } + } + return intersectionPoint != null + ? ReferenceLineIntersectionResult.CreateIntersectionResult(intersectionPoint) + : ReferenceLineIntersectionResult.CreateNoSingleIntersectionResult(); + } + + /// + /// Result of finding the intersections of a surface line and a reference line. + /// + public class ReferenceLineIntersectionResult + { + private ReferenceLineIntersectionResult(ReferenceLineIntersectionsResult typeOfIntersection, Point2D intersectionPoint) + { + TypeOfIntersection = typeOfIntersection; + IntersectionPoint = intersectionPoint; + } + + /// + /// Gets the type of intersection that was found. + /// + public ReferenceLineIntersectionsResult TypeOfIntersection { get; } + + /// + /// Gets the intersection point of the surface line and the reference line if + /// there was only one found; or null otherwise. + /// + public Point2D IntersectionPoint { get; } + + public static ReferenceLineIntersectionResult CreateNoSingleIntersectionResult() + { + return new ReferenceLineIntersectionResult(ReferenceLineIntersectionsResult.NoIntersections, null); + } + + public static ReferenceLineIntersectionResult CreateIntersectionResult(Point2D point) + { + return new ReferenceLineIntersectionResult(ReferenceLineIntersectionsResult.OneIntersection, point); + } + + public static ReferenceLineIntersectionResult CreateMultipleIntersectionsOrOverlapResult() + { + return new ReferenceLineIntersectionResult(ReferenceLineIntersectionsResult.MultipleIntersectionsOrOverlap, null); + } + } + } +} \ No newline at end of file Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/Ringtoets.Common.IO.Test.csproj =================================================================== diff -u -ra940166534b3dd6e778de2e7c8e7e5241f3d3381 -r8e717411be3a9f6947737321832ec2ffe06f43dd --- Ringtoets/Common/test/Ringtoets.Common.IO.Test/Ringtoets.Common.IO.Test.csproj (.../Ringtoets.Common.IO.Test.csproj) (revision a940166534b3dd6e778de2e7c8e7e5241f3d3381) +++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/Ringtoets.Common.IO.Test.csproj (.../Ringtoets.Common.IO.Test.csproj) (revision 8e717411be3a9f6947737321832ec2ffe06f43dd) @@ -120,6 +120,7 @@ + Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/SurfaceLines/SurfaceLineExtensionsTest.cs =================================================================== diff -u --- Ringtoets/Common/test/Ringtoets.Common.IO.Test/SurfaceLines/SurfaceLineExtensionsTest.cs (revision 0) +++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/SurfaceLines/SurfaceLineExtensionsTest.cs (revision 8e717411be3a9f6947737321832ec2ffe06f43dd) @@ -0,0 +1,156 @@ +// Copyright (C) Stichting Deltares 2017. All rights reserved. +// +// This file is part of Ringtoets. +// +// Ringtoets is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// All names, logos, and references to "Deltares" are registered trademarks of +// Stichting Deltares and remain full property of Stichting Deltares at all times. +// All rights reserved. + +using System; +using Core.Common.Base.Geometry; +using Core.Common.TestUtil; +using NUnit.Framework; +using Ringtoets.Common.Data.AssessmentSection; +using Ringtoets.Common.IO.SurfaceLines; + +namespace Ringtoets.Common.IO.Test.SurfaceLines +{ + [TestFixture] + public class SurfaceLineExtensionsTest + { + [Test] + public void CheckReferenceLineInterSections_WithoutSurfaceLine_ThrowsArgumentNullException() + { + // Call + TestDelegate test = () => ((SurfaceLine)null).CheckReferenceLineInterSections(new ReferenceLine()); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("surfaceLine", exception.ParamName); + } + + [Test] + public void CheckReferenceLineInterSections_WithoutReferenceLine_ThrowsArgumentNullException() + { + // Call + TestDelegate test = () => new SurfaceLine().CheckReferenceLineInterSections(null); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("referenceLine", exception.ParamName); + } + + [Test] + public void CheckReferenceLineInterSections_SurfaceLineThroughReferenceLine_ReturnIntersectionPoint() + { + // Setup + var referenceLine = new ReferenceLine(); + + const string surfaceLineName = "somewhere"; + var surfaceLine = new SurfaceLine + { + Name = surfaceLineName + }; + surfaceLine.SetGeometry(new[] + { + new Point3D(3.0, 4.0, 2.1), + new Point3D(3.0, 5.0, 2.1) + }); + referenceLine.SetGeometry(new[] + { + new Point2D(2.0, 4.5), + new Point2D(4.0, 4.5) + }); + + SurfaceLineExtensions.ReferenceLineIntersectionResult result = null; + + // Call + result = surfaceLine.CheckReferenceLineInterSections(referenceLine); + + // Assert + Assert.AreEqual(SurfaceLineExtensions.ReferenceLineIntersectionsResult.OneIntersection, result.TypeOfIntersection); + Assert.AreEqual(new Point2D(3.0, 4.5), result.IntersectionPoint); + } + + [Test] + public void CheckReferenceLineInterSections_SurfaceLineNotOnReferenceLine_LogErrorAndReturnResultWithIntersectionPointNull() + { + // Setup + var referenceLine = new ReferenceLine(); + + const string surfaceLineName = "somewhere"; + var surfaceLine = new SurfaceLine + { + Name = surfaceLineName + }; + surfaceLine.SetGeometry(new[] + { + new Point3D(3.0, 4.0, 2.1), + new Point3D(3.0, 5.0, 2.1) + }); + referenceLine.SetGeometry(new[] + { + new Point2D(2.0, 4.0) + }); + + SurfaceLineExtensions.ReferenceLineIntersectionResult result = null; + + // Call + Action call = () => result = surfaceLine.CheckReferenceLineInterSections(referenceLine); + + // Assert + string message = $"Profielschematisatie {surfaceLineName} doorkruist de huidige referentielijn niet of op meer dan één punt en kan niet worden geïmporteerd. Dit kan komen doordat de profielschematisatie een lokaal coördinaatsysteem heeft."; + TestHelper.AssertLogMessageWithLevelIsGenerated(call, Tuple.Create(message, LogLevelConstant.Error)); + Assert.AreEqual(SurfaceLineExtensions.ReferenceLineIntersectionsResult.NoIntersections, result.TypeOfIntersection); + Assert.IsNull(result.IntersectionPoint); + } + + [Test] + public void CheckReferenceLineInterSections_SurfaceLineIntersectsReferenceLineMultipleTimes_LogErrorAndReturnResultWithIntersectionPointNull() + { + // Setup + var referenceLine = new ReferenceLine(); + + const string surfaceLineName = "somewhere"; + var surfaceLine = new SurfaceLine + { + Name = surfaceLineName + }; + surfaceLine.SetGeometry(new[] + { + new Point3D(1.0, 5.0, 2.1), + new Point3D(1.0, 3.0, 2.1) + }); + referenceLine.SetGeometry(new[] + { + new Point2D(0.0, 4.0), + new Point2D(2.0, 4.0), + new Point2D(0.0, 4.0) + }); + + SurfaceLineExtensions.ReferenceLineIntersectionResult result = null; + + // Call + Action call = () => result = surfaceLine.CheckReferenceLineInterSections(referenceLine); + + // Assert + string message = $"Profielschematisatie {surfaceLineName} doorkruist de huidige referentielijn niet of op meer dan één punt en kan niet worden geïmporteerd."; + TestHelper.AssertLogMessageWithLevelIsGenerated(call, Tuple.Create(message, LogLevelConstant.Error)); + Assert.AreEqual(SurfaceLineExtensions.ReferenceLineIntersectionsResult.MultipleIntersectionsOrOverlap, result.TypeOfIntersection); + Assert.IsNull(result.IntersectionPoint); + } + } +} \ No newline at end of file Index: Ringtoets/MacroStabilityInwards/src/Ringtoets.MacroStabilityInwards.IO/Importers/MacrostabilityInwardsSurfaceLineTransformer.cs =================================================================== diff -u -ra940166534b3dd6e778de2e7c8e7e5241f3d3381 -r8e717411be3a9f6947737321832ec2ffe06f43dd --- Ringtoets/MacroStabilityInwards/src/Ringtoets.MacroStabilityInwards.IO/Importers/MacrostabilityInwardsSurfaceLineTransformer.cs (.../MacrostabilityInwardsSurfaceLineTransformer.cs) (revision a940166534b3dd6e778de2e7c8e7e5241f3d3381) +++ Ringtoets/MacroStabilityInwards/src/Ringtoets.MacroStabilityInwards.IO/Importers/MacrostabilityInwardsSurfaceLineTransformer.cs (.../MacrostabilityInwardsSurfaceLineTransformer.cs) (revision 8e717411be3a9f6947737321832ec2ffe06f43dd) @@ -93,13 +93,13 @@ if (result.TypeOfIntersection == ReferenceLineIntersectionsResult.NoIntersections) { - log.ErrorFormat(Resources.SurfaceLinesCsvImporter_CheckReferenceLineInterSections_Surfaceline_0_does_not_correspond_to_current_referenceline_1_, + log.ErrorFormat(Resources.SurfaceLineExtensions_CheckReferenceLineInterSections_Surfaceline_0_does_not_correspond_to_current_referenceline_1_, readSurfaceLine.Name, - Resources.SurfaceLinesCsvImporter_CheckReferenceLineInterSections_This_could_be_caused_coordinates_being_local_coordinate_system); + Resources.SurfaceLineExtensions_CheckReferenceLineInterSections_This_could_be_caused_coordinates_being_local_coordinate_system); } if (result.TypeOfIntersection == ReferenceLineIntersectionsResult.MultipleIntersectionsOrOverlap) { - log.ErrorFormat(Resources.SurfaceLinesCsvImporter_CheckReferenceLineInterSections_Surfaceline_0_does_not_correspond_to_current_referenceline, readSurfaceLine.Name); + log.ErrorFormat(Resources.SurfaceLineExtensions_CheckReferenceLineInterSections_Surfaceline_0_does_not_correspond_to_current_referenceline, readSurfaceLine.Name); } return result; Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Importers/PipingSurfaceLineTransformer.cs =================================================================== diff -u -ra940166534b3dd6e778de2e7c8e7e5241f3d3381 -r8e717411be3a9f6947737321832ec2ffe06f43dd --- Ringtoets/Piping/src/Ringtoets.Piping.IO/Importers/PipingSurfaceLineTransformer.cs (.../PipingSurfaceLineTransformer.cs) (revision a940166534b3dd6e778de2e7c8e7e5241f3d3381) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Importers/PipingSurfaceLineTransformer.cs (.../PipingSurfaceLineTransformer.cs) (revision 8e717411be3a9f6947737321832ec2ffe06f43dd) @@ -20,29 +20,23 @@ // All rights reserved. using System; -using System.Collections.Generic; -using System.Linq; using Core.Common.Base.Geometry; using log4net; using Ringtoets.Common.Data.AssessmentSection; using Ringtoets.Common.IO.Properties; using Ringtoets.Common.IO.SurfaceLines; using Ringtoets.Piping.Primitives; +using ReferenceLineIntersectionsResult = Ringtoets.Common.IO.SurfaceLines.SurfaceLineExtensions.ReferenceLineIntersectionsResult; +using ReferenceLineIntersectionResult = Ringtoets.Common.IO.SurfaceLines.SurfaceLineExtensions.ReferenceLineIntersectionResult; + namespace Ringtoets.Piping.IO.Importers { /// /// Transforms generic into piping specific . /// public class PipingSurfaceLineTransformer : ISurfaceLineTransformer { - private enum ReferenceLineIntersectionsResult - { - NoIntersections, - OneIntersection, - MultipleIntersectionsOrOverlap - } - private static readonly ILog log = LogManager.GetLogger(typeof(PipingSurfaceLineTransformer)); private readonly ReferenceLine referenceLine; @@ -62,139 +56,27 @@ public RingtoetsPipingSurfaceLine Transform(SurfaceLine surfaceLine, CharacteristicPoints characteristicPoints) { + ReferenceLineIntersectionResult result = surfaceLine.CheckReferenceLineInterSections(referenceLine); + + if (result.TypeOfIntersection != ReferenceLineIntersectionsResult.OneIntersection) + { + return null; + } + var pipingSurfaceLine = new RingtoetsPipingSurfaceLine { Name = surfaceLine.Name }; pipingSurfaceLine.SetGeometry(surfaceLine.Points); - ReferenceLineIntersectionResult result = CheckReferenceLineInterSections(pipingSurfaceLine, referenceLine); - - if (result.TypeOfIntersection != ReferenceLineIntersectionsResult.OneIntersection - || !ValidateDikeToesInOrder(pipingSurfaceLine, characteristicPoints)) + if (!pipingSurfaceLine.SetCharacteristicPoints(characteristicPoints)) { return null; } pipingSurfaceLine.ReferenceLineIntersectionWorldPoint = result.IntersectionPoint; - SetCharacteristicPointsOnSurfaceLine(pipingSurfaceLine, characteristicPoints); - return pipingSurfaceLine; } - - private static void SetCharacteristicPointsOnSurfaceLine(RingtoetsPipingSurfaceLine readSurfaceLine, CharacteristicPoints characteristicPointsLocation) - { - if (characteristicPointsLocation == null) - { - return; - } - readSurfaceLine.TrySetDitchPolderSide(characteristicPointsLocation.DitchPolderSide); - readSurfaceLine.TrySetBottomDitchPolderSide(characteristicPointsLocation.BottomDitchPolderSide); - readSurfaceLine.TrySetBottomDitchDikeSide(characteristicPointsLocation.BottomDitchDikeSide); - readSurfaceLine.TrySetDitchDikeSide(characteristicPointsLocation.DitchDikeSide); - readSurfaceLine.TrySetDikeToeAtRiver(characteristicPointsLocation.DikeToeAtRiver); - readSurfaceLine.TrySetDikeToeAtPolder(characteristicPointsLocation.DikeToeAtPolder); - } - - private static bool ValidateDikeToesInOrder(RingtoetsPipingSurfaceLine readSurfaceLine, CharacteristicPoints characteristicPoints) - { - if (characteristicPoints != null && characteristicPoints.DikeToeAtRiver != null && characteristicPoints.DikeToeAtPolder != null) - { - Point2D localDikeToeAtRiver = readSurfaceLine.GetLocalPointFromGeometry(characteristicPoints.DikeToeAtRiver); - Point2D localDikeToeAtPolder = readSurfaceLine.GetLocalPointFromGeometry(characteristicPoints.DikeToeAtPolder); - - if (localDikeToeAtPolder.X <= localDikeToeAtRiver.X) - { - log.WarnFormat(Resources.SurfaceLinesCsvImporter_CheckCharacteristicPoints_EntryPointL_greater_or_equal_to_ExitPointL_for_0_, characteristicPoints.Name); - return false; - } - } - return true; - } - - private static ReferenceLineIntersectionResult CheckReferenceLineInterSections(RingtoetsPipingSurfaceLine readSurfaceLine, ReferenceLine line) - { - ReferenceLineIntersectionResult result = GetReferenceLineIntersections(line, readSurfaceLine); - - if (result.TypeOfIntersection == ReferenceLineIntersectionsResult.NoIntersections) - { - log.ErrorFormat(Resources.SurfaceLinesCsvImporter_CheckReferenceLineInterSections_Surfaceline_0_does_not_correspond_to_current_referenceline_1_, - readSurfaceLine.Name, - Resources.SurfaceLinesCsvImporter_CheckReferenceLineInterSections_This_could_be_caused_coordinates_being_local_coordinate_system); - } - if (result.TypeOfIntersection == ReferenceLineIntersectionsResult.MultipleIntersectionsOrOverlap) - { - log.ErrorFormat(Resources.SurfaceLinesCsvImporter_CheckReferenceLineInterSections_Surfaceline_0_does_not_correspond_to_current_referenceline, readSurfaceLine.Name); - } - - return result; - } - - private static ReferenceLineIntersectionResult GetReferenceLineIntersections(ReferenceLine referenceLine, RingtoetsPipingSurfaceLine surfaceLine) - { - IEnumerable surfaceLineSegments = Math2D.ConvertLinePointsToLineSegments(surfaceLine.Points.Select(p => new Point2D(p.X, p.Y))); - Segment2D[] referenceLineSegments = Math2D.ConvertLinePointsToLineSegments(referenceLine.Points).ToArray(); - - return GetReferenceLineIntersectionsResult(surfaceLineSegments, referenceLineSegments); - } - - private static ReferenceLineIntersectionResult GetReferenceLineIntersectionsResult(IEnumerable surfaceLineSegments, Segment2D[] referenceLineSegments) - { - Point2D intersectionPoint = null; - foreach (Segment2D surfaceLineSegment in surfaceLineSegments) - { - foreach (Segment2D referenceLineSegment in referenceLineSegments) - { - Segment2DIntersectSegment2DResult result = Math2D.GetIntersectionBetweenSegments(surfaceLineSegment, referenceLineSegment); - - if (result.IntersectionType == Intersection2DType.Intersects) - { - if (intersectionPoint != null) - { - // Early exit as multiple intersections is a return result: - return ReferenceLineIntersectionResult.CreateMultipleIntersectionsOrOverlapResult(); - } - intersectionPoint = result.IntersectionPoints[0]; - } - - if (result.IntersectionType == Intersection2DType.Overlaps) - { - // Early exit as overlap is a return result: - return ReferenceLineIntersectionResult.CreateMultipleIntersectionsOrOverlapResult(); - } - } - } - return intersectionPoint != null - ? ReferenceLineIntersectionResult.CreateIntersectionResult(intersectionPoint) - : ReferenceLineIntersectionResult.CreateNoSingleIntersectionResult(); - } - - private class ReferenceLineIntersectionResult - { - private ReferenceLineIntersectionResult(ReferenceLineIntersectionsResult typeOfIntersection, Point2D intersectionPoint) - { - TypeOfIntersection = typeOfIntersection; - IntersectionPoint = intersectionPoint; - } - - public ReferenceLineIntersectionsResult TypeOfIntersection { get; } - public Point2D IntersectionPoint { get; } - - public static ReferenceLineIntersectionResult CreateNoSingleIntersectionResult() - { - return new ReferenceLineIntersectionResult(ReferenceLineIntersectionsResult.NoIntersections, null); - } - - public static ReferenceLineIntersectionResult CreateIntersectionResult(Point2D point) - { - return new ReferenceLineIntersectionResult(ReferenceLineIntersectionsResult.OneIntersection, point); - } - - public static ReferenceLineIntersectionResult CreateMultipleIntersectionsOrOverlapResult() - { - return new ReferenceLineIntersectionResult(ReferenceLineIntersectionsResult.MultipleIntersectionsOrOverlap, null); - } - } } } \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Importers/RingtoetsPipingSurfaceLineExtensions.cs =================================================================== diff -u -ra940166534b3dd6e778de2e7c8e7e5241f3d3381 -r8e717411be3a9f6947737321832ec2ffe06f43dd --- Ringtoets/Piping/src/Ringtoets.Piping.IO/Importers/RingtoetsPipingSurfaceLineExtensions.cs (.../RingtoetsPipingSurfaceLineExtensions.cs) (revision a940166534b3dd6e778de2e7c8e7e5241f3d3381) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Importers/RingtoetsPipingSurfaceLineExtensions.cs (.../RingtoetsPipingSurfaceLineExtensions.cs) (revision 8e717411be3a9f6947737321832ec2ffe06f43dd) @@ -22,9 +22,9 @@ using System; using Core.Common.Base.Geometry; using log4net; -using Ringtoets.Piping.IO.Properties; +using Ringtoets.Common.IO.Properties; +using Ringtoets.Common.IO.SurfaceLines; using Ringtoets.Piping.Primitives; -using Resources = Ringtoets.Common.IO.Properties.Resources; namespace Ringtoets.Piping.IO.Importers { @@ -197,11 +197,56 @@ return false; } + /// + /// Tries to set the relevant characteristic points from the + /// on the . + /// + /// The surface line to set characteristic points for. + /// The characteristic points to set, if the collection is valid. + /// true if the characteristic points could be set; false otherwise. + /// Thrown when is null. + public static bool SetCharacteristicPoints(this RingtoetsPipingSurfaceLine surfaceLine, CharacteristicPoints characteristicPoints) + { + if (surfaceLine == null) + { + throw new ArgumentNullException(nameof(surfaceLine)); + } + if (characteristicPoints == null || !surfaceLine.ValidateDikeToesInOrder(characteristicPoints)) + { + return false; + } + + surfaceLine.TrySetDitchPolderSide(characteristicPoints.DitchPolderSide); + surfaceLine.TrySetBottomDitchPolderSide(characteristicPoints.BottomDitchPolderSide); + surfaceLine.TrySetBottomDitchDikeSide(characteristicPoints.BottomDitchDikeSide); + surfaceLine.TrySetDitchDikeSide(characteristicPoints.DitchDikeSide); + surfaceLine.TrySetDikeToeAtPolder(characteristicPoints.DikeToeAtPolder); + surfaceLine.TrySetDikeToeAtRiver(characteristicPoints.DikeToeAtRiver); + + return true; + } + private static void LogError(RingtoetsPipingSurfaceLine surfaceLine, ArgumentException e) { log.ErrorFormat(Resources.SurfaceLinesCsvImporter_CharacteristicPoint_of_SurfaceLine_0_skipped_cause_1_, surfaceLine.Name, e.Message); } + + private static bool ValidateDikeToesInOrder(this RingtoetsPipingSurfaceLine readSurfaceLine, CharacteristicPoints characteristicPoints) + { + if (characteristicPoints != null && characteristicPoints.DikeToeAtRiver != null && characteristicPoints.DikeToeAtPolder != null) + { + Point2D localDikeToeAtRiver = readSurfaceLine.GetLocalPointFromGeometry(characteristicPoints.DikeToeAtRiver); + Point2D localDikeToeAtPolder = readSurfaceLine.GetLocalPointFromGeometry(characteristicPoints.DikeToeAtPolder); + + if (localDikeToeAtPolder.X <= localDikeToeAtRiver.X) + { + log.WarnFormat(Resources.SurfaceLinesCsvImporter_CheckCharacteristicPoints_EntryPointL_greater_or_equal_to_ExitPointL_for_0_, characteristicPoints.Name); + return false; + } + } + return true; + } } } \ No newline at end of file Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Importers/RingtoetsPipingSurfaceLineExtensionsTest.cs =================================================================== diff -u -ra940166534b3dd6e778de2e7c8e7e5241f3d3381 -r8e717411be3a9f6947737321832ec2ffe06f43dd --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Importers/RingtoetsPipingSurfaceLineExtensionsTest.cs (.../RingtoetsPipingSurfaceLineExtensionsTest.cs) (revision a940166534b3dd6e778de2e7c8e7e5241f3d3381) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Importers/RingtoetsPipingSurfaceLineExtensionsTest.cs (.../RingtoetsPipingSurfaceLineExtensionsTest.cs) (revision 8e717411be3a9f6947737321832ec2ffe06f43dd) @@ -20,9 +20,12 @@ // All rights reserved. using System; +using System.Collections.Generic; +using System.Linq; using Core.Common.Base.Geometry; using Core.Common.TestUtil; using NUnit.Framework; +using Ringtoets.Common.IO.SurfaceLines; using Ringtoets.Piping.IO.Importers; using Ringtoets.Piping.Primitives; @@ -390,5 +393,202 @@ Assert.IsTrue(result); Assert.AreEqual(point, surfaceLine.DikeToeAtRiver); } + + [Test] + public void SetCharacteristicPoints_SurfaceLineNull_ThrowsArgumentNullException() + { + // Setup + var points = new CharacteristicPoints("swapped dike toes") + { + DikeToeAtPolder = new Point3D(3, 2, 5), + DikeToeAtRiver = new Point3D(3.4, 3, 8), + DitchDikeSide = new Point3D(4.4, 6, 8), + BottomDitchDikeSide = new Point3D(5.1, 6, 6.5), + BottomDitchPolderSide = new Point3D(8.5, 7.2, 4.2), + DitchPolderSide = new Point3D(9.6, 7.5, 3.9) + }; + + // Call + TestDelegate test = () => ((RingtoetsPipingSurfaceLine) null).SetCharacteristicPoints(points); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("surfaceLine", exception.ParamName); + } + + [Test] + public void SetCharacteristicPoints_CharacteristicPointsNull_ReturnsFalseNoCharacteristicPointsSet() + { + // Setup + var surfaceLine = new RingtoetsPipingSurfaceLine(); + surfaceLine.SetGeometry(new[] + { + new Point3D(3, 2, 5), + new Point3D(3.4, 3, 8), + new Point3D(4.4, 6, 8), + new Point3D(5.1, 6, 6.5), + new Point3D(8.5, 7.2, 4.2), + new Point3D(9.6, 7.5, 3.9) + }); + + // Call + bool result = surfaceLine.SetCharacteristicPoints(null); + + // Assert + Assert.IsFalse(result); + Assert.IsNull(surfaceLine.DikeToeAtRiver); + Assert.IsNull(surfaceLine.DikeToeAtPolder); + Assert.IsNull(surfaceLine.DitchDikeSide); + Assert.IsNull(surfaceLine.BottomDitchDikeSide); + Assert.IsNull(surfaceLine.BottomDitchPolderSide); + Assert.IsNull(surfaceLine.DitchPolderSide); + } + + [Test] + public void SetCharacteristicPoints_DikeToesReversed_ReturnsFalseNoCharacteristicPointsSet() + { + // Setup + var points = new CharacteristicPoints("swapped dike toes") + { + DikeToeAtPolder = new Point3D(3, 2, 5), + DikeToeAtRiver = new Point3D(3.4, 3, 8), + DitchDikeSide = new Point3D(4.4, 6, 8), + BottomDitchDikeSide = new Point3D(5.1, 6, 6.5), + BottomDitchPolderSide = new Point3D(8.5, 7.2, 4.2), + DitchPolderSide = new Point3D(9.6, 7.5, 3.9) + }; + var surfaceLine = new RingtoetsPipingSurfaceLine(); + surfaceLine.SetGeometry(CharacteristicPointsToGeometry(points)); + + // Call + bool result = surfaceLine.SetCharacteristicPoints(points); + + // Assert + Assert.IsFalse(result); + Assert.IsNull(surfaceLine.DikeToeAtRiver); + Assert.IsNull(surfaceLine.DikeToeAtPolder); + Assert.IsNull(surfaceLine.DitchDikeSide); + Assert.IsNull(surfaceLine.BottomDitchDikeSide); + Assert.IsNull(surfaceLine.BottomDitchPolderSide); + Assert.IsNull(surfaceLine.DitchPolderSide); + } + + [Test] + [TestCaseSource(nameof(DifferentValidCharacteristicPointConfigurations))] + public void SetCharacteristicPoints_ValidSituations_ReturnsTruePointsAreSet(CharacteristicPoints points) + { + // Setup + var surfaceLine = new RingtoetsPipingSurfaceLine(); + surfaceLine.SetGeometry(CharacteristicPointsToGeometry(points)); + + // Call + bool result = surfaceLine.SetCharacteristicPoints(points); + + // Assert + Assert.IsTrue(result); + Assert.AreEqual(points.DikeToeAtRiver, surfaceLine.DikeToeAtRiver); + Assert.AreEqual(points.DikeToeAtPolder, surfaceLine.DikeToeAtPolder); + Assert.AreEqual(points.DitchDikeSide, surfaceLine.DitchDikeSide); + Assert.AreEqual(points.BottomDitchDikeSide, surfaceLine.BottomDitchDikeSide); + Assert.AreEqual(points.BottomDitchPolderSide, surfaceLine.BottomDitchPolderSide); + Assert.AreEqual(points.DitchPolderSide, surfaceLine.DitchPolderSide); + } + + private static IEnumerable CharacteristicPointsToGeometry(CharacteristicPoints points) + { + return new[] + { + points.DikeToeAtRiver, + points.DikeToeAtPolder, + points.DitchDikeSide, + points.BottomDitchDikeSide, + points.BottomDitchPolderSide, + points.DitchPolderSide + }.Where(p => p != null); + } + + private static IEnumerable DifferentValidCharacteristicPointConfigurations + { + get + { + var dikeToeAtRiver = new Point3D(3, 2, 5); + var dikeToeAtPolder = new Point3D(3.4, 3, 8); + var ditchDikeSide = new Point3D(4.4, 6, 8); + var bottomDitchDikeSide = new Point3D(5.1, 6, 6.5); + var bottomDitchPolderSide = new Point3D(8.5, 7.2, 4.2); + var ditchPolderSide = new Point3D(9.6, 7.5, 3.9); + + var name = "All present"; + yield return new TestCaseData(new CharacteristicPoints(name) + { + DikeToeAtRiver = dikeToeAtRiver, + DikeToeAtPolder = dikeToeAtPolder, + DitchDikeSide = ditchDikeSide, + BottomDitchDikeSide = bottomDitchDikeSide, + BottomDitchPolderSide = bottomDitchPolderSide, + DitchPolderSide = ditchPolderSide + }).SetName(name); + + name = "Missing DikeToeAtRiver"; + yield return new TestCaseData(new CharacteristicPoints(name) + { + DikeToeAtPolder = dikeToeAtPolder, + DitchDikeSide = ditchDikeSide, + BottomDitchDikeSide = bottomDitchDikeSide, + BottomDitchPolderSide = bottomDitchPolderSide, + DitchPolderSide = ditchPolderSide + }).SetName(name); + + name = "Missing DikeToeAtPolder"; + yield return new TestCaseData(new CharacteristicPoints(name) + { + DikeToeAtRiver = dikeToeAtRiver, + DitchDikeSide = ditchDikeSide, + BottomDitchDikeSide = bottomDitchDikeSide, + BottomDitchPolderSide = bottomDitchPolderSide, + DitchPolderSide = ditchPolderSide + }).SetName(name); + + name = "Missing DitchDikeSide"; + yield return new TestCaseData(new CharacteristicPoints(name) + { + DikeToeAtRiver = dikeToeAtRiver, + DikeToeAtPolder = dikeToeAtPolder, + BottomDitchDikeSide = bottomDitchDikeSide, + BottomDitchPolderSide = bottomDitchPolderSide, + DitchPolderSide = ditchPolderSide + }).SetName(name); + + name = "Missing BottomDitchDikeSide"; + yield return new TestCaseData(new CharacteristicPoints(name) + { + DikeToeAtRiver = dikeToeAtRiver, + DikeToeAtPolder = dikeToeAtPolder, + DitchDikeSide = ditchDikeSide, + BottomDitchPolderSide = bottomDitchPolderSide, + DitchPolderSide = ditchPolderSide + }).SetName(name); + + name = "Missing BottomDitchPolderSide"; + yield return new TestCaseData(new CharacteristicPoints(name) + { + DikeToeAtRiver = dikeToeAtRiver, + DikeToeAtPolder = dikeToeAtPolder, + DitchDikeSide = ditchDikeSide, + BottomDitchDikeSide = bottomDitchDikeSide, + DitchPolderSide = ditchPolderSide + }).SetName(name); + + name = "Missing DitchPolderSide"; + yield return new TestCaseData(new CharacteristicPoints(name) + { + DikeToeAtRiver = dikeToeAtRiver, + DikeToeAtPolder = dikeToeAtPolder, + DitchDikeSide = ditchDikeSide, + BottomDitchDikeSide = bottomDitchDikeSide, + BottomDitchPolderSide = bottomDitchPolderSide + }).SetName(name); + } + } } } \ No newline at end of file