using System; using System.Collections.Generic; using System.ComponentModel; using Deltares.Geographic; using Deltares.Geotechnics; using Deltares.Geotechnics.Mechanisms; using Deltares.Standard; using Deltares.Standard.Attributes; using Deltares.Standard.Data; using Deltares.Standard.EventPublisher; using Deltares.Standard.Units; using Deltares.Standard.Validation; namespace Deltares.DeltaModel { /// /// HydraulicBoundary /// TODO: Comment /// [Label("HydraulicBoundary")] public class HydraulicBoundary : IGeographicPoint, IVisibleEnabled, IName, IComparable, IComparable { private const double EPSILON = 0.001; private readonly DelegatedList windHydraulicBoundaries = new DelegatedList(); private int id; private string name = string.Empty; private Region region = new Region(); private double swellHeight; private double swellPeriod; private double waterLevelSetupHeight; private double x; private double y; /// /// Default constructor /// public HydraulicBoundary() { windHydraulicBoundaries.AddMethod = AddFetch; } /// /// Constructor with id /// /// Identification of the hydraulic boundary public HydraulicBoundary(int id) { this.id = id; } /// /// Identification of the hydraulic boundary as defined in the hydraulic databases /// [ReadOnly(true)] [Label("Id")] [PropertyOrder(0, 0)] public int Id { get { return id; } set { id = value; } } /// /// RegionId -> Hydraulic Boundary are grouped by region /// [Label("RegionId")] [ReadOnly(true)] [PropertyOrder(1)] [Group] public Region Region { get { return region; } set { region = value; } } /// /// Gets or sets the height of the WaterLevelSetup. /// /// /// The height. /// [Unit(UnitType.Length)] [Minimum(-1.000e+06)] [Maximum(1.000e+06)] [Format("F2")] [Label("Waterlevel setup height")] [Description("Waterlevel setup height")] [PropertyOrder(3)] [Browsable(false)] public double WaterLevelSetupHeight { get { return waterLevelSetupHeight; } set { DataEventPublisher.BeforeChange(this, "WaterLevelSetupHeight"); waterLevelSetupHeight = value; DataEventPublisher.AfterChange(this, "WaterLevelSetupHeight"); } } /// /// Gets or sets the period of the Swell. /// /// /// The period. /// [Unit(UnitType.Time)] [Format("F2")] [Label("Swell period")] [Description("Swell period")] [PropertyOrder(4, 0)] [ReadOnly(true)] [Browsable(false)] public double SwellPeriod { get { return swellPeriod; } set { DataEventPublisher.BeforeChange(this, "SwellPeriod"); swellPeriod = value; DataEventPublisher.AfterChange(this, "SwellPeriod"); } } /// /// Gets or sets the height of the Swell. /// /// /// The height. /// [Unit(UnitType.Length)] [Format("F2")] [Label("Swell height")] [Description("Swell height")] [PropertyOrder(4, 1)] [ReadOnly(true)] [Browsable(false)] public double SwellHeight { get { return swellHeight; } set { DataEventPublisher.BeforeChange(this, "SwellHeight"); swellHeight = value; DataEventPublisher.AfterChange(this, "SwellHeight"); } } /// /// List of hydraulic boundary data per wind direction /// [PropertyOrder(10, 0)] [Category("WindParameters")] [ReadOnly(true)] [Browsable(false)] [Mechanism(Mechanism.Overtopping, Mechanism.BlockRevetment, Mechanism.AsphaltRevetment)] public IList WindHydraulicBoundaries { get { if (!DataEventPublisher.IsDataEventPublishStopped && windHydraulicBoundaries.Count == 0) { GenerateWindDirections(); } return windHydraulicBoundaries; } } /// /// Gets or sets the X of a Fetch location. /// /// /// The X. /// [Label("X")] [Description("X")] [PropertyOrder(2, 0)] [Format("N2")] [ReadOnly(true)] [Unit(UnitType.Length)] public double X { get { return x; } set { if (Math.Abs(value - x) > EPSILON) { DataEventPublisher.BeforeChange(this, "X"); x = value; DataEventPublisher.AfterChange(this, "X"); } } } /// /// Gets or sets the X of a Fetch location. /// /// /// The X. /// [Label("Y")] [Description("Y")] [PropertyOrder(2, 1)] [Format("N2")] [ReadOnly(true)] [Unit(UnitType.Length)] public double Y { get { return y; } set { if (Math.Abs(value - y) > EPSILON) { DataEventPublisher.BeforeChange(this, "Y"); y = value; DataEventPublisher.AfterChange(this, "Y"); } } } /// /// Name /// [Label("Name")] [ReadOnly(true)] [PropertyOrder(0, 1)] [Data] public string Name { get { return name; } set { name = value; } } /// /// Generates wind fetch data based on the region wind directions /// public void GenerateWindDirections() { for (int i = 0; i < Region.WindDirections.Count; i++) { windHydraulicBoundaries.Add(new WindHydraulicBoundary(Region.WindDirections[i].Direction)); } } /// /// Gets the wind hydraulic boundary with a certain angle. /// /// The angle. /// wind hydraulic boundary public WindHydraulicBoundary GetWindHydraulicBoundary(double angle) { while (angle >= 360) { angle -= 360; } foreach (var windHydraulicBoundary in WindHydraulicBoundaries) { if (Math.Abs(windHydraulicBoundary.Angle - angle) < 0.01) { return windHydraulicBoundary; } } return null; } /// /// Gets the fetches count. /// /// the amount of fetches for the hydraulic boundary public int GetFetchesCount() { int count = 0; foreach (var windHydraulicBoundary in WindHydraulicBoundaries) { if (!double.IsNaN(windHydraulicBoundary.FetchLength)) { count++; } } return count; } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString() { if (string.IsNullOrEmpty(name) && Math.Abs(X - 0.0) < EPSILON && Math.Abs(Y - 0.0) < EPSILON) { return string.Empty; } return id + " (" + name + ")"; } public int CompareTo(object obj) { if (obj is HydraulicBoundary) { return CompareTo((HydraulicBoundary) obj); } else { return 0; } } public int CompareTo(HydraulicBoundary other) { return Id.CompareTo(other.Id); } public bool IsVisible(string property) { if (!MechanismSupport.IsMechanismVisible(typeof(DikeLocation), property)) { return false; } switch (property) { case "WindHydraulicBoundaries": return Region.NeedsFetches; case "WaterLevelSetupHeight": return false; case "SwellPeriod": return false; case "SwellHeight": return false; default: return true; } } public bool IsEnabled(string property) { return true; } private void AddFetch(WindHydraulicBoundary fetch) { fetch.StartPoint = this; } } }