// Copyright (C) Stichting Deltares 2016. 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 Core.Common.IO.Exceptions; using Core.Common.Utils; using Core.Common.Utils.Builders; using Core.Components.Gis.Data; using Core.Components.Gis.Features; using Core.Components.Gis.IO.Readers; using Ringtoets.Common.Data.FailureMechanism; using CoreCommonUtilsResources = Core.Common.Utils.Properties.Resources; using RingtoetsCommonIOResources = Ringtoets.Common.IO.Properties.Resources; namespace Ringtoets.Common.IO { /// /// Reads instances from a shapefile containing /// one or multiple line features. /// public class FailureMechanismSectionReader : IDisposable { private const string sectionNameAttributeKey = "Vaknaam"; private readonly PolylineShapeFileReader polylineShapeFileReader; private readonly string filePath; /// /// Initializes a new instance of the class. /// /// The shape file path. /// is invalid. /// Thrown when either: /// /// points to a file that doesn't exist. /// The shapefile has non-line geometries in it. /// An unexpected error occurred when reading the shapefile. /// /// public FailureMechanismSectionReader(string shapeFilePath) { FileUtils.ValidateFilePath(shapeFilePath); filePath = shapeFilePath; polylineShapeFileReader = new PolylineShapeFileReader(filePath); } /// /// Gets the number of failure mechanism sections in the shapefile. /// /// Thrown when the shapefile does not have /// a required attribute defined. public int GetFailureMechanismSectionCount() { ValidateExistenceOfRequiredAttributes(); return polylineShapeFileReader.GetNumberOfFeatures(); } /// /// Reads and consumes an entry in the shapefile, using the data to create a new /// instance of . /// /// The read from the file, or null /// when at the end of the file. /// Thrown 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(); return lineData == null ? null : CreateFailureMechanismSection(lineData); } public void Dispose() { polylineShapeFileReader.Dispose(); } /// /// Validates the existence of required attributes. /// /// Thrown when the shapefile does not have /// a required attribute defined. private void ValidateExistenceOfRequiredAttributes() { if (!polylineShapeFileReader.HasAttribute(sectionNameAttributeKey)) { throw CreateCriticalFileReadException( string.Format(RingtoetsCommonIOResources.FailureMechanismSectionReader_File_lacks_required_Attribute_0_, sectionNameAttributeKey)); } } /// /// Reads a new from the file. /// /// private MapLineData ReadMapLineData() { return polylineShapeFileReader.ReadFeature() as MapLineData; } private FailureMechanismSection CreateFailureMechanismSection(MapLineData lineData) { var features = lineData.Features.ToArray(); if (features.Length > 1) { throw CreateCriticalFileReadException(RingtoetsCommonIOResources.FailureMechanismSectionReader_File_has_unsupported_multiPolyline); } var feature = features[0]; string name = GetSectionName(feature); IEnumerable geometryPoints = GetSectionGeometry(feature); return new FailureMechanismSection(name, geometryPoints); } private string GetSectionName(MapFeature lineFeature) { var sectionName = lineFeature.MetaData[sectionNameAttributeKey] as string; if (string.IsNullOrWhiteSpace(sectionName)) { throw CreateCriticalFileReadException(RingtoetsCommonIOResources.FailureMechanismSectionReader_File_has_section_without_sectionName); } return sectionName; } private IEnumerable GetSectionGeometry(MapFeature lineFeature) { var mapGeometries = lineFeature.MapGeometries.ToArray(); if (mapGeometries.Length > 1) { throw CreateCriticalFileReadException(RingtoetsCommonIOResources.FailureMechanismSectionReader_File_has_unsupported_multiPolyline); } return mapGeometries[0].PointCollections.First().Select(p => new Point2D(p.X, p.Y)); } private CriticalFileReadException CreateCriticalFileReadException(string message) { var wrappedMessage = new FileReaderErrorMessageBuilder(filePath).Build(message); return new CriticalFileReadException(wrappedMessage); } } }