using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Xml.Serialization;
using Deltares.Geographic;
using Deltares.Geotechnics;
using Deltares.Geotechnics.GeotechnicalGeometry;
using Deltares.Geotechnics.Mechanisms;
using Deltares.Geotechnics.Soils;
using Deltares.Geotechnics.SurfaceLines;
using Deltares.Standard;
using Deltares.Standard.Attributes;
using Deltares.Standard.EventPublisher;
using Deltares.Standard.Reflection;
using Deltares.Standard.Units;
using Deltares.Standard.Validation;
namespace Deltares.DeltaModel
{
///
/// DikeLocation as a section with begin and end
///
public class DikeSection : DikeLocation, IGeographicString
{
# region Field variables
private readonly List dikeCrossSections = new List();
///
/// Start of section
///
private DikeLinePoint beginPoint;
///
/// End of section
///
private DikeLinePoint endPoint;
///
/// Dike Cross Section which represents this Dike Section
///
private DikeCrossSection representativeDikeCrossSection;
# endregion
///
/// Initializes a new instance of the class.
///
public DikeSection()
{
DataEventPublisher.OnAfterChange += DataEventPublisher_OnAfterChange;
}
///
/// Start of section
///
///
/// The begin point.
///
[Label("")]
[Description("")]
[XmlIgnore]
public DikeLinePoint BeginPoint
{
get
{
return beginPoint;
}
set
{
DataEventPublisher.BeforeChange(this, ds => ds.BeginPoint);
beginPoint = value;
if (beginPoint != null)
{
beginPoint.DikeLine = DikeLine;
}
DataEventPublisher.AfterChange(this, ds => ds.BeginPoint);
}
}
///
/// End of section
///
///
/// The end point.
///
[Label("")]
[Description("")]
[XmlIgnore]
public DikeLinePoint EndPoint
{
get
{
return endPoint;
}
set
{
DataEventPublisher.BeforeChange(this,ds => ds.EndPoint);
endPoint = value;
if (endPoint != null)
{
endPoint.DikeLine = DikeLine;
}
DataEventPublisher.AfterChange(this, ds => ds.EndPoint);
}
}
///
/// Dike Cross Section which represents this Dike Section
///
[Domain]
[Category("Location")]
[XmlIgnore]
public DikeCrossSection RepresentativeDikeCrossSection
{
get
{
return representativeDikeCrossSection;
}
set
{
this.SetAndNotify2(out representativeDikeCrossSection, value, ds => ds.RepresentativeDikeCrossSection);
}
}
///
/// Gets or sets the offset end point.
///
///
/// The offset end point.
///
[Browsable(false)]
[PropertyOrder(1, 14)]
[Format("F2")]
[Unit(UnitType.Length)]
[Category("Location")]
[XmlIgnore]
public double OffsetEndPoint
{
get
{
return EndPoint.Offset;
}
set
{
DataEventPublisher.BeforeChange(this, ds => ds.OffsetEndPoint);
EndPoint.Offset = value;
DataEventPublisher.AfterChange(this, ds => ds.OffsetEndPoint);
}
}
///
/// Gets or sets the offset begin point.
///
///
/// The offset begin point.
///
[Browsable(false)]
[PropertyOrder(1, 13)]
[Format("F2")]
[Unit(UnitType.Length)]
[Category("Location")]
[XmlIgnore]
public double OffsetBeginPoint
{
get
{
return BeginPoint.Offset;
}
set
{
DataEventPublisher.BeforeChange(this,ds => ds.OffsetBeginPoint);
BeginPoint.Offset = value;
DataEventPublisher.AfterChange(this, ds => ds.OffsetBeginPoint);
}
}
///
/// Gets or sets the name.
///
///
/// The name.
///
[XmlIgnore]
public override string Name
{
get
{
if (string.IsNullOrWhiteSpace(base.Name))
{
return RepresentativeDikeCrossSection != null
? RepresentativeDikeCrossSection.Name
: base.Name;
}
return base.Name;
}
}
///
/// The dikeline to which this location belongs
///
// TODO can be replaced by the Point's implementation...
[XmlIgnore]
public override DikeLine DikeLine
{
get
{
return base.DikeLine;
}
set
{
base.DikeLine = value;
if (beginPoint != null)
{
beginPoint.DikeLine = value;
}
if (endPoint != null)
{
endPoint.DikeLine = value;
}
}
}
///
/// Gets the offset, which is the center point of the section, of the section along the dike line.
///
[XmlIgnore]
public override double Offset
{
get
{
if (EndPoint.Offset >= BeginPoint.Offset)
{
return (BeginPoint.Offset + EndPoint.Offset)/2;
}
else
{
// Cyclic
return (BeginPoint.Offset + Length/2)%DikeLine.Length;
}
}
}
///
/// Gets or sets the original dike location.
///
///
/// The original dike location.
///
[Browsable(false)]
[XmlIgnore]
public override DikeLocation OriginalDikeLocation
{
get
{
return RepresentativeDikeCrossSection != null ? RepresentativeDikeCrossSection.OriginalDikeLocation : null;
}
set
{
if (RepresentativeDikeCrossSection != null)
{
RepresentativeDikeCrossSection.OriginalDikeLocation = value;
}
}
}
[XmlIgnore]
public override BlockRevetmentCrossSection BlockRevetmentCrossSection
{
get
{
return RepresentativeDikeCrossSection != null
? RepresentativeDikeCrossSection.BlockRevetmentCrossSection
: null;
}
set
{
if (RepresentativeDikeCrossSection != null)
{
DataEventPublisher.BeforeChange(this, x => x.BlockRevetmentCrossSection);
RepresentativeDikeCrossSection.BlockRevetmentCrossSection = value;
DataEventPublisher.AfterChange(this, x => x.BlockRevetmentCrossSection);
}
}
}
[XmlIgnore]
public override BlockRevetmentRegion BlockRevetmentRegion
{
get
{
return RepresentativeDikeCrossSection != null
? RepresentativeDikeCrossSection.BlockRevetmentRegion
: null;
}
set
{
if (RepresentativeDikeCrossSection != null)
{
DataEventPublisher.BeforeChange(this, ds => ds.BlockRevetmentRegion);
RepresentativeDikeCrossSection.BlockRevetmentRegion = value;
DataEventPublisher.AfterChange(this, ds => ds.BlockRevetmentRegion);
}
}
}
[XmlIgnore]
public override RoughnessCrossSection RoughnessCrossSection
{
get
{
return RepresentativeDikeCrossSection != null
? RepresentativeDikeCrossSection.RoughnessCrossSection
: null;
}
set
{
if (RepresentativeDikeCrossSection != null)
{
DataEventPublisher.BeforeChange(this, ds => ds.RoughnessCrossSection);
RepresentativeDikeCrossSection.RoughnessCrossSection = value;
DataEventPublisher.AfterChange(this, ds => ds.RoughnessCrossSection);
}
}
}
[XmlIgnore]
public override AsphaltCrossSection AsphaltCrossSection
{
get
{
return RepresentativeDikeCrossSection != null
? RepresentativeDikeCrossSection.AsphaltCrossSection
: null;
}
set
{
if (RepresentativeDikeCrossSection != null)
{
DataEventPublisher.BeforeChange(this, ds => ds.AsphaltCrossSection);
RepresentativeDikeCrossSection.AsphaltCrossSection = value;
DataEventPublisher.AfterChange(this, ds => ds.AsphaltCrossSection);
}
}
}
[XmlIgnore]
public override AsphaltRegion AsphaltRegion
{
get
{
return RepresentativeDikeCrossSection != null
? RepresentativeDikeCrossSection.AsphaltRegion
: null;
}
set
{
if (RepresentativeDikeCrossSection != null)
{
DataEventPublisher.BeforeChange(this, ds => ds.AsphaltRegion);
RepresentativeDikeCrossSection.AsphaltRegion = value;
DataEventPublisher.AfterChange(this, ds => ds.AsphaltRegion);
}
}
}
///
/// Length of the dike location
///
[Label("Length")]
[Description("Length of the section")]
[Unit(UnitType.Length)]
[Format("F2")]
[ReadOnly(true)]
[XmlIgnore]
[PropertyOrder(1, 15)]
public override double Length
{
get
{
return EndPoint.Offset - BeginPoint.Offset;
}
set {}
}
///
/// Soil Segments (per failure mechanism) for the location
///
[XmlIgnore]
public override Dictionary SoilSegments
{
get
{
return RepresentativeDikeCrossSection != null ? RepresentativeDikeCrossSection.SoilSegments : base.SoilSegments;
}
}
///
/// Gets or sets the break water.
///
///
/// The break water.
///
[XmlIgnore]
public override BreakWater BreakWater
{
get
{
return RepresentativeDikeCrossSection != null ? RepresentativeDikeCrossSection.BreakWater : null;
}
set
{
DataEventPublisher.BeforeChange(this, ds => ds.BreakWater);
RepresentativeDikeCrossSection.BreakWater = value;
DataEventPublisher.AfterChange(this, ds => ds.BreakWater);
}
}
///
/// Gets or sets the auto setting for break water.
///
///
/// The break water.
///
[XmlIgnore]
public override bool IsAutoLinkedToBreakWater
{
get
{
return RepresentativeDikeCrossSection != null ? RepresentativeDikeCrossSection.IsAutoLinkedToBreakWater : base.IsAutoLinkedToBreakWater;
}
set
{
if (RepresentativeDikeCrossSection != null)
{
DataEventPublisher.BeforeChange(this, ds => ds.IsAutoLinkedToBreakWater);
RepresentativeDikeCrossSection.IsAutoLinkedToBreakWater = value;
DataEventPublisher.AfterChange(this, ds => ds.IsAutoLinkedToBreakWater);
}
}
}
///
/// Reference to the first station
/// Relative share of hydraulic boundary 1
///
[XmlIgnore]
public override HydraulicBoundary HydraulicBoundary1
{
get
{
return RepresentativeDikeCrossSection != null ? RepresentativeDikeCrossSection.HydraulicBoundary1 : null;
}
set
{
if (RepresentativeDikeCrossSection != null)
{
DataEventPublisher.BeforeChange(this, x => x.HydraulicBoundary1);
RepresentativeDikeCrossSection.HydraulicBoundary1 = value;
DataEventPublisher.AfterChange(this, x => x.HydraulicBoundary1);
}
}
}
///
/// Reference to the first station
/// Relative share of hydraulic boundary 2
///
[XmlIgnore]
public override HydraulicBoundary HydraulicBoundary2
{
get
{
return RepresentativeDikeCrossSection != null ? RepresentativeDikeCrossSection.HydraulicBoundary2 : null;
}
set
{
if (RepresentativeDikeCrossSection != null)
{
DataEventPublisher.BeforeChange(this, x => HydraulicBoundary2);
RepresentativeDikeCrossSection.HydraulicBoundary2 = value;
DataEventPublisher.AfterChange(this, x => HydraulicBoundary2);
}
}
}
///
/// Surfaceline that is schematized for a specific mechanism
///
///
/// The schematized surface line.
///
[XmlIgnore]
[Validate]
public override SurfaceLine2 SchematizedSurfaceLine
{
get
{
return RepresentativeDikeCrossSection != null ? RepresentativeDikeCrossSection.SchematizedSurfaceLine : null;
}
set
{
if (RepresentativeDikeCrossSection != null)
{
DataEventPublisher.BeforeChange(this, ds => ds.SchematizedSurfaceLine);
RepresentativeDikeCrossSection.SchematizedSurfaceLine = value;
DataEventPublisher.AfterChange(this, ds => ds.SchematizedSurfaceLine);
}
}
}
///
/// gets or sets Surfaceline
///
///
/// The surface line.
///
[XmlIgnore]
public override LocalizedGeometryPointString SurfaceLine
{
get
{
return RepresentativeDikeCrossSection != null ? RepresentativeDikeCrossSection.SurfaceLine : null;
}
set
{
if (RepresentativeDikeCrossSection != null)
{
DataEventPublisher.BeforeChange(this, ds => ds.SurfaceLine);
RepresentativeDikeCrossSection.SurfaceLine = value;
DataEventPublisher.AfterChange(this, ds => ds.SurfaceLine);
}
}
}
///
/// gets or sets piezometric heads
///
[XmlIgnore]
public override PiezometricHeads PiezometricHeads
{
get
{
return RepresentativeDikeCrossSection != null ? RepresentativeDikeCrossSection.PiezometricHeads : null;
}
set
{
if (RepresentativeDikeCrossSection != null)
{
DataEventPublisher.BeforeChange(this, x => x.PiezometricHeads);
RepresentativeDikeCrossSection.PiezometricHeads = value;
DataEventPublisher.AfterChange(this, x => x.PiezometricHeads);
}
}
}
///
/// Get or Set Assessment Level
///
public override double AssessmentLevel
{
get
{
if (RepresentativeDikeCrossSection != null)
{
return RepresentativeDikeCrossSection.AssessmentLevel;
}
return double.NaN;
}
}
///
/// Gets or sets the flow speed.
///
///
/// The flow speed.
///
[XmlIgnore]
public override double FlowSpeed
{
get
{
return RepresentativeDikeCrossSection != null ? RepresentativeDikeCrossSection.FlowSpeed : 1;
}
set
{
if (RepresentativeDikeCrossSection != null)
{
RepresentativeDikeCrossSection.FlowSpeed = value;
}
}
}
///
/// Gets the design values.
///
///
/// The design values.
///
[XmlIgnore]
public override List DesignValues
{
get
{
return RepresentativeDikeCrossSection != null ? RepresentativeDikeCrossSection.DesignValues : base.DesignValues;
}
}
///
/// Gets a representation of this dike section using . This representation starts with the
/// and ends with the and all the points on the which are between these two points.
///
/// Shallow copy of , points of and .
[XmlIgnore]
public IList Points
{
get
{
if (BeginPoint == null || DikeLine == null)
{
return null;
}
var points = new List
{
BeginPoint
};
points.AddRange(DikeLine.GetPointBetweenOffsets(BeginPoint.Offset, EndPoint.Offset));
points.Add(EndPoint);
return points;
}
}
///
/// Function to get the ten nearest BreakWaters
///
[XmlIgnore]
[Browsable(false)]
public static Func> GetCrossSections { get; set; }
///
/// Creates a dike section based on the dike line end begin point info.
///
/// The dike line.
/// The begin.
/// dike section
public static DikeSection Create(DikeLine dikeLine, DikeLinePoint begin)
{
var dikeSection = Create(dikeLine, begin, new DikeLinePoint(dikeLine.Length, dikeLine));
return dikeSection;
}
///
/// Creates a dike section based on the dike line, begin and end point info.
///
/// The dike line.
/// The begin.
/// The end.
/// dike section
public static DikeSection Create(DikeLine dikeLine, DikeLinePoint begin, DikeLinePoint end)
{
return new DikeSection
{
DikeLine = dikeLine,
BeginPoint = begin,
EndPoint = end
};
}
///
/// Gets the representive point.
///
///
/// representative point
///
public override IGeographicPoint GetRepresentivePoint()
{
return RepresentativeDikeCrossSection != null ? RepresentativeDikeCrossSection.GetRepresentivePoint() : BeginPoint;
}
///
/// Gets the distance to a given location along the same dike line
///
/// Location
/// Distance
public override double GetDistance(double x)
{
if (OffsetBeginPoint <= OffsetEndPoint)
{
if (OffsetBeginPoint <= x && OffsetEndPoint >= x)
{
return 0;
}
else if (x < OffsetBeginPoint)
{
return OffsetBeginPoint - x;
}
else
{
return x - OffsetEndPoint;
}
}
else
{
// Cyclic
if (x <= OffsetEndPoint || x >= OffsetBeginPoint)
{
return 0;
}
else if (x < OffsetBeginPoint)
{
return OffsetBeginPoint - x;
}
else
{
return x - OffsetEndPoint;
}
}
}
[Obsolete("Only used for serialization", true)]
private SerializedDikeSection State
{
get
{
return new SerializedDikeSection(this);
}
set
{
DikeLine = value.DikeLine;
BeginPoint = value.BeginPoint;
EndPoint = value.EndPoint;
RepresentativeDikeCrossSection = value.RepresentativeDikeCrossSection;
Name = value.Name;
}
}
private void DataEventPublisher_OnAfterChange(object sender, PublishEventArgs e)
{
var offsetChanged = e.Property == StaticReflection.GetMemberName(ds => ds.Offset);
if (ReferenceEquals(sender, BeginPoint) && offsetChanged)
{
RestrictBeginPointOffsets();
DataEventPublisher.AfterChange(this, ds => ds.BeginPoint);
}
if (ReferenceEquals(sender, EndPoint) && offsetChanged)
{
RestrictEndPointOffsets();
}
if (ReferenceEquals(sender, RepresentativeDikeCrossSection))
{
DataEventPublisher.AfterChange(this, e.Properties);
}
}
private void RestrictEndPointOffsets()
{
if (endPoint.Offset - beginPoint.Offset <= 0)
{
endPoint.Offset = beginPoint.Offset + 1;
}
}
private void RestrictBeginPointOffsets()
{
if (endPoint.Offset - beginPoint.Offset <= 0)
{
beginPoint.Offset = endPoint.Offset - 1;
}
}
# region Methods
///
/// Gets the dike cross sections.
///
///
/// The dike cross sections.
///
public List DikeCrossSections
{
get
{
return dikeCrossSections;
}
}
///
/// Gets the domain.
///
/// The property.
///
/// domain
///
public override ICollection GetDomain(string property)
{
if (property == StaticReflection.GetMemberName(ds => RepresentativeDikeCrossSection))
{
return GetCrossSectionsDomain();
}
return base.GetDomain(property);
}
///
/// Gets the cross sections domain.
///
/// Domain
private ICollection GetCrossSectionsDomain()
{
if (GetCrossSections == null)
{
return null;
}
return GetCrossSections(this).ToList();
}
#region IDisposable
public override void Dispose()
{
DataEventPublisher.OnAfterChange -= DataEventPublisher_OnAfterChange;
base.Dispose();
}
#endregion
#endregion
#region class SerializedDikeSection
private class SerializedDikeSection
{
public SerializedDikeSection(DikeSection point)
{
DikeLine = point.DikeLine;
BeginPoint = point.BeginPoint;
EndPoint = point.EndPoint;
RepresentativeDikeCrossSection = point.RepresentativeDikeCrossSection;
Name = point.Name;
}
private SerializedDikeSection() { }
public DikeLine DikeLine { get; private set; }
public DikeLinePoint BeginPoint { get; private set; }
public DikeLinePoint EndPoint { get; private set; }
public DikeCrossSection RepresentativeDikeCrossSection { get; private set; }
public String Name { get; private set; }
}
#endregion
}
}