using System; using System.ComponentModel; using System.Xml.Serialization; using Deltares.Geometry; using Deltares.Geotechnics; using Deltares.Geotechnics.Mechanisms; using Deltares.Standard; using Deltares.Standard.Attributes; using Deltares.Standard.EventPublisher; using Deltares.Standard.Units; using Deltares.Standard.Validation; namespace Deltares.DeltaModel { public abstract class RevetmentSegment : GeometryObject, IComparable { protected SurfaceLineGeometryPoint firstPoint = new SurfaceLineGeometryPoint(Double.NaN, 0, Double.NaN) { SendEvents = true }; protected SurfaceLineGeometryPoint lastPoint = new SurfaceLineGeometryPoint(Double.NaN, 0, Double.NaN) { SendEvents = true }; private ISegmentDescription segmentDescription; /// /// Constructor. /// protected RevetmentSegment() { firstPoint.Next = lastPoint; lastPoint.Previous = firstPoint; } /// /// Constructor. /// /// The data to attach to the segment. protected RevetmentSegment(ISegmentDescription segmentDescription) { SegmentDescription = segmentDescription; } /// /// Gets the x coordinate of the start point. /// [Format("F2")] [Unit(UnitType.Length)] [PropertyOrder(1, 1)] [Category("Position")] [XmlIgnore] public double StartX { get { return firstPoint.X; } set { DataEventPublisher.BeforeChange(this, x => x.StartX); firstPoint.X = value; DataEventPublisher.AfterChange(this, x => x.StartX); } } /// /// Gets the x coordinate of the end point. /// [Format("F2")] [Unit(UnitType.Length)] [PropertyOrder(1, 3)] [Category("Position")] [XmlIgnore] public double EndX { get { return lastPoint.X; } set { DataEventPublisher.BeforeChange(this, x => x.EndX); lastPoint.X = value; DataEventPublisher.AfterChange(this, x => x.EndX); } } /// /// The data attached to the segment, e.g. roughness characteristics /// [Validate] [Browsable(false)] public virtual ISegmentDescription SegmentDescription { get { return segmentDescription; } set { this.SetAndNotify2(out segmentDescription, value, x => x.SegmentDescription); } } [XmlIgnore] [ReadOnly(false)] [PropertyOrder(1, 0)] [Mechanism(Mechanism.Overtopping, Mechanism.AsphaltRevetment)] public override string Name { get { return SegmentDescription != null ? SegmentDescription.Name : ""; } set { if (SegmentDescription != null) { DataEventPublisher.BeforeChange(this, x => x.Name); SegmentDescription.Name = value; DataEventPublisher.AfterChange(this, x => x.Name); } } } public bool HasPoint(GeometryPoint point) { return firstPoint == point || lastPoint == point; } /// /// Connect this segment's last point to the first point of the next . After connecting, /// changing the endpoint of this segment, will also change the firstpoint of the next . /// /// The segment to connect to. public void ConnectTo(RevetmentSegment nextSegment) { lastPoint = nextSegment.firstPoint; lastPoint.Previous = firstPoint; firstPoint.Next = lastPoint; } /// /// Disconnects the segment from the next . After disconnecting, the endpoints /// of the segments can be changed independently. /// /// The segment to disconnect from. public void DisconnectFrom(RevetmentSegment nextSegment) { if (IsConnectedTo(nextSegment)) { lastPoint = (SurfaceLineGeometryPoint) lastPoint.Clone(); lastPoint.Next = null; firstPoint.Next = lastPoint; nextSegment.firstPoint.Previous = null; } } /// /// Returns true if this segment is connected to the next . /// /// The segment which is possibly connected to. /// True if the segments are connected, false otherwise. public bool IsConnectedTo(RevetmentSegment nextSegment) { return lastPoint == nextSegment.firstPoint; } /// /// Returns the geometry bounds. /// public override GeometryBounds GetGeometryBounds() { if (!Double.IsNaN(StartX) && !Double.IsNaN(EndX)) { return firstPoint.GetGeometryBounds() + lastPoint.GetGeometryBounds(); } if (Double.IsNaN(StartX) && !Double.IsNaN(EndX)) { return lastPoint.GetGeometryBounds(); } if (Double.IsNaN(EndX) && !Double.IsNaN(StartX)) { return firstPoint.GetGeometryBounds(); } return null; } public override string ToString() { return Name ?? "UnknownSegment"; } public int CompareTo(RevetmentSegment other) { var compare = StartX.CompareTo(other.StartX); if (compare == 0) { compare = EndX.CompareTo(other.EndX); } return compare; } /// Used in serialization [Obsolete("Used only for serialization.", true)] protected SurfaceLineGeometryPoint FirstPoint { get { return firstPoint; } set { firstPoint = value; } } /// Used in serialization [Obsolete("Used only for serialization.", true)] protected SurfaceLineGeometryPoint LastPoint { get { return lastPoint; } set { lastPoint = value; } } } }