Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_EmptyVakken.dbf =================================================================== diff -u Binary files differ Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_EmptyVakken.prj =================================================================== diff -u --- Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_EmptyVakken.prj (revision 0) +++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_EmptyVakken.prj (revision 031999777327a1b802c1a1e05d8ce303277f9c49) @@ -0,0 +1 @@ +GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] \ No newline at end of file Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_EmptyVakken.qpj =================================================================== diff -u --- Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_EmptyVakken.qpj (revision 0) +++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_EmptyVakken.qpj (revision 031999777327a1b802c1a1e05d8ce303277f9c49) @@ -0,0 +1 @@ +GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]] Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_EmptyVakken.shp =================================================================== diff -u Binary files differ Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_EmptyVakken.shx =================================================================== diff -u Binary files differ Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_InvalidVakken_SectionEndTooFarFromReferenceline.dbf =================================================================== diff -u Binary files differ Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_InvalidVakken_SectionEndTooFarFromReferenceline.prj =================================================================== diff -u --- Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_InvalidVakken_SectionEndTooFarFromReferenceline.prj (revision 0) +++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_InvalidVakken_SectionEndTooFarFromReferenceline.prj (revision 031999777327a1b802c1a1e05d8ce303277f9c49) @@ -0,0 +1 @@ +PROJCS["Amersfoort_RD_New",GEOGCS["GCS_Amersfoort",DATUM["D_Amersfoort",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Double_Stereographic"],PARAMETER["latitude_of_origin",52.15616055555555],PARAMETER["central_meridian",5.38763888888889],PARAMETER["scale_factor",0.9999079],PARAMETER["false_easting",155000],PARAMETER["false_northing",463000],UNIT["Meter",1]] \ No newline at end of file Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_InvalidVakken_SectionEndTooFarFromReferenceline.qpj =================================================================== diff -u --- Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_InvalidVakken_SectionEndTooFarFromReferenceline.qpj (revision 0) +++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_InvalidVakken_SectionEndTooFarFromReferenceline.qpj (revision 031999777327a1b802c1a1e05d8ce303277f9c49) @@ -0,0 +1 @@ +PROJCS["Amersfoort / RD New",GEOGCS["Amersfoort",DATUM["Amersfoort",SPHEROID["Bessel 1841",6377397.155,299.1528128,AUTHORITY["EPSG","7004"]],TOWGS84[565.417,50.3319,465.552,-0.398957,0.343988,-1.8774,4.0725],AUTHORITY["EPSG","6289"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4289"]],PROJECTION["Oblique_Stereographic"],PARAMETER["latitude_of_origin",52.15616055555555],PARAMETER["central_meridian",5.38763888888889],PARAMETER["scale_factor",0.9999079],PARAMETER["false_easting",155000],PARAMETER["false_northing",463000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["X",EAST],AXIS["Y",NORTH],AUTHORITY["EPSG","28992"]] Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_InvalidVakken_SectionEndTooFarFromReferenceline.shp =================================================================== diff -u Binary files differ Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_InvalidVakken_SectionEndTooFarFromReferenceline.shx =================================================================== diff -u Binary files differ Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_InvalidVakken_SectionStartTooFarFromReferenceline.dbf =================================================================== diff -u Binary files differ Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_InvalidVakken_SectionStartTooFarFromReferenceline.prj =================================================================== diff -u --- Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_InvalidVakken_SectionStartTooFarFromReferenceline.prj (revision 0) +++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_InvalidVakken_SectionStartTooFarFromReferenceline.prj (revision 031999777327a1b802c1a1e05d8ce303277f9c49) @@ -0,0 +1 @@ +PROJCS["Amersfoort_RD_New",GEOGCS["GCS_Amersfoort",DATUM["D_Amersfoort",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Double_Stereographic"],PARAMETER["latitude_of_origin",52.15616055555555],PARAMETER["central_meridian",5.38763888888889],PARAMETER["scale_factor",0.9999079],PARAMETER["false_easting",155000],PARAMETER["false_northing",463000],UNIT["Meter",1]] \ No newline at end of file Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_InvalidVakken_SectionStartTooFarFromReferenceline.qpj =================================================================== diff -u --- Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_InvalidVakken_SectionStartTooFarFromReferenceline.qpj (revision 0) +++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_InvalidVakken_SectionStartTooFarFromReferenceline.qpj (revision 031999777327a1b802c1a1e05d8ce303277f9c49) @@ -0,0 +1 @@ +PROJCS["Amersfoort / RD New",GEOGCS["Amersfoort",DATUM["Amersfoort",SPHEROID["Bessel 1841",6377397.155,299.1528128,AUTHORITY["EPSG","7004"]],TOWGS84[565.417,50.3319,465.552,-0.398957,0.343988,-1.8774,4.0725],AUTHORITY["EPSG","6289"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4289"]],PROJECTION["Oblique_Stereographic"],PARAMETER["latitude_of_origin",52.15616055555555],PARAMETER["central_meridian",5.38763888888889],PARAMETER["scale_factor",0.9999079],PARAMETER["false_easting",155000],PARAMETER["false_northing",463000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["X",EAST],AXIS["Y",NORTH],AUTHORITY["EPSG","28992"]] Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_InvalidVakken_SectionStartTooFarFromReferenceline.shp =================================================================== diff -u Binary files differ Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_InvalidVakken_SectionStartTooFarFromReferenceline.shx =================================================================== diff -u Binary files differ Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_ValidVakken.shp =================================================================== diff -u -r816b69a61b755731102fd3e0d4552e19a8b6d439 -r031999777327a1b802c1a1e05d8ce303277f9c49 Binary files differ Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_referencelijn_testA_ValidVakken.shx =================================================================== diff -u -r816b69a61b755731102fd3e0d4552e19a8b6d439 -r031999777327a1b802c1a1e05d8ce303277f9c49 Binary files differ Index: Ringtoets/Integration/src/Ringtoets.Integration.Plugin/FileImporters/FailureMechanismSectionsImporter.cs =================================================================== diff -u -r816b69a61b755731102fd3e0d4552e19a8b6d439 -r031999777327a1b802c1a1e05d8ce303277f9c49 --- Ringtoets/Integration/src/Ringtoets.Integration.Plugin/FileImporters/FailureMechanismSectionsImporter.cs (.../FailureMechanismSectionsImporter.cs) (revision 816b69a61b755731102fd3e0d4552e19a8b6d439) +++ Ringtoets/Integration/src/Ringtoets.Integration.Plugin/FileImporters/FailureMechanismSectionsImporter.cs (.../FailureMechanismSectionsImporter.cs) (revision 031999777327a1b802c1a1e05d8ce303277f9c49) @@ -27,6 +27,7 @@ /// public class FailureMechanismSectionsImporter : FileImporterBase { + private const double snapLimit = 1; private static readonly ILog log = LogManager.GetLogger(typeof(FailureMechanismSectionsImporter)); public override string Name @@ -73,14 +74,27 @@ public override bool Import(object targetItem, string filePath) { + var context = (FailureMechanismSectionsContext)targetItem; + if (context.ParentAssessmentSection.ReferenceLine == null) + { + LogCriticalFileReadError(Resources.FailureMechanismSectionsImporter_Import_Required_referenceline_missing); + return false; + } + ReadResult readResults = ReadFailureMechanismSections(filePath); if (readResults.CriticalErrorOccurred) { return false; } - AddImportedDataToModel(targetItem, readResults); + if (!SectionsCorrespondToReferenceLine(context, readResults)) + { + LogCriticalFileReadError("Vakkenindeling komt niet overeen met de huidige referentielijn."); + return false; + } + + AddImportedDataToModel(context, readResults); return true; } @@ -119,6 +133,11 @@ try { var count = reader.GetFailureMechanismSectionCount(); + if (count == 0) + { + LogCriticalFileReadError(Resources.FailureMechanismSectionsImporter_ReadFile_File_is_empty); + return new ReadResult(true); + } var importedSections = new FailureMechanismSection[count]; for (int i = 0; i < count; i++) @@ -140,14 +159,40 @@ private void LogCriticalFileReadError(Exception exception) { + LogCriticalFileReadError(exception.Message); + } + + private void LogCriticalFileReadError(string message) + { var errorMessage = String.Format(Resources.FailureMechanismSectionsImporter_CriticalErrorMessage_0_No_sections_imported, - exception.Message); + message); log.Error(errorMessage); } - private void AddImportedDataToModel(object targetItem, ReadResult readResults) + private bool SectionsCorrespondToReferenceLine(FailureMechanismSectionsContext context, ReadResult readResults) { - var context = (FailureMechanismSectionsContext)targetItem; + ICollection failureMechanismSections = readResults.ImportedItems; + IEnumerable allStartAndEndPoints = failureMechanismSections.Select(s => s.GetStart()).Concat(failureMechanismSections.Select(s => s.GetLast())); + foreach (Point2D point in allStartAndEndPoints) + { + if (GetDistanceToReferenceLine(point, context.ParentAssessmentSection.ReferenceLine) > snapLimit) + { + return false; + } + } + + return true; + } + + private double GetDistanceToReferenceLine(Point2D point, ReferenceLine referenceLine) + { + return GetLineSegments(referenceLine.Points) + .Select(segment => segment.GetEuclideanDistanceToPoint(point)) + .Min(); + } + + private void AddImportedDataToModel(FailureMechanismSectionsContext context, ReadResult readResults) + { IEnumerable snappedSections = SnapReadSectionsToReferenceLine(readResults.ImportedItems, context.ParentAssessmentSection.ReferenceLine); foreach (FailureMechanismSection section in snappedSections) { @@ -205,14 +250,11 @@ private void GrowTowardsEnd(List resultList, List sourceList) { - const double snapLimit = 1; - bool doneGrowingToEnd = false; while (!doneGrowingToEnd) { Point2D endPointToConnect = resultList[resultList.Count - 1].GetLast(); - var shortestDistance = double.MaxValue; FailureMechanismSection closestSectionToConnectWith = null; Dictionary sectionConnectionDistances = sourceList.ToDictionary(s => endPointToConnect.GetEuclideanDistanceTo(s.GetStart()), s => s); @@ -239,8 +281,6 @@ private void GrowTowardsStart(List resultList, List sourceList) { - const double snapLimit = 1; - bool doneGrowingToStart = false; while (!doneGrowingToStart) { @@ -277,17 +317,7 @@ private IEnumerable GetLineSegments(IEnumerable linePoints) { - Point2D endPoint = null; - foreach (Point2D linePoint in linePoints) - { - Point2D startPoint = endPoint; - endPoint = linePoint; - - if (startPoint != null) - { - yield return new Segment2D(startPoint, endPoint); - } - } + return Math2D.ConvertLinePointsToLineSegments(linePoints); } } } \ No newline at end of file Index: Ringtoets/Integration/src/Ringtoets.Integration.Plugin/Properties/Resources.Designer.cs =================================================================== diff -u -rd066b31047707b6fb1453bd83a65fe773b5838cb -r031999777327a1b802c1a1e05d8ce303277f9c49 --- Ringtoets/Integration/src/Ringtoets.Integration.Plugin/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision d066b31047707b6fb1453bd83a65fe773b5838cb) +++ Ringtoets/Integration/src/Ringtoets.Integration.Plugin/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 031999777327a1b802c1a1e05d8ce303277f9c49) @@ -71,6 +71,33 @@ } /// + /// Looks up a localized string similar to Er is geen referentielijn beschikbaar om een vakindeling voor de definiëren.. + /// + internal static string FailureMechanismSectionsImporter_Import_Required_reference_line_is_missing { + get { + return ResourceManager.GetString("FailureMechanismSectionsImporter_Import_Required_reference_line_is_missing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Er is geen referentielijn beschikbaar om een vakindeling voor de definiëren.. + /// + internal static string FailureMechanismSectionsImporter_Import_Required_referenceline_missing { + get { + return ResourceManager.GetString("FailureMechanismSectionsImporter_Import_Required_referenceline_missing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Het bestand heeft geen vakindeling.. + /// + internal static string FailureMechanismSectionsImporter_ReadFile_File_is_empty { + get { + return ResourceManager.GetString("FailureMechanismSectionsImporter_ReadFile_File_is_empty", resourceCulture); + } + } + + /// /// Looks up a localized string similar to {0} Het bestand wordt overgeslagen.. /// internal static string HydraulicBoundaryDatabaseImporter_ErrorMessage_0_file_skipped { Index: Ringtoets/Integration/src/Ringtoets.Integration.Plugin/Properties/Resources.resx =================================================================== diff -u -rd066b31047707b6fb1453bd83a65fe773b5838cb -r031999777327a1b802c1a1e05d8ce303277f9c49 --- Ringtoets/Integration/src/Ringtoets.Integration.Plugin/Properties/Resources.resx (.../Resources.resx) (revision d066b31047707b6fb1453bd83a65fe773b5838cb) +++ Ringtoets/Integration/src/Ringtoets.Integration.Plugin/Properties/Resources.resx (.../Resources.resx) (revision 031999777327a1b802c1a1e05d8ce303277f9c49) @@ -154,4 +154,13 @@ {0} Er is geen vakindeling geïmporteerd. + + Er is geen referentielijn beschikbaar om een vakindeling voor de definiëren. + + + Er is geen referentielijn beschikbaar om een vakindeling voor de definiëren. + + + Het bestand heeft geen vakindeling. + \ No newline at end of file Index: Ringtoets/Integration/test/Ringtoets.Integration.Plugin.Test/FileImporters/FailureMechanismSectionsImporterTest.cs =================================================================== diff -u -r816b69a61b755731102fd3e0d4552e19a8b6d439 -r031999777327a1b802c1a1e05d8ce303277f9c49 --- Ringtoets/Integration/test/Ringtoets.Integration.Plugin.Test/FileImporters/FailureMechanismSectionsImporterTest.cs (.../FailureMechanismSectionsImporterTest.cs) (revision 816b69a61b755731102fd3e0d4552e19a8b6d439) +++ Ringtoets/Integration/test/Ringtoets.Integration.Plugin.Test/FileImporters/FailureMechanismSectionsImporterTest.cs (.../FailureMechanismSectionsImporterTest.cs) (revision 031999777327a1b802c1a1e05d8ce303277f9c49) @@ -176,16 +176,112 @@ mocks.VerifyAll(); } - // TODO: ReferenceLine not set - // TODO: Has endpoint not on surfaceline - // TODO: Has startpoint not on surfaceline + [Test] + public void Import_NoReferenceLine_CancelImportWithErrorMessage() + { + // Setup + var sectionsFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, "traject_1-1_vakken.shp"); + + var mocks = new MockRepository(); + var assessmentSection = mocks.Stub(); + assessmentSection.ReferenceLine = null; + mocks.ReplayAll(); + + var importer = new FailureMechanismSectionsImporter(); + + var failureMechanism = new SimpleFailureMechanism(); + var failureMechanismSectionsContext = new FailureMechanismSectionsContext(failureMechanism, assessmentSection); + + // Call + bool importSuccesful = true; + Action call = () => importSuccesful = importer.Import(failureMechanismSectionsContext, sectionsFilePath); + + // Assert + var expectedMessage = "Er is geen referentielijn beschikbaar om een vakindeling voor de definiëren." + Environment.NewLine + + "Er is geen vakindeling geïmporteerd."; + TestHelper.AssertLogMessageIsGenerated(call, expectedMessage, 1); + Assert.IsFalse(importSuccesful); + CollectionAssert.IsEmpty(failureMechanism.Sections); + CollectionAssert.IsEmpty(failureMechanismSectionsContext.WrappedData); + mocks.VerifyAll(); + } + + [Test] + public void Import_EmptyArtificialFile_CancelImportWithErrorMessage() + { + // Setup + var referenceLineFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, "Artificial_referencelijn_testA.shp"); + var sectionsFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, "Artificial_referencelijn_testA_EmptyVakken.shp"); + + var mocks = new MockRepository(); + var assessmentSection = mocks.Stub(); + mocks.ReplayAll(); + + var referenceLineContext = new ReferenceLineContext(assessmentSection); + + var referenceLineImporter = new ReferenceLineImporter(); + referenceLineImporter.Import(referenceLineContext, referenceLineFilePath); + + var importer = new FailureMechanismSectionsImporter(); + + var failureMechanism = new SimpleFailureMechanism(); + var failureMechanismSectionsContext = new FailureMechanismSectionsContext(failureMechanism, assessmentSection); + + // Call + bool importSuccesful = true; + Action call = () => importSuccesful = importer.Import(failureMechanismSectionsContext, sectionsFilePath); + + // Assert + var expectedMessage = "Het bestand heeft geen vakindeling." + Environment.NewLine + + "Er is geen vakindeling geïmporteerd."; + TestHelper.AssertLogMessageIsGenerated(call, expectedMessage, 1); + Assert.IsFalse(importSuccesful); + CollectionAssert.IsEmpty(failureMechanism.Sections); + CollectionAssert.IsEmpty(failureMechanismSectionsContext.WrappedData); + mocks.VerifyAll(); + } + + [Test] + [TestCase("Artificial_referencelijn_testA_InvalidVakken_SectionStartTooFarFromReferenceline.shp")] + [TestCase("Artificial_referencelijn_testA_InvalidVakken_SectionEndTooFarFromReferenceline.shp")] + public void Import_InvalidArtificialFileBecauseOfStartEndPointsTooFarFromReferenceLine_CancelImportWithErrorMessage(string shapeFileName) + { + // Setup + var referenceLineFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, "Artificial_referencelijn_testA.shp"); + var sectionsFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, shapeFileName); + + var mocks = new MockRepository(); + var assessmentSection = mocks.Stub(); + mocks.ReplayAll(); + + var referenceLineContext = new ReferenceLineContext(assessmentSection); + + var referenceLineImporter = new ReferenceLineImporter(); + referenceLineImporter.Import(referenceLineContext, referenceLineFilePath); + + var importer = new FailureMechanismSectionsImporter(); + + var failureMechanism = new SimpleFailureMechanism(); + var failureMechanismSectionsContext = new FailureMechanismSectionsContext(failureMechanism, assessmentSection); + + // Call + bool importSuccesful = true; + Action call = () => importSuccesful = importer.Import(failureMechanismSectionsContext, sectionsFilePath); + + // Assert + var expectedMessage = "Vakkenindeling komt niet overeen met de huidige referentielijn." + Environment.NewLine + + "Er is geen vakindeling geïmporteerd."; + TestHelper.AssertLogMessageIsGenerated(call, expectedMessage, 1); + Assert.IsFalse(importSuccesful); + CollectionAssert.IsEmpty(failureMechanism.Sections); + CollectionAssert.IsEmpty(failureMechanismSectionsContext.WrappedData); + mocks.VerifyAll(); + } + // TODO: Has some other point not on surfaceline // TODO: Definite start not on refereline start // TODO: Definite end not on referenceline end - // TODO: File is empty -> error - // TODO: Has sections and Confirm cancel -> No changes and return false - // TODO: Has sections and Confirm continue -> replace sections, clear failure mechanism calculations - // TODO: Has sections and Cancel during Confirm -> generate log message + // TODO: Has sections -> Replace // TODO: Progress // TODO: Reused of cancelled importer // TODO: DoPostImportUpdates when clearing failure mechanism calculations