// 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.IO; using System.Linq; using Deltares.Dam.Data; using Deltares.Geotechnics.SurfaceLines; using Deltares.Standard.Logging; using NUnit.Framework; namespace Deltares.Dam.Tests; [TestFixture] public class CsvImportDirectorTests { private string importFolder; /// /// Setup for whole testfixture /// [SetUp] public void FixtureSetup() { importFolder = Path.Combine(Directory.GetCurrentDirectory(), "TmpImportFiles"); Directory.CreateDirectory(importFolder); } [TearDown] public void FixtureTearDown() { if (Directory.Exists(importFolder)) { Directory.Delete(importFolder, true); } } /// /// Setup for single test /// [SetUp] public void Setup() { if (Directory.Exists(importFolder)) { Directory.Delete(importFolder, true); } Directory.CreateDirectory(importFolder); CreateCharacteristicPointsFile(); CreateLocationsFile(); CreateSegmentsFor1DProfilesFile(); CreateSurfaceLinesFiles(); CreateSoilProfilesFile(); CreateScenarios(); CreateSoilsFile(); } /// /// Test /// [Test] public void CvsImporter_ImportFromNonExistingDirectory_AddsMessageWithFatalErrorType() { ImportDirector.Construct("C:\\SomeNoneExistingDirectory", null); Assert.That(LogManager.Messages.Count, Is.EqualTo(1)); Assert.That(LogManager.Messages[0].MessageType, Is.EqualTo(LogMessageType.FatalError)); Assert.That(LogManager.Messages[0].Message, Is.EqualTo("The import folder C:\\SomeNoneExistingDirectory does not exist")); } /// /// Test /// [Test] public void CvsImporter_ImportWithIncompleteLocationTable_AddsMessageWithWarning() { File.Delete(importFolder + "\\locations.csv"); using (StreamWriter writer = File.CreateText(importFolder + "\\locations.csv")) { writer.WriteLine("location_id;surfaceline_id;segment_id;geo_x;geo_y;polderlevel;head_pl2;head_pl3;grass_quality;direction"); writer.WriteLine("LOC1;D1;ok;414.950;91.850;0.1;4.0;3.0;4.3;1.0"); } ImportDirector.Construct(importFolder, null); Assert.That(LogManager.Messages[0].MessageType, Is.EqualTo(LogMessageType.Warning)); } /// /// Test /// [Test] public void CanImportDikeWith2DSoilGeometries() { File.Delete(importFolder + "\\segments.csv"); File.Delete(importFolder + "\\soilprofiles.csv"); using (StreamWriter writer = File.CreateText(importFolder + "\\segments.csv")) { writer.WriteLine("segment_id;soilgeometry2D_name;probability;calculation_type"); writer.WriteLine("1;Geometrie 1;80;Stability"); writer.WriteLine("1;Geometrie 2;20;Stability"); writer.WriteLine("1;Geometrie 1 piping;100;Piping"); writer.WriteLine("2;Geometrie 2;100;Stability"); writer.WriteLine("2;Geometrie 1 piping;100;Piping"); } using (Dike dike = ImportDirector.Construct(importFolder, null)) { Assert.That(dike.Segments, Has.Count.EqualTo(2)); Assert.Multiple(() => { Assert.That(dike.Segments[0].SoilProfileProbabilities, Has.Count.EqualTo(3)); Assert.That(dike.Segments[1].SoilProfileProbabilities, Has.Count.EqualTo(2)); }); Assert.Multiple(() => { Assert.That(dike.Segments[0].SoilProfileProbabilities[0].SoilGeometry2DName, Is.EqualTo("Geometrie 1")); Assert.That(dike.Segments[0].SoilProfileProbabilities[0].Probability, Is.EqualTo(80)); Assert.That(dike.Segments[0].SoilProfileProbabilities[0].SegmentFailureMechanismType, Is.EqualTo(FailureMechanismSystemType.StabilityInside)); Assert.That(dike.Segments[0].SoilProfileProbabilities[1].SoilGeometry2DName, Is.EqualTo("Geometrie 2")); Assert.That(dike.Segments[0].SoilProfileProbabilities[1].Probability, Is.EqualTo(20)); Assert.That(dike.Segments[0].SoilProfileProbabilities[1].SegmentFailureMechanismType, Is.EqualTo(FailureMechanismSystemType.StabilityInside)); Assert.That(dike.Segments[0].SoilProfileProbabilities[2].SoilGeometry2DName, Is.EqualTo("Geometrie 1 piping")); Assert.That(dike.Segments[0].SoilProfileProbabilities[2].Probability, Is.EqualTo(100)); Assert.That(dike.Segments[0].SoilProfileProbabilities[2].SegmentFailureMechanismType, Is.EqualTo(FailureMechanismSystemType.Piping)); Assert.That(dike.Segments[1].SoilProfileProbabilities[0].SoilGeometry2DName, Is.EqualTo("Geometrie 2")); Assert.That(dike.Segments[1].SoilProfileProbabilities[0].Probability, Is.EqualTo(100)); Assert.That(dike.Segments[1].SoilProfileProbabilities[0].SegmentFailureMechanismType, Is.EqualTo(FailureMechanismSystemType.StabilityInside)); Assert.That(dike.Segments[1].SoilProfileProbabilities[1].SoilGeometry2DName, Is.EqualTo("Geometrie 1 piping")); Assert.That(dike.Segments[1].SoilProfileProbabilities[1].Probability, Is.EqualTo(100)); Assert.That(dike.Segments[1].SoilProfileProbabilities[1].SegmentFailureMechanismType, Is.EqualTo(FailureMechanismSystemType.Piping)); }); } } /// /// Test /// [Test] public void CanImportDikeWith1DSoilGeometries() { using (Dike dike = ImportDirector.Construct(importFolder, null)) { Assert.That(dike, Is.Not.Null); Assert.That(dike.SoilProfiles.Count, Is.EqualTo(2), "SoilProfiles.Count"); Assert.That(dike.Segments.Count, Is.EqualTo(2), "Segments.Count"); Assert.That(dike.SurfaceLines2.Count, Is.EqualTo(1), "SurfaceLines.Count"); Assert.That(dike.Locations.Count, Is.EqualTo(1)); Assert.That(dike.Locations[0].Name, Is.EqualTo("LOC1")); Assert.That(dike.Locations[0].SurfaceLine2.Name, Is.EqualTo("D1")); Assert.That(dike.Locations[0].Segment.Name, Is.EqualTo("1")); Assert.That(dike.Locations[0].XRd, Is.EqualTo(414.950)); Assert.That(dike.Locations[0].YRd, Is.EqualTo(91.850)); Assert.That(dike.Locations[0].XSoilGeometry2DOrigin, Is.EqualTo(14.0)); Assert.That(dike.Locations[0].DikeEmbankmentMaterial, Is.EqualTo("ophoogmateriaaldijk")); Assert.That(dike.Locations[0].ShoulderEmbankmentMaterial, Is.EqualTo("ophoogmateriaalberm")); Assert.That(dike.Locations[0].DampingFactorPL3, Is.EqualTo(0.31)); Assert.That(dike.Locations[0].DampingFactorPL4, Is.EqualTo(0.41)); Assert.That(dike.SurfaceLines2[0].CharacteristicPoints.Count(cp => cp.CharacteristicPointType != CharacteristicPointType.None), Is.EqualTo(13)); Assert.That(dike.SurfaceLines2[0].CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchPolderSide), Is.Not.Null); } } /// /// Test /// /// /// Test /// [Test] public void SoilProfilesOfImportedDikeHaveCorrectProbability() { Dike dike = ImportDirector.Construct(importFolder, null); Assert.That(dike.Segments[0].GetSoilProfileProbability(dike.SoilProfiles[0], FailureMechanismSystemType.StabilityInside), Is.EqualTo(80)); Assert.That(dike.Segments[0].GetSoilProfileProbability(dike.SoilProfiles[1], FailureMechanismSystemType.Piping), Is.EqualTo(100)); } /// /// Test /// [Test] public void SurfaceLinesOfImportedDikeHaveSameInstance() { Dike dike = ImportDirector.Construct(importFolder, null); Assert.That(dike.SurfaceLines2[0], Is.SameAs(dike.Locations[0].SurfaceLine2)); } /// /// Test /// [Test] public void CanImportDikeWithMinimalInput() { Dike dike = ImportDirector.Construct(importFolder, null); Assert.That(dike, Is.Not.Null); } /// /// Create csv file with 1D soilprofiles /// private void CreateSoilProfilesFile() { using StreamWriter writer = File.CreateText(importFolder + "\\soilprofiles.csv"); writer.WriteLine("soilprofile_id;top_level;soil_name;is_aquifer"); writer.WriteLine("1DP1;10;HW-OBO;FALSE;"); writer.WriteLine("1DP1;-0.6;HW-DUN;FALSE;"); writer.WriteLine("1DP1;-1.8;HW-DUOzand;FALSE;"); writer.WriteLine("1DP1;-2.8;HW-HVN;FALSE;"); writer.WriteLine("1DP1;-4;HW-HVN;FALSE;"); writer.WriteLine("1DP1;-5;Alg-zand (0-30);TRUE;"); writer.WriteLine("1DP2;10;HW-OBO;FALSE;"); writer.WriteLine("1DP2;-0.7;HW-DUN;FALSE;"); writer.WriteLine("1DP2;-1.5;HW-DUOzand;FALSE;"); writer.WriteLine("1DP2;-2.4;HW-HVN;FALSE;"); writer.WriteLine("1DP2;-4.3;HW-HVN;FALSE;"); writer.WriteLine("1DP2;-5.3;Alg-zand (0-30);TRUE;"); } /// /// Create csv file with scenarios /// private void CreateScenarios() { using StreamWriter writer = File.CreateText(importFolder + "\\scenarios.csv"); writer.WriteLine("location_id;location_scenario_id;water_height;dike_table_height;safety_factor_stability_inner_slope;safety_factor_piping;water_height_decimerings_hoogte;max_waterheight"); writer.WriteLine("LOC1;1;1.14;4.6;1.17;1.2;0.4;4"); } /// /// Create csv file with surface lines /// private void CreateSurfaceLinesFiles() { using StreamWriter writer = File.CreateText(importFolder + "\\surfacelines.csv"); writer.WriteLine( "Profielnaam;Geologischprofiel;X_GridPoint;Y_GridPoint;ScenarioClusterID;X1;Y1;Z1;.....;Xn;Yn;Zn;(Profiel)"); writer.WriteLine( "D1;;63,310;0,000;1;0,000;0,000;0,680;21,110;0,000;1,120;31,600;0,000;1,300;31,730;0,000;1,610;32,210;0,000;1,670;35,580;0,000;1,580;40,480;0,000;1,940;47,860;0,000;3,790;50,110;0,000;4,460;51,750;0,000;4,662;52,630;0,000;4,770;54,250;0,000;4,690;55,170;0,000;4,460;58,850;0,000;2,980;60,290;0,000;2,460;63,310;0,000;1,360;67,900;0,000;1,070;69,410;0,000;0,600;69,800;0,000;0,480;70,530;0,000;0,000;70,820;0,000;-0,190;71,550;0,000;-0,600;72,370;0,000;-1,060;72,380;0,000;-1,170;72,550;0,000;-1,460;73,860;0,000;-1,390;73,990;0,000;-1,0;74,570;0,000;-0,840;74,970;0,000;-0,600;76,170;0,000;0,110;86,660;0,000;0,270;103,280;0,000;0,220;117,940;0,000;0,120"); } /// /// Create csv file with segments containing 1d soilprofiles /// private void CreateSegmentsFor1DProfilesFile() { using StreamWriter writer = File.CreateText(importFolder + "\\segments.csv"); writer.WriteLine("segment_id;soilprofile_id;probability;calculation_type"); writer.WriteLine("1;1DP1;80;Stability"); writer.WriteLine("1;1DP2;20;Stability"); writer.WriteLine("1;1DP2;100;Piping"); writer.WriteLine("2;1DP2;100;Stability"); writer.WriteLine("2;1DP1;100;Piping"); } /// /// Create csv file with locations /// private void CreateLocationsFile() { using StreamWriter writer = File.CreateText(importFolder + "\\locations.csv"); writer.WriteLine("location_id;surfaceline_id;segment_id;geo_x;geo_y;x_soilgeometry2D_origin;Pl1_id;polderlevel;head_pl2;head_pl3;grass_quality;direction;ophoogmateriaaldijk;ophoogmateriaalberm;dempingsfactor_pl3;dempingsfactor_pl4;Sheetpile_x;Sheetpile_y;Sheetpile_z;Sheetpile_length;"); writer.WriteLine("LOC1;D1;1;414.950;91.850;14.0;PL1A;0.1;4.0;3.0;4.3;1.0;ophoogmateriaaldijk;ophoogmateriaalberm;0.31;0.41;432.1;0.0;654.3;22.0;"); } /// /// Create csv file with characteristic points /// private void CreateCharacteristicPointsFile() { using StreamWriter writer = File.CreateText(importFolder + "\\characteristicpoints.csv"); writer.WriteLine( "Profielnaam;X_Maaiveld binnenwaarts;Y_Maaiveld binnenwaarts;Z_Maaiveld binnenwaarts;X_Insteek sloot polderzijde;Y_Insteek sloot polderzijde;Z_Insteek sloot polderzijde;X_Slootbodem polderzijde;Y_Slootbodem polderzijde;Z_Slootbodem polderzijde;X_Slootbodem dijkzijde;Y_Slootbodem dijkzijde;Z_Slootbodem dijkzijde;X_Insteek sloot dijkzijde;Y_Insteek_sloot dijkzijde;Z_Insteek sloot dijkzijde;X_Teen dijk binnenwaarts;Y_Teen dijk binnenwaarts;Z_Teen dijk binnenwaarts;X_Kruin binnenberm;Y_Kruin binnenberm;Z_Kruin binnenberm;X_Insteek binnenberm;Y_Insteek binnenberm;Z_Insteek binnenberm;X_Kruin binnentalud;Y_Kruin binnentalud;Z_Kruin binnentalud;X_Verkeersbelasting kant binnenwaarts;Y_Verkeersbelasting kant binnenwaarts;Z_Verkeersbelasting kant binnenwaarts;X_Verkeersbelasting kant buitenwaarts;Y_Verkeersbelasting kant buitenwaarts;Z_Verkeersbelasting kant buitenwaarts;X_Kruin buitentalud;Y_Kruin buitentalud;Z_Kruin buitentalud;X_Insteek buitenberm;Y_Insteek buitenberm;Z_Insteek buitenberm;X_Kruin buitenberm;Y_Kruin buitenberm;Z_Kruin buitenberm;X_Teen dijk buitenwaarts;Y_Teen dijk buitenwaarts;Z_Teen dijk buitenwaarts;X_Maaiveld buitenwaarts;Y_Maaiveld buitenwaarts;Z_Maaiveld buitenwaarts;Volgnummer"); writer.WriteLine( "D1;117,94;0;0,12;-1;-1;-1;73,99;0;-1,0;72,55;0;-1,46;67,9;0;1,07;63,31;0;1,36;-1;-1;-1;-1;-1;-1;55,17;0;4,46;54,25;0;4,69;51,75;0;4,662;50,11;0;4,46;40,48;0;1,94;32,21;0;1,67;31,6;0;1,3;0;0;0,68;1"); } private void CreateSoilsFile() { using StreamWriter writer = File.CreateText(importFolder + "\\soils.csv"); writer.WriteLine("soil_name;soil_color;soil_type;saturated_unit_weight;unsaturated_unit_weight;cohesion;friction_angle;diameter_d70;permeability_x;shear_strength_model;use_pop;pop"); writer.WriteLine("Alg-zand (0-30);#FFFFFF;Sand;18.00;18.00;4.60;21.90;200.00;0.2;MohrCoulomb;True;10.00"); writer.WriteLine("HW-CAO;#FFFFFF;Clay;17.00;17.00;3.50;16.50;200.00;0.2;MohrCoulomb;True;10.00"); writer.WriteLine("HW-DUN;#FFFFFF;Clay;15.80;15.80;1.60;21.30;200.00;0.2;MohrCoulomb;True;10.00"); writer.WriteLine("HW-DUOklei;#FFFFFF;Clay;20.00;17.00;0.00;30.00;200.00;0.2;MohrCoulomb;True;10.00"); writer.WriteLine("HW-DUOzand;#FFFFFF;Sand;17.70;17.70;4.00;17.60;200.00;0.2;MohrCoulomb;True;10.00"); writer.WriteLine("HW-HVN;#FFFFFF;Peat;10.40;10.40;4.50;17.50;200.00;0.2;MohrCoulomb;True;10.00"); writer.WriteLine("HW-OBO;#FFFFFF;Clay;15.80;15.80;3.00;21.20;200.00;0.2;MohrCoulomb;True;10.00"); } }