// 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.Data; using Ringtoets.Common.Data.Calculation; using Ringtoets.Common.Data.DikeProfiles; using Ringtoets.Common.Data.Hydraulics; using Ringtoets.Common.IO.FileImporters; using Ringtoets.GrassCoverErosionInwards.Data; using Ringtoets.GrassCoverErosionInwards.IO.Properties; using Ringtoets.GrassCoverErosionInwards.IO.Readers; using RingtoetsCommonIOResources = Ringtoets.Common.IO.Properties.Resources; namespace Ringtoets.GrassCoverErosionInwards.IO.Importers { public class GrassCoverErosionInwardsCalculationConfigurationImporter : CalculationConfigurationImporter { private readonly IEnumerable availableHydraulicBoundaryLocations; private readonly IEnumerable availableDikeProfiles; /// /// Creates a new instance of . /// /// The path to the XML file to import from. /// The calculation group to update. /// The hydraulic boundary locations /// used to check if the imported objects contain the right location. /// The dike profiles used to check if /// the imported objects contain the right profile. /// Thrown when any parameter is /// null. public GrassCoverErosionInwardsCalculationConfigurationImporter( string xmlFilePath, CalculationGroup importTarget, IEnumerable hydraulicBoundaryLocations, IEnumerable dikeProfiles) : base(xmlFilePath, importTarget) { if (hydraulicBoundaryLocations == null) { throw new ArgumentNullException(nameof(hydraulicBoundaryLocations)); } if (dikeProfiles == null) { throw new ArgumentNullException(nameof(dikeProfiles)); } availableHydraulicBoundaryLocations = hydraulicBoundaryLocations; availableDikeProfiles = dikeProfiles; } protected override GrassCoverErosionInwardsCalculationConfigurationReader CreateCalculationConfigurationReader(string xmlFilePath) { return new GrassCoverErosionInwardsCalculationConfigurationReader(xmlFilePath); } protected override ICalculation ParseReadCalculation(ReadGrassCoverErosionInwardsCalculation readCalculation) { var calculation = new GrassCoverErosionInwardsCalculation { Name = readCalculation.Name }; ReadDikeHeightCalculationType(readCalculation, calculation); if(!ReadCriticalWaveReduction(readCalculation, calculation)) { return null; } if (!ReadHydraulicBoundaryLocation(readCalculation, calculation)) { return null; } if (!ReadDikeProfile(readCalculation, calculation)) { return null; } if (!ReadOrientation(readCalculation, calculation)) { return null; } if (!ReadWaveReduction(readCalculation, calculation)) { return null; } if (!ReadDikeHeight(readCalculation, calculation)) { return null; } return calculation; } /// /// Reads the hydraulic boundary location. /// /// The calculation read from the imported file. /// The calculation to configure. /// false when the has a /// set which is not available in , true otherwise. private bool ReadHydraulicBoundaryLocation(ReadGrassCoverErosionInwardsCalculation readCalculation, GrassCoverErosionInwardsCalculation calculation) { if (readCalculation.HydraulicBoundaryLocation != null) { HydraulicBoundaryLocation location = availableHydraulicBoundaryLocations .FirstOrDefault(l => l.Name == readCalculation.HydraulicBoundaryLocation); if (location == null) { LogReadCalculationConversionError( string.Format( RingtoetsCommonIOResources.CalculationConfigurationImporter_ReadHydraulicBoundaryLocation_HydraulicBoundaryLocation_0_does_not_exist, readCalculation.HydraulicBoundaryLocation), calculation.Name); return false; } calculation.InputParameters.HydraulicBoundaryLocation = location; } return true; } /// /// Reads the foreshore profile. /// /// The calculation read from the imported file. /// The calculation to configure. /// false when the has a /// set which is not available in , true otherwise. private bool ReadDikeProfile(ReadGrassCoverErosionInwardsCalculation readCalculation, GrassCoverErosionInwardsCalculation calculation) { if (readCalculation.DikeProfile != null) { DikeProfile dikeProfile = availableDikeProfiles.FirstOrDefault(fp => fp.Name == readCalculation.DikeProfile); if (dikeProfile == null) { LogReadCalculationConversionError( string.Format( Resources.GrassCoverErosionInwardsCalculationConfigurationImporter_ReadDikeProfile_DikeProfile_0_does_not_exist, readCalculation.DikeProfile), calculation.Name); return false; } calculation.InputParameters.DikeProfile = dikeProfile; } return true; } /// /// Reads the orientation. /// /// The calculation read from the imported file. /// The calculation to configure. /// false when the orientation is invalid or when there is an orientation but /// no dike profile defined, true otherwise. private bool ReadOrientation(ReadGrassCoverErosionInwardsCalculation readCalculation, GrassCoverErosionInwardsCalculation calculation) { if (calculation.InputParameters.DikeProfile == null) { if (readCalculation.Orientation.HasValue) { LogReadCalculationConversionError( Resources.GrassCoverErosionInwardsCalculationConfigurationImporter_ValidateWaveReduction_No_DikeProfile_provided_for_Orientation, calculation.Name); return false; } } if (readCalculation.Orientation.HasValue) { double orientation = readCalculation.Orientation.Value; try { calculation.InputParameters.Orientation = (RoundedDouble) orientation; } catch (ArgumentOutOfRangeException e) { LogOutOfRangeException( string.Format(Resources.GrassCoverErosionInwardsCalculationConfigurationImporter_ReadOrientation_Orientation_0_invalid, orientation), calculation.Name, e); return false; } } return true; } /// /// Reads the wave reduction parameters. /// /// The calculation read from the imported file. /// The calculation to configure. /// false when there is an invalid wave reduction parameter defined, true otherwise. private bool ReadWaveReduction(ReadGrassCoverErosionInwardsCalculation readCalculation, GrassCoverErosionInwardsCalculation calculation) { if (!ValidateWaveReduction(readCalculation, calculation)) { return false; } if (readCalculation.UseForeshore.HasValue) { calculation.InputParameters.UseForeshore = readCalculation.UseForeshore.Value; } if (readCalculation.UseBreakWater.HasValue) { calculation.InputParameters.UseBreakWater = readCalculation.UseBreakWater.Value; } if (readCalculation.BreakWaterType.HasValue) { calculation.InputParameters.BreakWater.Type = (BreakWaterType) readCalculation.BreakWaterType.Value; } if (readCalculation.BreakWaterHeight.HasValue) { calculation.InputParameters.BreakWater.Height = (RoundedDouble) readCalculation.BreakWaterHeight; } return true; } /// /// Reads the dike height. /// /// The calculation read from the imported file. /// The calculation to configure. /// false when there is a dike height but no dike profile defined, true otherwise. private bool ReadDikeHeight(ReadGrassCoverErosionInwardsCalculation readCalculation, GrassCoverErosionInwardsCalculation calculation) { if (calculation.InputParameters.DikeProfile == null) { if (readCalculation.DikeHeight.HasValue) { LogReadCalculationConversionError( Resources.GrassCoverErosionInwardsCalculationConfigurationImporter_ValidateWaveReduction_No_DikeProfile_provided_for_DikeHeight, calculation.Name); return false; } } else if (readCalculation.DikeHeight.HasValue) { calculation.InputParameters.DikeHeight = (RoundedDouble) readCalculation.DikeHeight.Value; } return true; } /// /// Reads the dike height calculation type. /// /// The calculation read from the imported file. /// The calculation to configure. private void ReadDikeHeightCalculationType(ReadGrassCoverErosionInwardsCalculation readCalculation, GrassCoverErosionInwardsCalculation calculation) { if (readCalculation.DikeHeightCalculationType.HasValue) { calculation.InputParameters.DikeHeightCalculationType = (DikeHeightCalculationType) readCalculation.DikeHeightCalculationType.Value; } } /// /// Reads the critical wave reduction. /// /// The calculation read from the imported file. /// The calculation to configure. private bool ReadCriticalWaveReduction(ReadGrassCoverErosionInwardsCalculation readCalculation, GrassCoverErosionInwardsCalculation calculation) { return ReadCriticalFlowRateMean(readCalculation, calculation) && ReadCriticalFlowRateStandardDeviation(readCalculation, calculation); } private bool ReadCriticalFlowRateMean(ReadGrassCoverErosionInwardsCalculation readCalculation, GrassCoverErosionInwardsCalculation calculation) { if (!readCalculation.CriticalFlowRateMean.HasValue) { return true; } double criticalFlowRateMean = readCalculation.CriticalFlowRateMean.Value; try { calculation.InputParameters.CriticalFlowRate.Mean = (RoundedDouble)criticalFlowRateMean; } catch (ArgumentOutOfRangeException e) { string errorMessage = string.Format( Resources.GrassCoverErosionInwardsCalculationConfigurationImporter_ReadCriticalWaveReduction_ReadCriticalWaveReductionMean_0_invalid, criticalFlowRateMean); LogOutOfRangeException( errorMessage, calculation.Name, e); return false; } return true; } private bool ReadCriticalFlowRateStandardDeviation(ReadGrassCoverErosionInwardsCalculation readCalculation, GrassCoverErosionInwardsCalculation calculation) { if (!readCalculation.CriticalFlowRateStandardDeviation.HasValue) { return true; } double criticalFlowRateStandardDeviation = readCalculation.CriticalFlowRateStandardDeviation.Value; try { calculation.InputParameters.CriticalFlowRate.StandardDeviation = (RoundedDouble) criticalFlowRateStandardDeviation; } catch (ArgumentOutOfRangeException e) { string errorMessage = string.Format( Resources.GrassCoverErosionInwardsCalculationConfigurationImporter_ReadCriticalWaveReduction_ReadCriticalWaveReductionStandardDeviation_0_invalid, criticalFlowRateStandardDeviation); LogOutOfRangeException( errorMessage, calculation.Name, e); return false; } return true; } /// /// Validation to check if the defined wave reduction parameters are valid. /// /// The calculation read from the imported file. /// The calculation to configure. /// false when there is an invalid wave reduction parameter defined, true otherwise. private bool ValidateWaveReduction(ReadGrassCoverErosionInwardsCalculation readCalculation, GrassCoverErosionInwardsCalculation calculation) { if (calculation.InputParameters.DikeProfile == null) { if (readCalculation.UseBreakWater.HasValue || readCalculation.UseForeshore.HasValue || readCalculation.BreakWaterHeight != null || readCalculation.BreakWaterType != null) { LogReadCalculationConversionError( Resources.GrassCoverErosionInwardsCalculationConfigurationImporter_ValidateWaveReduction_No_DikeProfile_provided_for_BreakWater_parameters, calculation.Name); return false; } } else if (!calculation.InputParameters.ForeshoreGeometry.Any()) { if (readCalculation.UseForeshore.HasValue && readCalculation.UseForeshore.Value) { LogReadCalculationConversionError( string.Format( Resources.GrassCoverErosionInwardsCalculationConfigurationImporter_ValidateWaveReduction_DikeProfile_0_has_no_geometry_and_cannot_be_used, readCalculation.DikeProfile), calculation.Name); return false; } } return true; } } }