// 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.Data; using System.Data.SQLite; using System.Linq; using Core.Common.Base.Geometry; using Core.Common.Base.IO; using Core.Common.IO.Readers; using Core.Common.Util.Builders; using Ringtoets.Common.IO.Exceptions; using Ringtoets.Common.IO.Properties; using Ringtoets.Common.IO.SoilProfile.Schema; namespace Ringtoets.Common.IO.SoilProfile { /// /// This class reads a D-Soil Model file and reads segment points from this database. /// public class SegmentPointReader : SqLiteDatabaseReaderBase { private IDataReader dataReader; /// /// Creates a new instance of which will use the /// as its source. /// /// The path of the database file to open. /// Thrown when: /// /// The contains invalid characters; /// No file could be found at . /// /// public SegmentPointReader(string databaseFilePath) : base(databaseFilePath) {} /// /// Gets a value indicating whether or not more stochastic soil model geometry can be /// read using the . /// public bool HasNext { get; private set; } /// /// Initializes the database. /// /// Thrown when the query to fetch stochastic /// soil model segment points from the database failed. public void Initialize() { CreateDataReader(); MoveNext(); } /// /// Reads the segment points corresponding to the stochastic soil model. /// /// The segment points corresponding to the stochastic soil model. /// Thrown when the geometry could not be read. public IEnumerable ReadSegmentPoints() { return !HasNext ? Enumerable.Empty() : TryReadSegmentPoints(); } /// /// Reads the stochastic soil model id from the data reader. /// /// The stochastic soil model id. /// Thrown when the data reader does not point to a row. public long ReadStochasticSoilModelId() { if (!HasNext) { throw new InvalidOperationException("The reader does not have a row to read."); } return Convert.ToInt64(dataReader[StochasticSoilModelTableDefinitions.StochasticSoilModelId]); } protected override void Dispose(bool disposing) { if (dataReader != null) { dataReader.Close(); dataReader.Dispose(); dataReader = null; } base.Dispose(disposing); } /// /// Tries to read the segment points corresponding to the stochastic soil model. /// /// The segment points corresponding to the stochastic soil model. /// Thrown when the geometry could not be read. private IEnumerable TryReadSegmentPoints() { var segmentPoints = new List(); long currentStochasticSoilModelId = ReadStochasticSoilModelId(); try { while (HasNext && ReadStochasticSoilModelId() == currentStochasticSoilModelId) { segmentPoints.Add(ReadSegmentPoint()); MoveNext(); } } catch (StochasticSoilModelException) { MoveToNextStochasticSoilModel(); throw; } return segmentPoints; } /// /// Moves the reader to the next stochastic soil model. /// private void MoveToNextStochasticSoilModel() { long currentStochasticSoilModelId = ReadStochasticSoilModelId(); while (HasNext && currentStochasticSoilModelId.Equals(ReadStochasticSoilModelId())) { MoveNext(); } } private string ReadStochasticSoilModelSegmentName() { return Convert.ToString(dataReader[StochasticSoilModelTableDefinitions.StochasticSoilModelName]); } /// /// Reads the segment point from the database. /// /// The segment point. /// Thrown when the geometry could not be read. private Point2D ReadSegmentPoint() { object coordinateX = dataReader[SegmentPointsTableDefinitions.CoordinateX]; object coordinateY = dataReader[SegmentPointsTableDefinitions.CoordinateY]; if (coordinateX == Convert.DBNull || coordinateY == Convert.DBNull) { throw new StochasticSoilModelException( string.Format(Resources.SegmentPointReader_ReadSegmentPoint_StochasticSoilModel_0_must_contain_geometry, ReadStochasticSoilModelSegmentName())); } double coordinateXValue = Convert.ToDouble(coordinateX); double coordinateYValue = Convert.ToDouble(coordinateY); return new Point2D(coordinateXValue, coordinateYValue); } /// /// Creates a new . /// /// Thrown when the query to fetch stochastic soil /// model segment points from the database failed. private void CreateDataReader() { string stochasticSoilModelSegmentsQuery = SoilDatabaseQueryBuilder.GetSegmentPointsQuery(); try { dataReader = CreateDataReader(stochasticSoilModelSegmentsQuery); } catch (SQLiteException exception) { string message = new FileReaderErrorMessageBuilder(Path).Build(Resources.StochasticSoilModelDatabaseReader_Failed_to_read_database); throw new CriticalFileReadException(message, exception); } } private void MoveNext() { HasNext = MoveNext(dataReader); } } }