// 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.IO; using System.Linq; using Core.Common.Base.Geometry; using Core.Common.Base.IO; using Core.Common.Util; using Core.Common.Util.Builders; using Core.Common.Util.Properties; using Core.Components.Gis.Data; using Core.Components.Gis.Features; using Core.Components.Gis.Geometries; using Core.Components.Gis.IO.Readers; using Ringtoets.Common.Data.AssessmentSection; using RingtoetsCommonIOResources = Ringtoets.Common.IO.Properties.Resources; namespace Ringtoets.Common.IO.ReferenceLines { /// /// Shape file reader that reads objects based on the line feature in the file. /// public static class ReferenceLinesMetaReader { private const string assessmentsectionIdAttributeKey = "TRAJECT_ID"; private const string signalingValueAttributeKey = "NORM_SW"; private const string lowerLimitValueAttributeKey = "NORM_OG"; /// /// Reads the current features in the shape file into a collection of objects. /// /// The file path to the shape file. /// The created collection of objects. /// Thrown when is invalid. /// Thrown when current feature in the shape file: /// /// points to a file that does not exist. /// The shape file does not contain the mandatory attributes. /// Has an empty attribute. /// The shape file has non-line geometries in it. /// public static IEnumerable ReadReferenceLinesMetas(string shapeFilePath) { ValidateFilePath(shapeFilePath); using (PolylineShapeFileReader reader = OpenPolyLineShapeFile(shapeFilePath)) { ValidateExistenceOfRequiredAttributes(reader, shapeFilePath); return ReadReferenceLinesMetas(reader); } } private static IEnumerable ReadReferenceLinesMetas(PolylineShapeFileReader reader) { var referenceLinesMetas = new List(); ReferenceLineMeta referenceLinesMeta; do { referenceLinesMeta = ReadReferenceLinesMeta(reader); if (referenceLinesMeta != null) { referenceLinesMetas.Add(referenceLinesMeta); } } while (referenceLinesMeta != null); return referenceLinesMetas; } private static ReferenceLineMeta ReadReferenceLinesMeta(PolylineShapeFileReader reader) { MapLineData lineData = ReadMapLineData(reader); return lineData == null ? null : CreateReferenceLineMeta(lineData); } /// /// Validates the . /// /// The file path to the shape file. /// Thrown when is invalid. /// Thrown when does not exist. private static void ValidateFilePath(string shapeFilePath) { IOUtils.ValidateFilePath(shapeFilePath); if (!File.Exists(shapeFilePath)) { string message = new FileReaderErrorMessageBuilder(shapeFilePath) .Build(Resources.Error_File_does_not_exist); throw new CriticalFileReadException(message); } } /// /// Validates the file by checking if all mandatory attributes are present in the shape file. /// /// The opened shape file reader. /// The file path to the shape file. /// Thrown when the shape file lacks one of the mandatory attributes. private static void ValidateExistenceOfRequiredAttributes(PolylineShapeFileReader polylineShapeFileReader, string shapeFilePath) { IEnumerable missingAttributes = GetMissingAttributes(polylineShapeFileReader); if (missingAttributes.Any()) { string message = string.Format(RingtoetsCommonIOResources.ReferenceLinesMetaReader_File_0_lacks_required_Attribute_1_, shapeFilePath, string.Join("', '", missingAttributes)); throw new CriticalFileReadException(message); } } private static IEnumerable GetMissingAttributes(PolylineShapeFileReader polylineShapeFileReader) { if (!polylineShapeFileReader.HasAttribute(assessmentsectionIdAttributeKey)) { yield return assessmentsectionIdAttributeKey; } if (!polylineShapeFileReader.HasAttribute(signalingValueAttributeKey)) { yield return signalingValueAttributeKey; } if (!polylineShapeFileReader.HasAttribute(lowerLimitValueAttributeKey)) { yield return lowerLimitValueAttributeKey; } } /// /// Opens a new to . /// /// Path to the shape file to read. /// A new instance of the class. /// Thrown when is invalid. /// Thrown when: /// /// points to a file that does not exist. /// The shape file has non-line geometries in it. /// /// private static PolylineShapeFileReader OpenPolyLineShapeFile(string shapeFilePath) { return new PolylineShapeFileReader(shapeFilePath); } private static MapLineData ReadMapLineData(PolylineShapeFileReader polylineShapeFileReader) { return (MapLineData) polylineShapeFileReader.ReadFeature(); } /// /// Creates a new from the . /// /// The to create a from. /// The newly created . private static ReferenceLineMeta CreateReferenceLineMeta(MapLineData lineData) { MapFeature feature = lineData.Features.First(); string assessmentSectionId = GetAssessmentSectionId(feature); int? signalingValue = ParseNormValue(feature.MetaData[signalingValueAttributeKey]); int? lowerLimitValue = ParseNormValue(feature.MetaData[lowerLimitValueAttributeKey]); IEnumerable geometryPoints = GetSectionGeometry(feature); var referenceLineMeta = new ReferenceLineMeta { AssessmentSectionId = assessmentSectionId }; if (lowerLimitValue != null) { referenceLineMeta.LowerLimitValue = lowerLimitValue.Value; } if (signalingValue != null) { referenceLineMeta.SignalingValue = signalingValue.Value; } referenceLineMeta.ReferenceLine.SetGeometry(geometryPoints); return referenceLineMeta; } /// /// Gets the geometry from the . /// /// The to get the geometry from. /// A collection that represents the 's geometry. private static IEnumerable GetSectionGeometry(MapFeature lineFeature) { MapGeometry[] mapGeometries = lineFeature.MapGeometries.ToArray(); if (mapGeometries.Length != 1) { return Enumerable.Empty(); } return mapGeometries[0].PointCollections.First().Select(p => new Point2D(p)).ToArray(); } private static string GetAssessmentSectionId(MapFeature lineFeature) { return Convert.ToString(lineFeature.MetaData[assessmentsectionIdAttributeKey]); } private static int? ParseNormValue(object readObject) { try { return readObject == null ? (int?) null : Convert.ToInt32(readObject); } catch (Exception exception) { if (exception is InvalidCastException || exception is FormatException || exception is OverflowException) { return null; } throw; } } } }