// Copyright (C) Stichting Deltares 2025. All rights reserved. // // This file is part of the application DAM - UI. // // DAM - UI 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.Drawing; using System.Globalization; using System.IO; using System.Threading; using Deltares.Dam.Data.DamEngineIo; using Deltares.Dam.Data.Importers; using Deltares.Geotechnics.Soils; using Deltares.Standard; using Deltares.Standard.IO; using Deltares.Standard.Language; using LumenWorks.Framework.IO.Csv; namespace Deltares.Dam.Data.CsvImporters; public class CsvImporterSoilsException : Exception { public CsvImporterSoilsException(string message) : base(message) {} } public class CsvImporterSoils { private int currentColIndex = -1; // Keep track of column for error message public CsvImporterSoils(string fileName) { ErrorMessages.Clear(); ThrowHelper.ThrowIfStringArgumentNullOrEmpty(fileName, StringResourceNames.CsvFileNotValid); ThrowHelper.ThrowIfFileNotExist(fileName, StringResourceNames.CsvFileNotFound); CultureInfo oldCultureInfo = Thread.CurrentThread.CurrentCulture; try { Thread.CurrentThread.CurrentCulture = CsvReaderUtilities.DetermineCultureForFile(fileName); using (var csv = new CsvReader(new StreamReader(fileName), true, ';')) { string[] headers = CsvImporterHelper.GetFieldHeaders(this, csv); if (headers.Length < 2) { string csvHeaderError = LocalizationManager.GetTranslatedText(GetType(), "csvHeaderError"); throw new CsvImporterSoilsException($"{fileName} : {csvHeaderError}"); } int colIndexSoilName = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.SoilNameColumnName); CheckColumn(colIndexSoilName, fileName, CsvColumnNames.SoilNameColumnName); int colIndexSoilColor = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.SoilColorColumnName); CheckColumn(colIndexSoilColor, fileName, CsvColumnNames.SoilColorColumnName); int colIndexSoilType = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.SoilTypeColumnName); CheckColumn(colIndexSoilType, fileName, CsvColumnNames.SoilTypeColumnName); int colIndexSaturatedUnitWeight = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.SaturatedUnitWeightColumnName); int colIndexUnsaturatedUnitWeight = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.UnsaturatedUnitWeightColumnName); int colIndexCohesion = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.CohesionColumnName); int colIndexFrictionAngle = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.FrictionAngleColumnName); int colIndexDiameterD70 = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.DiameterD70ColumnName); int colIndexPermeabilityX = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.PermeabilityXColumnName); int colIndexShearStrengthModel = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.ShearStrengthModelColumnName); int colIndexStrengthIncreaseExponent = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.StrengthIncreaseExponentColumnName); int colIndexRatioSuPc = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.RatioSuPcColumnName); int colIndexPop = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.PopColumnName); int colIndexSigmaTauCurveName = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.SigmaTauCurveNameColumnName); int colIndexSuTableName = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.SuTableNameColumnName); int colIndexTrafficLoadDegreeOfConsolidation = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.TrafficLoadDegreeOfConsolidationColumnName); while (csv.ReadNextRecord()) { var soil = new SoilRecord(); try { // Required columns currentColIndex = colIndexSoilName; soil.SoilName = csv[currentColIndex]; currentColIndex = colIndexSoilColor; soil.SoilColor = ColorTranslator.FromHtml(csv[currentColIndex]); currentColIndex = colIndexSoilType; soil.SoilType = ConversionHelper.ConvertToSoilType(csv[currentColIndex]); // Optional columns soil.SaturatedUnitWeight = FetchOptionalColumn(colIndexSaturatedUnitWeight, csv); soil.UnsaturatedUnitWeight = FetchOptionalColumn(colIndexUnsaturatedUnitWeight, csv); soil.Cohesion = FetchOptionalColumn(colIndexCohesion, csv); soil.FrictionAngle = FetchOptionalColumn(colIndexFrictionAngle, csv); soil.DiameterD70 = FetchOptionalColumn(colIndexDiameterD70, csv) * Physics.FactorMicroMeterToMeter; soil.PermeabilityX = FetchOptionalColumn(colIndexPermeabilityX, csv); if (colIndexShearStrengthModel > -1) { currentColIndex = colIndexShearStrengthModel; soil.ShearStrengthModel = ConversionHelper.ConvertToShearStrengthModel(csv[currentColIndex]); } soil.StrengthIncreaseExponent = FetchOptionalColumn(colIndexStrengthIncreaseExponent, csv); soil.RatioSuPc = FetchOptionalColumn(colIndexRatioSuPc, csv); if (colIndexSigmaTauCurveName > -1) { currentColIndex = colIndexSigmaTauCurveName; soil.SigmaTauCurveName = csv[currentColIndex]; } if (colIndexSuTableName > -1) { currentColIndex = colIndexSuTableName; soil.SuTableName = csv[currentColIndex]; } soil.Pop = FetchOptionalColumn(colIndexPop, csv); soil.TrafficLoadDegreeOfConsolidation = (int?) FetchOptionalColumn(colIndexTrafficLoadDegreeOfConsolidation, csv); ImportedItems.Add(soil); } catch (Exception e) { string csvSoilError = string.Format(LocalizationManager.GetTranslatedText(GetType(), "csvSoilError"), soil.SoilName, currentColIndex + 1); ErrorMessages.Add(csvSoilError + e.Message); } } } } finally { Thread.CurrentThread.CurrentCulture = oldCultureInfo; } } public List ImportedItems { get; } = new(); public List ErrorMessages { get; } = new(); private double? FetchOptionalColumn(int colIndex, CsvReader csv) { if (colIndex > -1) { currentColIndex = colIndex; return Convert.ToDouble(csv[colIndex]); } return null; } private void CheckColumn(int index, string fileName, string fieldName) { if (index < 0) { string csvHeaderFieldError = LocalizationManager.GetTranslatedText(GetType(), "csvHeaderFieldError"); throw new CsvImporterSoilsException($"{fileName} : {csvHeaderFieldError} {fieldName}"); } } public class SoilRecord { public string SoilName { get; set; } public Color SoilColor { get; set; } public SoilType SoilType { get; set; } public double? SaturatedUnitWeight { get; set; } public double? UnsaturatedUnitWeight { get; set; } public double? Cohesion { get; set; } public double? FrictionAngle { get; set; } public double? DiameterD70 { get; set; } public double? PermeabilityX { get; set; } public ShearStrengthModel ShearStrengthModel { get; set; } public string SigmaTauCurveName { get; set; } = ""; public string SuTableName { get; set; } = ""; public double? StrengthIncreaseExponent { get; set; } public double? RatioSuPc { get; set; } public double? Pop { get; set; } public int? TrafficLoadDegreeOfConsolidation { get; set; } } }