using System; using System.Collections.Generic; using System.ComponentModel; using System.Xml.Serialization; using Deltares.Geographic; using Deltares.Standard; using Deltares.Standard.Attributes; using Deltares.Standard.EventPublisher; using Deltares.Standard.Language; using Deltares.Standard.Reflection; using Deltares.Standard.Units; using Deltares.Standard.Validation; namespace Deltares.DeltaModel { /// /// Wind Hydraulic Boundary Object /// TODO: Comment /// public class WindHydraulicBoundary : IGeographicString { private const double deg2rad = Math.PI/180.0; private double angle; private BindPropertyInfo angleProperty = PropertyInfoSupport.GetPropertyInfo(typeof(WindHydraulicBoundary), "Angle"); private IGeographicPoint endPoint = null; private double fetchBottom = double.NaN; private double fetchLength = double.NaN; private List points = null; private IGeographicPoint startPoint = new GeographicPoint(0, 0); /// /// Initializes a new instance of the class. /// public WindHydraulicBoundary() { DataEventPublisher.OnAfterChange += DataEventPublisher_OnAfterChange; } /// /// Initializes a new instance of the class. /// /// The angle. public WindHydraulicBoundary(double angle) : this() { this.angle = angle; } /// /// Gets or sets the incoming angle of the wind. /// /// /// The angle. /// [Unit(UnitType.Angle)] [Minimum(0)] [Maximum(360)] [Format("F2")] [Label("WindDirection")] [Description("WindDirection")] [PropertyOrder(0, 0)] [ReadOnly(true)] public double Angle { get { return angle; } set { DataEventPublisher.BeforeChange(this, "Angle"); angle = value; UpdateEndPoint(); DataEventPublisher.AfterChange(this, "Angle"); } } /// /// Gets or sets the length of the fetch. /// /// /// The length of the fetch. /// [Unit(UnitType.Length)] [Minimum(0)] [Maximum(1.000e+06)] [Format("F2")] [Label("Length")] [Description("Length")] [PropertyOrder(1, 0)] [Clearable] public double FetchLength { get { return fetchLength; } set { DataEventPublisher.BeforeChange(this, "FetchLength"); if (value == 0.0) { fetchLength = double.NaN; fetchBottom = double.NaN; } else { fetchLength = value; } UpdateEndPoint(); DataEventPublisher.AfterChange(this, "FetchLength"); } } /// /// Gets or sets the fetch bottom. /// /// /// The fetch bottom. /// [Unit(UnitType.Depth)] [Minimum(-1.000e+06)] [Maximum(1.000e+06)] [Format("F2")] [Label("Bottom")] [Description("Bottom")] [PropertyOrder(1, 1)] [Clearable] public double FetchBottom { get { return fetchBottom; } set { DataEventPublisher.BeforeChange(this, "FetchBottom"); fetchBottom = value; DataEventPublisher.AfterChange(this, "FetchBottom"); } } /// /// Indicates the starting point of the wind arrow /// [Browsable(false)] [XmlIgnore] public IGeographicPoint StartPoint { get { return startPoint; } set { startPoint = value; UpdateEndPoint(); } } [Browsable(false)] [XmlIgnore] public IList Points { get { if (points == null) { endPoint = new GeographicPoint(StartPoint.X, StartPoint.Y); points = new List() { StartPoint, endPoint }; UpdateEndPoint(); } return points; } } public override string ToString() { return LocalizationManager.GetTranslatedText(GetType(), "Fetch at") + angleProperty.GetUserValue(this) + " " + angleProperty.GetUnitString(this); } private void UpdateEndPoint() { if (endPoint == null) { return; } if (double.IsNaN(FetchLength)) { endPoint.X = startPoint.X; endPoint.Y = startPoint.Y; } else { endPoint.X = startPoint.X + Math.Sin(Angle*deg2rad)*FetchLength; endPoint.Y = startPoint.Y + Math.Cos(Angle*deg2rad)*FetchLength; } } private void DataEventPublisher_OnAfterChange(object sender, PublishEventArgs e) { if (sender == StartPoint) { UpdateEndPoint(); DataEventPublisher.AfterChange(this); } } } }