Index: Core/Components/src/Core.Components.Gis.IO/PolylineShapeFileReader.cs =================================================================== diff -u -r33c64ea2cd6b287bf5954e63a548d89dadb7f153 -r5e0d414ac611e8a6fd5b77a41d0459be8b749e83 --- Core/Components/src/Core.Components.Gis.IO/PolylineShapeFileReader.cs (.../PolylineShapeFileReader.cs) (revision 33c64ea2cd6b287bf5954e63a548d89dadb7f153) +++ Core/Components/src/Core.Components.Gis.IO/PolylineShapeFileReader.cs (.../PolylineShapeFileReader.cs) (revision 5e0d414ac611e8a6fd5b77a41d0459be8b749e83) @@ -23,6 +23,7 @@ using System.Data; using System.IO; using System.Linq; + using Core.Common.Base.Geometry; using Core.Common.IO.Exceptions; using Core.Common.Utils; @@ -79,11 +80,6 @@ } } - public void Dispose() - { - lineShapeFile.Close(); - } - /// /// Gets the number of lines in the shapefile. /// @@ -117,6 +113,22 @@ } /// + /// Determines whether the specified attribute has been defined in the shapefile attributes. + /// + /// Name of the attribute. + /// True is the attribute is defined, false otherwise. + /// This check is case-sensitive. + public bool HasAttribute(string attributeName) + { + return lineShapeFile.Attributes.Columns.Any(c => c.ColumnName == attributeName); + } + + public void Dispose() + { + lineShapeFile.Close(); + } + + /// /// Gets the single line feature at the given index. /// /// The index of which feature to retrieve. @@ -128,8 +140,8 @@ if (lineFeature.NumGeometries > 1) { string message = new FileReaderErrorMessageBuilder(filePath) - .WithLocation(string.Format(Properties.Resources.PolylineShapeFileReader_GetSingleLineFeature_At_shapefile_index_0_, index)) - .Build(Properties.Resources.PolylineShapeFileReader_ReadLine_Read_unsupported_multipolyline); + .WithLocation(string.Format(GisIOResources.PolylineShapeFileReader_GetSingleLineFeature_At_shapefile_index_0_, index)) + .Build(GisIOResources.PolylineShapeFileReader_ReadLine_Read_unsupported_multipolyline); throw new ElementReadException(message); } return lineFeature; Index: Core/Components/test/Core.Components.Gis.IO.Test/PolylineShapeFileReaderTest.cs =================================================================== diff -u -r33c64ea2cd6b287bf5954e63a548d89dadb7f153 -r5e0d414ac611e8a6fd5b77a41d0459be8b749e83 --- Core/Components/test/Core.Components.Gis.IO.Test/PolylineShapeFileReaderTest.cs (.../PolylineShapeFileReaderTest.cs) (revision 33c64ea2cd6b287bf5954e63a548d89dadb7f153) +++ Core/Components/test/Core.Components.Gis.IO.Test/PolylineShapeFileReaderTest.cs (.../PolylineShapeFileReaderTest.cs) (revision 5e0d414ac611e8a6fd5b77a41d0459be8b749e83) @@ -266,9 +266,9 @@ public void ReadLine_WhenAtEndOfShapeFile_ReturnNull(string shapeFileName) { // Setup - string shapeWithOneLine = TestHelper.GetTestDataPath(TestDataPath.Core.Components.Gis.IO, - shapeFileName); - using (var reader = new PolylineShapeFileReader(shapeWithOneLine)) + string linesShapefileFilePath = TestHelper.GetTestDataPath(TestDataPath.Core.Components.Gis.IO, + shapeFileName); + using (var reader = new PolylineShapeFileReader(linesShapefileFilePath)) { for (int i = 0; i < reader.GetNumberOfLines(); i++) { @@ -301,5 +301,42 @@ var message = Assert.Throws(call).Message; Assert.AreEqual(expectedMessage, message); } + + [Test] + public void HasAttribute_AttributeInShapefile_ReturnTrue() + { + // Setup + string shapefileFilePath = TestHelper.GetTestDataPath(TestDataPath.Core.Components.Gis.IO, + "Multiple_PolyLine_with_ID.shp"); + using (var reader = new PolylineShapeFileReader(shapefileFilePath)) + { + // Call + bool result = reader.HasAttribute("id"); + + // Assert + Assert.IsTrue(result); + } + } + + [Test] + [TestCase("id", true)] + [TestCase("ID", false)] + [TestCase("Id", false)] + [TestCase("iD", false)] + [TestCase("Im_not_in_file", false)] + public void HasAttribute_VariousCases_ReturnTrueIfMatchesInProperCaseHasBeenFound(string attributeName, bool expectedResult) + { + // Setup + string shapefileFilePath = TestHelper.GetTestDataPath(TestDataPath.Core.Components.Gis.IO, + "Multiple_PolyLine_with_ID.shp"); + using (var reader = new PolylineShapeFileReader(shapefileFilePath)) + { + // Call + bool result = reader.HasAttribute(attributeName); + + // Assert + Assert.AreEqual(expectedResult, result); + } + } } } \ No newline at end of file Index: Ringtoets/Common/src/Ringtoets.Common.IO/FailureMechanismSectionReader.cs =================================================================== diff -u -r428f61c9f1c755c69ea1ff2745e38c1864dad558 -r5e0d414ac611e8a6fd5b77a41d0459be8b749e83 --- Ringtoets/Common/src/Ringtoets.Common.IO/FailureMechanismSectionReader.cs (.../FailureMechanismSectionReader.cs) (revision 428f61c9f1c755c69ea1ff2745e38c1864dad558) +++ Ringtoets/Common/src/Ringtoets.Common.IO/FailureMechanismSectionReader.cs (.../FailureMechanismSectionReader.cs) (revision 5e0d414ac611e8a6fd5b77a41d0459be8b749e83) @@ -69,11 +69,12 @@ /// /// Gets the number of failure mechanism sections in the shapefile. /// + /// When the shapefile does not have + /// a required attribute defined. public int GetFailureMechanismSectionCount() { + ValidateExistenceOfRequiredAttributes(); return polylineShapeFileReader.GetNumberOfLines(); - - // TODO: Validate: Existence of required attributes } /// @@ -82,8 +83,15 @@ /// /// The read from the file, or null /// when at the end of the file. + /// When either: + /// + /// the shapefile does not have a required attribute defined. + /// the element read from the file is a multi-polyline. + /// public FailureMechanismSection ReadFailureMechanismSection() { + ValidateExistenceOfRequiredAttributes(); + var lineData = ReadMapLineData(); if (lineData == null) { @@ -98,6 +106,21 @@ polylineShapeFileReader.Dispose(); } + /// + /// Validates the existence of required attributes. + /// + /// When the shapefile does not have + /// a required attribute defined. + private void ValidateExistenceOfRequiredAttributes() + { + if (!polylineShapeFileReader.HasAttribute(SectionNameAttributeKey)) + { + var message = string.Format(RingtoetsCommonIOResources.FailureMechanismSectionReader_File_lacks_required_Attribute_0_, + SectionNameAttributeKey); + throw new CriticalFileReadException(message); + } + } + private static PolylineShapeFileReader OpenPolyLineShapeFile(string shapeFilePath) { try @@ -112,10 +135,21 @@ } } + /// + /// Reads a new from the file. + /// + /// + /// When the line being read is a multi-polyline. private MapLineData ReadMapLineData() { - MapLineData lineData = polylineShapeFileReader.ReadLine(); - return lineData; + try + { + return polylineShapeFileReader.ReadLine(); + } + catch (ElementReadException e) + { + throw new CriticalFileReadException(RingtoetsCommonIOResources.FailureMechanismSectionReader_File_has_unsupported_multiPolyline, e); + } } private FailureMechanismSection CreateFailureMechanismSection(MapLineData lineData) Index: Ringtoets/Common/src/Ringtoets.Common.IO/Properties/Resources.Designer.cs =================================================================== diff -u -r428f61c9f1c755c69ea1ff2745e38c1864dad558 -r5e0d414ac611e8a6fd5b77a41d0459be8b749e83 --- Ringtoets/Common/src/Ringtoets.Common.IO/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 428f61c9f1c755c69ea1ff2745e38c1864dad558) +++ Ringtoets/Common/src/Ringtoets.Common.IO/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 5e0d414ac611e8a6fd5b77a41d0459be8b749e83) @@ -61,6 +61,24 @@ } /// + /// Looks up a localized string similar to Het bestand heeft een of meerdere multi-polylijnen, welke niet ondersteund worden.. + /// + internal static string FailureMechanismSectionReader_File_has_unsupported_multiPolyline { + get { + return ResourceManager.GetString("FailureMechanismSectionReader_File_has_unsupported_multiPolyline", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Het bestand heeft geen attribuut '{0}' welke vereist is om een vakindeling te importeren.. + /// + internal static string FailureMechanismSectionReader_File_lacks_required_Attribute_0_ { + get { + return ResourceManager.GetString("FailureMechanismSectionReader_File_lacks_required_Attribute_0_", resourceCulture); + } + } + + /// /// Looks up a localized string similar to Bestand mag uitsluitend polylijnen bevatten.. /// internal static string FailureMechanismSectionReader_OpenPolyLineShapeFile_File_can_only_have_polylines { Index: Ringtoets/Common/src/Ringtoets.Common.IO/Properties/Resources.resx =================================================================== diff -u -r428f61c9f1c755c69ea1ff2745e38c1864dad558 -r5e0d414ac611e8a6fd5b77a41d0459be8b749e83 --- Ringtoets/Common/src/Ringtoets.Common.IO/Properties/Resources.resx (.../Resources.resx) (revision 428f61c9f1c755c69ea1ff2745e38c1864dad558) +++ Ringtoets/Common/src/Ringtoets.Common.IO/Properties/Resources.resx (.../Resources.resx) (revision 5e0d414ac611e8a6fd5b77a41d0459be8b749e83) @@ -126,4 +126,10 @@ Bestand mag uitsluitend polylijnen bevatten. + + Het bestand heeft geen attribuut '{0}' welke vereist is om een vakindeling te importeren. + + + Het bestand heeft een of meerdere multi-polylijnen, welke niet ondersteund worden. + \ No newline at end of file Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/FailureMechanismSectionReaderTest.cs =================================================================== diff -u -r428f61c9f1c755c69ea1ff2745e38c1864dad558 -r5e0d414ac611e8a6fd5b77a41d0459be8b749e83 --- Ringtoets/Common/test/Ringtoets.Common.IO.Test/FailureMechanismSectionReaderTest.cs (.../FailureMechanismSectionReaderTest.cs) (revision 428f61c9f1c755c69ea1ff2745e38c1864dad558) +++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/FailureMechanismSectionReaderTest.cs (.../FailureMechanismSectionReaderTest.cs) (revision 5e0d414ac611e8a6fd5b77a41d0459be8b749e83) @@ -138,8 +138,24 @@ } } - // TODO: GetFailureMechanismSectionCount : Required attributes missing -> Throw exception + [Test] + public void GetFailureMechanismSectionCount_FileLacksNameAttribute_ThrowCriticalFileReadException() + { + // Setup + string validFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, + "traject_227_vakken_LacksVaknaamAttribute.shp"); + using (var reader = new FailureMechanismSectionReader(validFilePath)) + { + // Call + TestDelegate call = () => reader.GetFailureMechanismSectionCount(); + + // Assert + var message = Assert.Throws(call).Message; + Assert.AreEqual("Het bestand heeft geen attribuut 'Vaknaam' welke vereist is om een vakindeling te importeren.", message); + } + } + [Test] public void ReadFailureMechanismSection_ValidFilePath1_ReturnElement() { @@ -232,6 +248,47 @@ } } - // TODO: Reading file with Multi-polyline + [Test] + public void ReadFailureMechanismSection_FileLacksNameAttribute_ThrowCriticalFileReadException() + { + // Setup + string validFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, + "traject_227_vakken_LacksVaknaamAttribute.shp"); + + using (var reader = new FailureMechanismSectionReader(validFilePath)) + { + // Call + TestDelegate call = () => reader.ReadFailureMechanismSection(); + + // Assert + var message = Assert.Throws(call).Message; + Assert.AreEqual("Het bestand heeft geen attribuut 'Vaknaam' welke vereist is om een vakindeling te importeren.", message); + } + } + + [Test] + public void ReadFailureMechanismSection_FileHadMultiPolylines_ThrowCriticalFileReadException() + { + // Setup + string validFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, + "Artificial_MultiPolyline_vakken.shp"); + + using (var reader = new FailureMechanismSectionReader(validFilePath)) + { + // Call + TestDelegate call = () => + { + reader.ReadFailureMechanismSection(); + reader.ReadFailureMechanismSection(); + reader.ReadFailureMechanismSection(); + reader.ReadFailureMechanismSection(); + }; + + + // Assert + var message = Assert.Throws(call).Message; + Assert.AreEqual("Het bestand heeft een of meerdere multi-polylijnen, welke niet ondersteund worden.", message); + } + } } } \ No newline at end of file Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_MultiPolyline_vakken.dbf =================================================================== diff -u Binary files differ Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_MultiPolyline_vakken.prj =================================================================== diff -u --- Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_MultiPolyline_vakken.prj (revision 0) +++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_MultiPolyline_vakken.prj (revision 5e0d414ac611e8a6fd5b77a41d0459be8b749e83) @@ -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_MultiPolyline_vakken.qpj =================================================================== diff -u --- Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_MultiPolyline_vakken.qpj (revision 0) +++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_MultiPolyline_vakken.qpj (revision 5e0d414ac611e8a6fd5b77a41d0459be8b749e83) @@ -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_MultiPolyline_vakken.shp =================================================================== diff -u Binary files differ Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/Artificial_MultiPolyline_vakken.shx =================================================================== diff -u Binary files differ Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/traject_227_vakken_LacksVaknaamAttribute.dbf =================================================================== diff -u Binary files differ Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/traject_227_vakken_LacksVaknaamAttribute.prj =================================================================== diff -u --- Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/traject_227_vakken_LacksVaknaamAttribute.prj (revision 0) +++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/traject_227_vakken_LacksVaknaamAttribute.prj (revision 5e0d414ac611e8a6fd5b77a41d0459be8b749e83) @@ -0,0 +1 @@ +PROJCS["RD_New",GEOGCS["GCS_Amersfoort",DATUM["D_Amersfoort",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Double_Stereographic"],PARAMETER["False_Easting",155000.0],PARAMETER["False_Northing",463000.0],PARAMETER["Central_Meridian",5.38763888888889],PARAMETER["Scale_Factor",0.9999079],PARAMETER["Latitude_Of_Origin",52.15616055555555],UNIT["Meter",1.0]] \ No newline at end of file Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/traject_227_vakken_LacksVaknaamAttribute.shp =================================================================== diff -u Binary files differ Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/traject_227_vakken_LacksVaknaamAttribute.shx =================================================================== diff -u Binary files differ