// Copyright (C) Stichting Deltares 2020. All rights reserved.
//
// This file is part of the Layer On Slope Tool.
//
// The Layer On Slope Tool is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero 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 System.Threading;
using Deltares.LayerOnSlopeTool.Data.CsvImporters;
using LumenWorks.Framework.IO.Csv;
namespace Deltares.LayerOnSlopeTool.Importer
{
///
/// Holds the importer for the locations from csv files
///
public class CsvImporterLocations
{
private readonly List locationRecords = new List();
private readonly List errorMessages = new List();
///
/// Record used for importing the items from the locations csv file.
///
public class LocationRecord
{
///
/// Gets or sets the location record identifier.
///
///
/// The location record identifier.
///
public int LocationRecordId { get; set; }
///
/// Gets or sets the location identifier.
///
///
/// The location identifier.
///
public string LocationId { get; set; }
///
/// Gets or sets the surface line identifier.
///
///
/// The surface line identifier.
///
public string SurfaceLineId { get; set; }
///
/// Gets or sets the x offset.
/// This is the offset needed to combine with the surface line correctly when both do not line up.
///
///
/// The x offset.
///
public double? XOffset { get; set; } // Only optional item
///
/// Gets or sets the dike embankment material. This is to be used as filling material for surface between the original 2D sti profile and the surface line.
///
///
/// The dike embankment material.
///
public string DikeEmbankmentMaterial { get; set; } // Now required, not optional
///
/// Gets or sets the name of the soil geometry.
///
///
/// The name of the soil geometry.
///
public string SoilGeometryName { get; set; } //NEW
///
/// Gets or sets the layer material.
///
///
/// The layer material.
///
public string LayerMaterial { get; set; } //NEW
///
/// Gets or sets the layer thickness.
///
///
/// The layer thickness.
///
public double LayerThickness { get; set; } //NEW
}
///
/// Initializes a new instance of the class, filling the records from the csv.
///
/// Name of the file.
///
/// De filenaam voor de locations csv is leeg.
/// or
/// or
///
public CsvImporterLocations(string fileName)
{
errorMessages.Clear();
if (fileName == "")
{
throw new ArgumentException("The file name for the Locations csv is empty.");
}
if (!File.Exists(fileName))
{
throw new ArgumentException(string.Format("The Locations csv file with name {0} could not be found.", fileName));
}
var oldcur = 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.Count() < 3)
{
var csvHeaderError = "The header of the csv file is wrong.";
throw new ArgumentException(string.Format("{0} : {1}", fileName, csvHeaderError));
}
int colIndexLocationId = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.LocationColumnName);
CheckColumn(colIndexLocationId, fileName, CsvColumnNames.LocationColumnName);
int colIndexSurfaceLineId = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.SurfaceLineColumnName);
CheckColumn(colIndexSurfaceLineId, fileName, CsvColumnNames.SurfaceLineColumnName);
int colIndexXOffset = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.XOffsetColumnName);
int colIndexDikeEmbankmentMaterial = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.DikeEmbankmentMaterialColumnName);
CheckColumn(colIndexDikeEmbankmentMaterial, fileName, CsvColumnNames.DikeEmbankmentMaterialColumnName);
int colSoilGeometryName = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.SoilGeometryNameColumnName);
CheckColumn(colSoilGeometryName, fileName, CsvColumnNames.SoilGeometryNameColumnName);
int colLayerMaterial = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.LayerMaterialColumnName);
CheckColumn(colLayerMaterial, fileName, CsvColumnNames.LayerMaterialColumnName);
int colLayerThickness = CsvReaderUtilities.GetHeaderIndexByString(headers, CsvColumnNames.LayerThicknessColumnName);
CheckColumn(colLayerThickness, fileName, CsvColumnNames.LayerThicknessColumnName);
var index = 1;
while (csv.ReadNextRecord())
{
var locationRecord = new LocationRecord();
var colIndex = -1; // Keep track of column for error message
try
{
locationRecord.LocationRecordId = index++;
/*
* Required columns
*/
locationRecord.LocationId = csv[colIndexLocationId];
locationRecord.SurfaceLineId = csv[colIndexSurfaceLineId];
locationRecord.DikeEmbankmentMaterial = csv[colIndexDikeEmbankmentMaterial];
locationRecord.SoilGeometryName = csv[colSoilGeometryName];
locationRecord.LayerMaterial = csv[colLayerMaterial];
locationRecord.LayerThickness = Convert.ToDouble(csv[colLayerThickness]);
/*
* Optional column
*/
if (colIndexXOffset > -1)
{
colIndex = colIndexXOffset;
locationRecord.XOffset = Convert.ToDouble(csv[colIndexXOffset]);
}
locationRecords.Add(locationRecord);
}
catch (Exception e)
{
var csvLocationError = String.Format("Next error occured whilst reading location {0} column {1} from csv: ",
locationRecord.LocationId, colIndex + 1);
errorMessages.Add(csvLocationError + e.Message);
}
}
}
}
finally
{
Thread.CurrentThread.CurrentCulture = oldcur;
}
}
///
/// Gets the imported items.
///
///
/// The imported items.
///
public List ImportedItems
{
get { return locationRecords; }
}
///
/// Gets the error messages.
///
///
/// The error messages.
///
public List ErrorMessages
{
get { return errorMessages; }
}
private void CheckColumn(int index, string fileName, string fieldName)
{
if (index < 0)
{
var csvHeaderFieldError = "The header misses the field: ";
throw new ArgumentException(string.Format("{0} : {1} {2} at index {3}.", fileName, csvHeaderFieldError, fieldName, index));
}
}
}
}