//-----------------------------------------------------------------------
//
// Copyright (c) 2009 Deltares. All rights reserved.
//
// R.C. blankenburgh
// remko.blankenburgh@deltares.nl
// 26-08-2009
// n.a.
//-----------------------------------------------------------------------
using Deltares.Geotechnics.Converter;
using Deltares.Geotechnics.Soils;
using Deltares.Geotechnics.SurfaceLines;
using Deltares.Geotechnics.Validation;
using Deltares.Standard.Attributes;
using Deltares.Standard.Data;
using Deltares.Standard.Language;
using Deltares.Standard.Logging;
namespace Deltares.Dam.Data
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Soilbase;
using Standard;
using Geotechnics;
using System.ComponentModel;
using System.Xml.Serialization;
using Standard.Extensions;
public class DikeException : Exception
{
public DikeException(string message)
: base(message)
{
}
}
public class DikeParameterNames
{
public const string MapForSoilGeometries2D = "MapForSoilGeometries2D";
}
[TrackChanges]
public class Dike: IVisibleEnabled, IDisposable
{
private string description = "";
public virtual string MapForSoilGeometries2D { get; set; }
private IList locations;
private IList pl1Lines;
private bool removeStiFiles;
private MStabShearStrength shearmodel;
private SoilList soilList;
private IList gauges = new List();
private IList gaugePLLines = new List();
private IList nonWaterRetainingObjects;
private IList soilProfiles;
private string soilDatabaseName = "";
private List databaseSoils = new List();
public Dike()
{
this.Name = "Dijkring";
this.MapForSoilGeometries2D = "";
this.locations = new List();
this.soilProfiles = new List();
this.surfaceLines = new DelegatedList { AddMethod = ConvertAddedOldSurfaceLineToNewFormat };
SurfaceLines2 = new List();
this.pl1Lines = new List();
this.soilList = new SoilList();
this.nonWaterRetainingObjects = new List();
removeStiFiles = true;
}
public bool IsRemoveStiFiles { get { return removeStiFiles; } set { removeStiFiles = value; } }
public MStabShearStrength ShearStrengthModel { get { return shearmodel; } set { shearmodel = value; } }
public virtual string Name { get; set; }
public virtual string SoilDatabaseName
{
get { return this.soilDatabaseName; }
set
{
this.soilDatabaseName = value;
UpdateLocationsDatabaseName();
}
}
///
/// Updates the locations for scenarios.
///
public void UpdateLocationsForScenarios()
{
foreach (Location location in this.Locations)
{
foreach (Scenario scenario in location.Scenarios)
{
scenario.Location = location;
}
}
}
///
/// Updates the name soil database for all locations.
///
public void UpdateLocationsDatabaseName()
{
foreach (Location location in this.Locations)
{
location.SoildatabaseName = this.SoilDatabaseName;
}
}
[XmlIgnore]
public SoilbaseDB SoilBaseDB { get; set; }
///
/// Gets the locations.
///
///
/// The locations.
///
public virtual IList Locations
{
get { return this.locations; }
private set { this.locations = value; }
}
///
/// Sorts the locations.
///
public void SortLocations()
{
this.locations = this.Locations.OrderBy(o => o.Name).ToList();
}
public IList SurfaceLines2 { get; set; }
public virtual IList PL1Lines
{
get { return this.pl1Lines; }
set { this.pl1Lines = value; }
}
public virtual IList SoilProfiles
{
get { return this.soilProfiles; }
set { this.soilProfiles = value; }
}
public virtual SoilList SoilList
{
get { return this.soilList; }
set { this.soilList = value; }
}
[Browsable(false)]
public virtual IList Gauges
{
get { return this.gauges; }
set { this.gauges = value; }
}
[Browsable(false)]
public virtual IList GaugePLLines
{
get { return this.gaugePLLines; }
set { this.gaugePLLines = value; }
}
public virtual IList NonWaterRetainingObjects
{
get { return this.nonWaterRetainingObjects; }
set { this.nonWaterRetainingObjects = value; }
}
public bool UsesGauges { get { return this.GaugePLLines != null && this.GaugePLLines.Count > 0 && this.Gauges != null; } }
public virtual List Scenarios
{
get
{
var scenarios = new List();
foreach (Location location in Locations)
{
scenarios.AddRange(location.Scenarios);
}
return scenarios;
}
}
public string Description
{
get { return description; }
set { description = value; }
}
public void Validate()
{
if (Locations == null || Locations.Count < 1)
{
throw new DikeException("The dike ring has no locations defined");
}
foreach (Location location in Locations)
{
if (location.LocalXZSurfaceLine2 != null)
{
var validator = new SurfaceLine2Validator();
var validationResults = validator.ValidateCharacteristicPointsAreOrdered(location.LocalXZSurfaceLine2)
.Concat(validator.ValidateGeometryPointsAreOrdered(location.LocalXZSurfaceLine2)).ToArray();
if (validationResults.Length > 0)
{
throw new SurfaceLineException(validationResults[0].Text);
}
}
}
}
public void CreateSoilBase()
{
if (this.SoilDatabaseName == null || !File.Exists(this.SoilDatabaseName))
{
throw new DikeException(String.Format("The soil database '{0}' cannot be found", this.SoilDatabaseName));
}
this.SoilBaseDB = SoilbaseDB.Create(this.SoilDatabaseName);
}
///
/// Read all the soils and their parameters from the database
///
public void FillDataBaseSoilListFromSoilBase()
{
using (var geoDatabase = new GeoDatabase(this.SoilDatabaseName))
{
geoDatabase.ReUseSoils = true;
var newSoilList = geoDatabase.ReadSoils(soilList.Soils);
databaseSoils = newSoilList.Soils;
}
}
///
/// Add 1D-soilprofiles from MGeobase database
///
public void AddSoilProfilesFromDB()
{
if (this.SoilDatabaseName == null || !File.Exists(this.SoilDatabaseName))
{
throw new DikeException(String.Format("The MGeobase database '{0}' cannot be found", this.SoilDatabaseName));
}
if (soilList.Soils.Count == 0)
{
FillDataBaseSoilListFromSoilBase();
soilList.Soils.AddRange(databaseSoils);
}
if (soilList.Soils.Count == 0)
{
throw new DikeException(String.Format("The MGeobase database '{0}' does not contain soils and can not be used.", this.SoilDatabaseName));
}
MGeobaseDB mgbDB = new MGeobaseDB(soilList);
IList addedSoilProfiles = mgbDB.AddSoilProfiles(this.SoilDatabaseName);
foreach (var addedSoilProfile in addedSoilProfiles)
{
soilProfiles.Add(addedSoilProfile);
}
}
///
/// Adapt data so it is consistent
///
public List MakeDataConsistent()
{
var errorSoils = TryToMakeSoilDataConsistent();
var logMessages = new List();
// Delete all locations without surfaceline
logMessages.AddRange(DeleteLocationsWithoutSurfaceLines());
// Delete all locations that have profiles (in their segment) which hold soils
// that are not in the soil database and so have no parameters.
logMessages.AddRange(DeleteLocationsWithProfilesWithUnknownSoils(errorSoils));
return logMessages;
}
///
/// Tries to make the soil data as read for 1D profiles consistent with the data in the soil database.
/// In the end we have a neat soil list with parameters for every soil as read from the database.
/// We might have a list with errors (soils that were not to be found in the database so soils for which
/// no parameters could be found).
///
///
private List TryToMakeSoilDataConsistent()
{
var errorSoils = new List();
// Fill the list of errorSoils with soils that are in the current soillist (as result of importing
// 1D profiles) but that are not found in the soil database because that are errors
foreach (var soil in soilList.Soils)
{
var fs = databaseSoils.Find(t => String.Equals(t.Name, soil.Name, StringComparison.CurrentCultureIgnoreCase));
if (fs == null)
{
errorSoils.Add(soil);
}
}
// Remove the error soils form the list
foreach (var errorSoil in errorSoils)
{
soilList.Soils.Remove(errorSoil);
}
// Get the parameters for every soil in the now proper soil list from the database. Add soils
// that are in the database but not yet in the soil list.
foreach (Soil soil in databaseSoils)
{
Soil existingSoil = this.soilList.GetSoilByName(soil.Name);
if (existingSoil == null)
{
this.soilList.Soils.Add(soil);
}
else
{
existingSoil.Assign(soil);
}
}
return errorSoils;
}
///
/// Removes all locations which have profiles that have invalid soils
///
private List DeleteLocationsWithProfilesWithUnknownSoils(List invalidSoils)
{
var logMessages = new List();
var invalidLocations = new List();
string soilProf;
string invSoil;
foreach (var location in locations)
{
bool isInValid;
string message = "";
if (location.Segment == null)
{
isInValid = true;
message = String.Format(LocalizationManager.GetTranslatedText(this.GetType(), "LocationWitNameHasNoSegment"), location.Name);
}
else
{
isInValid = DoesLocationHaveInvalidSoils(invalidSoils, location, out soilProf, out invSoil);
if (isInValid)
{
message = String.Format(LocalizationManager.GetTranslatedText(this.GetType(), "LocationHasProfileWithInvalidSoils"), location.Name, soilProf, invSoil);
}
}
if (isInValid)
{
invalidLocations.Add(location);
logMessages.Add(new LogMessage(LogMessageType.Warning, this, message));
}
}
foreach (var invalidLocation in invalidLocations)
{
locations.Remove(invalidLocation);
}
return logMessages;
}
///
/// Checks wether a location (or rather the soilprofiles in the segement of the location) contains invalid soils.
/// A soil is hereby considered invalid if it is not found in the database.
///
///
///
///
///
///
private bool DoesLocationHaveInvalidSoils(List invalidSoils, Location location, out string soilProf, out string invSoil)
{
soilProf = " ";
invSoil = " ";
foreach (var spp in location.Segment.SoilProfileProbabilities)
{
foreach (var invalidSoil in invalidSoils)
{
var fl = spp.SoilProfile.Layers.Find(l => String.Equals(l.Soil.Name, invalidSoil.Name, StringComparison.CurrentCultureIgnoreCase));
if (fl != null)
{
soilProf = spp.SoilProfile.Name;
invSoil = invalidSoil.Name;
return true;
}
}
}
return false;
}
///
/// Delete all locations without surfacelines
///
private List DeleteLocationsWithoutSurfaceLines()
{
var logMessages = new List();
//Add all locations with valid surfaceline
var newLocations = new List();
newLocations.AddRange(this.Locations.Where(loc => loc.SurfaceLine2 != null));
// Report which locations are not added because no valid surfaceline is found
var deletedLocations = new List();
deletedLocations.AddRange(this.Locations.Where(loc => loc.SurfaceLine2 == null));
foreach (var deletedLocation in deletedLocations)
{
var locationHasNoSurfaceLine = LocalizationManager.GetTranslatedText(this.GetType(), "LocationHasNoSurfaceLine");
logMessages.Add(new LogMessage(LogMessageType.Warning, this,
String.Format(locationHasNoSurfaceLine, deletedLocation.Name)));
}
this.Locations = newLocations;
return logMessages;
}
public override string ToString()
{
return this.Name;
}
public Dictionary GetParametersAsNameValuePairs()
{
var nameValuePairs = new Dictionary();
nameValuePairs.Add(DikeParameterNames.MapForSoilGeometries2D, MapForSoilGeometries2D);
return nameValuePairs;
}
public void SetParameterFromNameValuePair(string parameterName, string parameterValue)
{
if (parameterName.Equals(DikeParameterNames.MapForSoilGeometries2D))
this.MapForSoilGeometries2D = parameterValue;
}
public void UpdateLocation(Location location)
{
location.SoildatabaseName = this.SoilDatabaseName;
location.SoilList = this.SoilList;
location.MapForSoilGeometries2D = this.MapForSoilGeometries2D;
location.Gauges.Clear();
location.Gauges.AddRange(this.Gauges);
location.GaugePLLines.Clear();
location.GaugePLLines.AddRange(this.GaugePLLines);
}
public bool IsVisible(string property)
{
return true;
}
public bool IsEnabled(string property)
{
switch (property)
{
case "Name": return false;
case "SoilList": return false;
default: return true;
}
}
#region Backwards compatibility
private IList surfaceLines;
///
/// Gets or sets all surface lines instances associated with this dike.
///
/// Composite owner of all that are part of the
/// application that are associated with this dike.
[Obsolete("Do not use this member; Only exists for backwards compatibility.", true)]
public virtual IList SurfaceLines
{
get { return surfaceLines; }
set { surfaceLines = value; }
}
///
/// Performs backwards compatibility conversion from old-style surfaceline to new-style
/// surfaceline, and ensures that shared references are set correctly.
///
/// Persisted version of the old-style surfaceline.
private void ConvertAddedOldSurfaceLineToNewFormat(SurfaceLine argument)
{
var surfaceLine2 = new OldSurfaceLineToNewConverter().Convert(argument);
SurfaceLines2.Add(surfaceLine2);
foreach (var location in Locations)
{
location.SetNewSurfaceLineIfMatchesWithOldPersistedSurfaceLine(surfaceLine2);
}
// Remove old entry; it is no longer required.
surfaceLines.Remove(argument);
argument.Dispose();
}
#endregion
public void Dispose()
{
foreach (var location in Locations)
{
location.Dispose();
}
foreach (var surfaceLine2 in SurfaceLines2)
{
surfaceLine2.Dispose();
}
}
}
}