Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/SurfaceLineAdapter.cs
===================================================================
diff -u -r4000 -r4052
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/SurfaceLineAdapter.cs (.../SurfaceLineAdapter.cs) (revision 4000)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/SurfaceLineAdapter.cs (.../SurfaceLineAdapter.cs) (revision 4052)
@@ -27,501 +27,500 @@
using Deltares.DamEngine.Data.Geometry;
using Deltares.DamEngine.Data.Geotechnics;
-namespace Deltares.DamEngine.Calculators.DikesDesign
+namespace Deltares.DamEngine.Calculators.DikesDesign;
+
+///
+/// Definition of a ditch
+///
+public struct DitchDefinition
{
+ public double OriginalX { get; set; }
+ public double DistanceFromToe { get; set; }
+ public double DistanceToBottomDikeSide { get; set; }
+ public double DistanceToBottomPolderSide { get; set; }
+ public double DistanceToEndDitch { get; set; }
+ public double DepthBottomDikeSide { get; set; }
+ public double DepthBottomPolderSide { get; set; }
+}
+
+///
+/// Base class for adapting the surfaceline
+///
+public abstract class SurfaceLineAdapter
+{
+ const double offset = 100.0;
+
+ protected readonly Location Location;
+ protected readonly SurfaceLine2 surfaceLine;
+ protected double trafficLoadOffsetXfromRiverside;
+ protected double trafficLoadOffsetXfromPolderside;
+ protected double trafficLoadWidth;
+ protected bool hasTrafficLoad;
+ protected bool isTrafficLoadOnCrest;
+ protected double polderLevel;
+
///
- /// Definition of a ditch
+ /// Constructor
///
- public struct DitchDefinition
+ ///
+ ///
+ ///
+ protected SurfaceLineAdapter(SurfaceLine2 surfaceLine, Location location, double scenarioPolderLevel)
{
- public double OriginalX { get; set; }
- public double DistanceFromToe { get; set; }
- public double DistanceToBottomDikeSide { get; set; }
- public double DistanceToBottomPolderSide { get; set; }
- public double DistanceToEndDitch { get; set; }
- public double DepthBottomDikeSide { get; set; }
- public double DepthBottomPolderSide { get; set; }
+ ThrowWhenSurfaceLineIsNull(surfaceLine);
+ ThrowWhenSurfaceLineDoesNotSatisfyToSpecification(surfaceLine);
+ this.surfaceLine = surfaceLine.FullDeepClone();
+ Location = location;
+ polderLevel = scenarioPolderLevel;
+ RetainTrafficLoad();
}
///
- /// Base class for adapting the surfaceline
+ /// Create traffic load based on the retained traffic load parameters
+ /// See documentation in Issue [MWDAM-548]
///
- public abstract class SurfaceLineAdapter
+ protected void RestoreTrafficLoad()
{
- const double offset = 100.0;
-
- protected readonly Location Location;
- protected readonly SurfaceLine2 surfaceLine;
- protected double trafficLoadOffsetXfromRiverside;
- protected double trafficLoadOffsetXfromPolderside;
- protected double trafficLoadWidth;
- protected bool hasTrafficLoad;
- protected bool isTrafficLoadOnCrest;
- protected double polderLevel;
-
- ///
- /// Constructor
- ///
- ///
- ///
- ///
- protected SurfaceLineAdapter(SurfaceLine2 surfaceLine, Location location, double scenarioPolderLevel)
+ if (hasTrafficLoad)
{
- ThrowWhenSurfaceLineIsNull(surfaceLine);
- ThrowWhenSurfaceLineDoesNotSatisfyToSpecification(surfaceLine);
- this.surfaceLine = surfaceLine.FullDeepClone();
- Location = location;
- polderLevel = scenarioPolderLevel;
- RetainTrafficLoad();
- }
-
- ///
- /// Create traffic load based on the retained traffic load parameters
- /// See documentation in Issue [MWDAM-548]
- ///
- protected void RestoreTrafficLoad()
- {
- if (hasTrafficLoad)
+ GeometryPoint pointDikeTopAtRiver = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver);
+ GeometryPoint pointDikeTopAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder);
+ if (isTrafficLoadOnCrest)
{
- GeometryPoint pointDikeTopAtRiver = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver);
- GeometryPoint pointDikeTopAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder);
- if (isTrafficLoadOnCrest)
+ // The traffic load will be restored relative to the binnenkruinlijn. If the leftside of the traffic load passes the buitenkruinlijn,
+ // the leftside of the traffic load will be placed on the buitenkruinlijn. It is possible that the rightside of the traffic load
+ // passes the buitenkruinlijn.
+ surfaceLine.SortPoints(); // line need to be sorted to use GetZAtX
+ double xCoordinate = pointDikeTopAtPolder.X - trafficLoadOffsetXfromPolderside - trafficLoadWidth;
+ if (xCoordinate < pointDikeTopAtRiver.X)
{
- // The traffic load will be restored relative to the binnenkruinlijn. If the leftside of the traffic load passes the buitenkruinlijn,
- // the leftside of the traffic load will be placed on the buitenkruinlijn. It is possible that the rightside of the traffic load
- // passes the buitenkruinlijn.
- surfaceLine.SortPoints(); // line need to be sorted to use GetZAtX
- double xCoordinate = pointDikeTopAtPolder.X - trafficLoadOffsetXfromPolderside - trafficLoadWidth;
- if (xCoordinate < pointDikeTopAtRiver.X)
- {
- xCoordinate = pointDikeTopAtRiver.X;
- }
+ xCoordinate = pointDikeTopAtRiver.X;
+ }
- double zCoordinate = surfaceLine.Geometry.GetZatX(xCoordinate);
- surfaceLine.EnsurePointOfType(xCoordinate, zCoordinate, CharacteristicPointType.TrafficLoadOutside);
+ double zCoordinate = surfaceLine.Geometry.GetZatX(xCoordinate);
+ surfaceLine.EnsurePointOfType(xCoordinate, zCoordinate, CharacteristicPointType.TrafficLoadOutside);
- surfaceLine.SortPoints(); // line need to be sorted to use GetZAtX
- xCoordinate += trafficLoadWidth;
- zCoordinate = surfaceLine.Geometry.GetZatX(xCoordinate);
- surfaceLine.EnsurePointOfType(xCoordinate, zCoordinate, CharacteristicPointType.TrafficLoadInside);
- }
- else
- {
- // The traffic load will be restore relative to the buitenkruinlijn.
- surfaceLine.SortPoints(); // line need to be sorted to use GetZAtX
- double xCoordinate = pointDikeTopAtRiver.X + trafficLoadOffsetXfromRiverside;
- double zCoordinate = surfaceLine.Geometry.GetZatX(xCoordinate);
- surfaceLine.EnsurePointOfType(xCoordinate, zCoordinate, CharacteristicPointType.TrafficLoadOutside);
+ surfaceLine.SortPoints(); // line need to be sorted to use GetZAtX
+ xCoordinate += trafficLoadWidth;
+ zCoordinate = surfaceLine.Geometry.GetZatX(xCoordinate);
+ surfaceLine.EnsurePointOfType(xCoordinate, zCoordinate, CharacteristicPointType.TrafficLoadInside);
+ }
+ else
+ {
+ // The traffic load will be restore relative to the buitenkruinlijn.
+ surfaceLine.SortPoints(); // line need to be sorted to use GetZAtX
+ double xCoordinate = pointDikeTopAtRiver.X + trafficLoadOffsetXfromRiverside;
+ double zCoordinate = surfaceLine.Geometry.GetZatX(xCoordinate);
+ surfaceLine.EnsurePointOfType(xCoordinate, zCoordinate, CharacteristicPointType.TrafficLoadOutside);
- surfaceLine.SortPoints(); // line need to be sorted to use GetZAtX
- xCoordinate = pointDikeTopAtRiver.X + trafficLoadOffsetXfromRiverside + trafficLoadWidth;
- zCoordinate = surfaceLine.Geometry.GetZatX(xCoordinate);
- surfaceLine.EnsurePointOfType(xCoordinate, zCoordinate, CharacteristicPointType.TrafficLoadInside);
- }
+ surfaceLine.SortPoints(); // line need to be sorted to use GetZAtX
+ xCoordinate = pointDikeTopAtRiver.X + trafficLoadOffsetXfromRiverside + trafficLoadWidth;
+ zCoordinate = surfaceLine.Geometry.GetZatX(xCoordinate);
+ surfaceLine.EnsurePointOfType(xCoordinate, zCoordinate, CharacteristicPointType.TrafficLoadInside);
}
}
+ }
- ///
- /// Replaces the inside slope by adding the new end point of the slope to the surfaceline.
- ///
- ///
- ///
- /// point equal to the ShoulderTopInside when the new slope ends on that point else null
- protected GeometryPoint ReplaceBaseInsideForNewSlope(GeometryPoint startPoint, double slopeTangent)
+ ///
+ /// Replaces the inside slope by adding the new end point of the slope to the surfaceline.
+ ///
+ ///
+ ///
+ /// point equal to the ShoulderTopInside when the new slope ends on that point else null
+ protected GeometryPoint ReplaceBaseInsideForNewSlope(GeometryPoint startPoint, double slopeTangent)
+ {
+ GeometryPoint result = null;
+ var line = new Line
{
- GeometryPoint result = null;
- var line = new Line
+ BeginPoint = new Point2D(startPoint.X, startPoint.Z),
+ EndPoint =
+ new Point2D(startPoint.X + offset,
+ startPoint.Z - offset * slopeTangent)
+ };
+ // Find the intersectionpoint(s) of the new slope with the surface line
+ IList intersectionpoints = surfaceLine.Geometry.IntersectionPointsXzWithLineXz(line);
+ Point2D newSlopeEndPoint = null;
+ if (intersectionpoints.Count > 0)
+ {
+ newSlopeEndPoint = intersectionpoints.First();
+ // One of the intersection points can be the dike top which should not be replaced
+ if (newSlopeEndPoint.X == surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X &&
+ newSlopeEndPoint.Z == surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z)
{
- BeginPoint = new Point2D(startPoint.X, startPoint.Z),
- EndPoint =
- new Point2D(startPoint.X + offset,
- startPoint.Z - offset * slopeTangent)
- };
- // Find the intersectionpoint(s) of the new slope with the surface line
- IList intersectionpoints = surfaceLine.Geometry.IntersectionPointsXzWithLineXz(line);
- Point2D newSlopeEndPoint = null;
- if (intersectionpoints.Count > 0)
- {
- newSlopeEndPoint = intersectionpoints.First();
- // One of the intersection points can be the dike top which should not be replaced
- if (newSlopeEndPoint.X == surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X &&
- newSlopeEndPoint.Z == surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z)
+ newSlopeEndPoint = null;
+ if (intersectionpoints.Count > 1)
{
- newSlopeEndPoint = null;
- if (intersectionpoints.Count > 1)
- {
- newSlopeEndPoint = intersectionpoints[1];
- }
+ newSlopeEndPoint = intersectionpoints[1];
}
}
+ }
- if (newSlopeEndPoint == null)
- {
- throw new SurfaceLineAdapterException(Resources.SlopeErrorNoIntersection);
- }
+ if (newSlopeEndPoint == null)
+ {
+ throw new SurfaceLineAdapterException(Resources.SlopeErrorNoIntersection);
+ }
- GeometryPoint dikeToeAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder);
- if (newSlopeEndPoint.X > dikeToeAtPolder.X)
+ GeometryPoint dikeToeAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder);
+ if (newSlopeEndPoint.X > dikeToeAtPolder.X)
+ {
+ // The new point is beyond the old dike toe so adapt that point.
+ surfaceLine.EnsurePointOfType(newSlopeEndPoint.X, newSlopeEndPoint.Z, CharacteristicPointType.DikeToeAtPolder);
+ // Remove all points between top and dike toe,
+ surfaceLine.RemoveSegmentBetween(
+ surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X,
+ newSlopeEndPoint.X);
+ }
+ else
+ {
+ GeometryPoint shoulderTopInside = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside);
+ GeometryPoint shoulderBaseInside = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside);
+ if (shoulderBaseInside != null && shoulderTopInside != null)
{
- // The new point is beyond the old dike toe so adapt that point.
- surfaceLine.EnsurePointOfType(newSlopeEndPoint.X, newSlopeEndPoint.Z, CharacteristicPointType.DikeToeAtPolder);
- // Remove all points between top and dike toe,
- surfaceLine.RemoveSegmentBetween(
- surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X,
- newSlopeEndPoint.X);
- }
- else
- {
- GeometryPoint shoulderTopInside = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside);
- GeometryPoint shoulderBaseInside = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside);
- if (shoulderBaseInside != null && shoulderTopInside != null)
+ if (newSlopeEndPoint.X > shoulderTopInside.X)
{
- if (newSlopeEndPoint.X > shoulderTopInside.X)
+ // The new point is in the slope part of the shoulder (between ShoulderTopInside and Dike toe). So add a normal point
+ // at the new location and remove all points between the top and the new point.
+ //surfaceLine.RemovePoint(CharacteristicPointType.);
+ surfaceLine.EnsurePoint(newSlopeEndPoint.X, newSlopeEndPoint.Z);
+ surfaceLine.RemoveSegmentBetween(
+ surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X,
+ newSlopeEndPoint.X);
+ }
+ else
+ {
+ if (newSlopeEndPoint.X < shoulderTopInside.X)
{
- // The new point is in the slope part of the shoulder (between ShoulderTopInside and Dike toe). So add a normal point
- // at the new location and remove all points between the top and the new point.
- //surfaceLine.RemovePoint(CharacteristicPointType.);
- surfaceLine.EnsurePoint(newSlopeEndPoint.X, newSlopeEndPoint.Z);
- surfaceLine.RemoveSegmentBetween(
- surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X,
- newSlopeEndPoint.X);
+ // The new point is in the horizontal part of the shoulder. Remove all points between the current
+ // shoulderbase inside and its new location, then move the base
+ surfaceLine.RemoveSegmentBetween(shoulderBaseInside.X, newSlopeEndPoint.X);
+ surfaceLine.EnsurePointOfType(newSlopeEndPoint.X, newSlopeEndPoint.Z,
+ CharacteristicPointType.ShoulderBaseInside);
}
else
{
- if (newSlopeEndPoint.X < shoulderTopInside.X)
+ // The new point is equal to ShoulderTopInside. So remove that, add a normal point at its location
+ // and remove all points between the top and the new point.
+ CharacteristicPoint toBeRemoved = surfaceLine.CharacteristicPoints.FirstOrDefault(
+ cp => cp.CharacteristicPointType == CharacteristicPointType.ShoulderTopInside);
+ if (toBeRemoved != null)
{
- // The new point is in the horizontal part of the shoulder. Remove all points between the current
- // shoulderbase inside and its new location, then move the base
- surfaceLine.RemoveSegmentBetween(shoulderBaseInside.X, newSlopeEndPoint.X);
- surfaceLine.EnsurePointOfType(newSlopeEndPoint.X, newSlopeEndPoint.Z,
- CharacteristicPointType.ShoulderBaseInside);
+ surfaceLine.CharacteristicPoints.Remove(toBeRemoved);
}
- else
- {
- // The new point is equal to ShoulderTopInside. So remove that, add a normal point at its location
- // and remove all points between the top and the new point.
- CharacteristicPoint toBeRemoved = surfaceLine.CharacteristicPoints.FirstOrDefault(
- cp => cp.CharacteristicPointType == CharacteristicPointType.ShoulderTopInside);
- if (toBeRemoved != null)
- {
- surfaceLine.CharacteristicPoints.Remove(toBeRemoved);
- }
- surfaceLine.EnsurePoint(newSlopeEndPoint.X, newSlopeEndPoint.Z);
- surfaceLine.RemoveSegmentBetween(
- surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X,
- newSlopeEndPoint.X);
- result = new GeometryPoint(newSlopeEndPoint.X, newSlopeEndPoint.Z);
- }
+ surfaceLine.EnsurePoint(newSlopeEndPoint.X, newSlopeEndPoint.Z);
+ surfaceLine.RemoveSegmentBetween(
+ surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X,
+ newSlopeEndPoint.X);
+ result = new GeometryPoint(newSlopeEndPoint.X, newSlopeEndPoint.Z);
}
}
- else
- {
- // if the newtoe equals the diketoe, then just skip, nothing has to be changed. Otherwise there is a mistake!
- if (!newSlopeEndPoint.LocationEquals(new Point2D(dikeToeAtPolder.X, dikeToeAtPolder.Z)))
- {
- // There is no shoulder so the slope must be too steep.
- throw new SurfaceLineAdapterException(Resources.SlopeErrorNoIntersection);
- }
- }
}
-
- surfaceLine.SortPoints();
- return result;
- }
-
- ///
- /// Gets the ditch definition.
- ///
- ///
- ///
- protected DitchDefinition? GetDitchDefinition()
- {
- var ditchDefinition = new DitchDefinition();
- if (surfaceLine.HasDitch() && surfaceLine.IsDitchCorrect())
- {
- GeometryPoint ditchDikeSide = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide);
- ditchDefinition.DistanceFromToe = ditchDikeSide.X -
- surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X;
- if (ditchDefinition.DistanceFromToe >= 0)
- {
- ditchDefinition.OriginalX = ditchDikeSide.X;
- ditchDefinition.DistanceToBottomDikeSide =
- surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchDikeSide).X -
- ditchDikeSide.X;
- ditchDefinition.DistanceToBottomPolderSide =
- surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchPolderSide).X -
- ditchDikeSide.X;
- ditchDefinition.DistanceToEndDitch =
- surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide).X -
- ditchDikeSide.X;
- ditchDefinition.DepthBottomDikeSide = ditchDikeSide.Z -
- surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchDikeSide).Z;
- ditchDefinition.DepthBottomPolderSide = ditchDikeSide.Z -
- surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchPolderSide).Z;
- return ditchDefinition;
- }
- }
else
{
- if (surfaceLine.HasDitch())
+ // if the newtoe equals the diketoe, then just skip, nothing has to be changed. Otherwise there is a mistake!
+ if (!newSlopeEndPoint.LocationEquals(new Point2D(dikeToeAtPolder.X, dikeToeAtPolder.Z)))
{
- // Incorrect ditch is an error here, this should have been checked already
- throw new SurfaceLineAdapterException(Resources.SurfaceLineAdapterDikeDitchError);
+ // There is no shoulder so the slope must be too steep.
+ throw new SurfaceLineAdapterException(Resources.SlopeErrorNoIntersection);
}
}
-
- return null;
}
- ///
- /// Removes the existing ditch.
- ///
- /// The ditch definition.
- protected void RemoveExistingDitch(DitchDefinition? ditchDefinition)
+ surfaceLine.SortPoints();
+ return result;
+ }
+
+ ///
+ /// Gets the ditch definition.
+ ///
+ ///
+ ///
+ protected DitchDefinition? GetDitchDefinition()
+ {
+ var ditchDefinition = new DitchDefinition();
+ if (surfaceLine.HasDitch() && surfaceLine.IsDitchCorrect())
{
- if (ditchDefinition != null)
+ GeometryPoint ditchDikeSide = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide);
+ ditchDefinition.DistanceFromToe = ditchDikeSide.X -
+ surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X;
+ if (ditchDefinition.DistanceFromToe >= 0)
{
- // It is possible that DikeToeAtPolder coinsides with DitchDikeSide or SurfaceLevelInside with DitchPolderSide
- // If that is the case, those characteristic points should be restored
- // So first save those characteristic points
- GeometryPoint dikeToeAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder);
- GeometryPoint surfaceLevelInside = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside);
- // The characteristic points DitchDikeSide and DitchPolderSide should be removed, but the points itself should be restored,
- // else the surfaceline will get a new form. So save those points
- GeometryPoint ditchDikeSide = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide);
- GeometryPoint ditchPolderSide = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide);
- surfaceLine.RemoveSegmentIncluding(
- surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide).X,
- surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide).X);
- // Now restore characteristic points DikeToeAtPolder and SurfaceLevelInside if necessary
- surfaceLine.EnsurePointOfType(dikeToeAtPolder.X, dikeToeAtPolder.Z, CharacteristicPointType.DikeToeAtPolder);
- surfaceLine.EnsurePointOfType(surfaceLevelInside.X, surfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside);
- // Now restore points ditchDikeSide and ditchPolderSide
- surfaceLine.EnsurePoint(ditchDikeSide.X, ditchDikeSide.Z);
- surfaceLine.EnsurePoint(ditchPolderSide.X, ditchPolderSide.Z);
- surfaceLine.SortPoints();
+ ditchDefinition.OriginalX = ditchDikeSide.X;
+ ditchDefinition.DistanceToBottomDikeSide =
+ surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchDikeSide).X -
+ ditchDikeSide.X;
+ ditchDefinition.DistanceToBottomPolderSide =
+ surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchPolderSide).X -
+ ditchDikeSide.X;
+ ditchDefinition.DistanceToEndDitch =
+ surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide).X -
+ ditchDikeSide.X;
+ ditchDefinition.DepthBottomDikeSide = ditchDikeSide.Z -
+ surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchDikeSide).Z;
+ ditchDefinition.DepthBottomPolderSide = ditchDikeSide.Z -
+ surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.BottomDitchPolderSide).Z;
+ return ditchDefinition;
}
}
-
- ///
- /// Restores the ditch.
- ///
- /// The ditch definition.
- ///
- protected void RestoreDitch(DitchDefinition? ditchDefinition)
+ else
{
- if (ditchDefinition == null)
+ if (surfaceLine.HasDitch())
{
- return;
+ // Incorrect ditch is an error here, this should have been checked already
+ throw new SurfaceLineAdapterException(Resources.SurfaceLineAdapterDikeDitchError);
}
+ }
+ return null;
+ }
+
+ ///
+ /// Removes the existing ditch.
+ ///
+ /// The ditch definition.
+ protected void RemoveExistingDitch(DitchDefinition? ditchDefinition)
+ {
+ if (ditchDefinition != null)
+ {
+ // It is possible that DikeToeAtPolder coinsides with DitchDikeSide or SurfaceLevelInside with DitchPolderSide
+ // If that is the case, those characteristic points should be restored
+ // So first save those characteristic points
GeometryPoint dikeToeAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder);
- double distanceToNewToe = ditchDefinition.Value.OriginalX - dikeToeAtPolder.X;
- double xDitchDikeSide;
- DitchCoordinates coors;
+ GeometryPoint surfaceLevelInside = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside);
+ // The characteristic points DitchDikeSide and DitchPolderSide should be removed, but the points itself should be restored,
+ // else the surfaceline will get a new form. So save those points
+ GeometryPoint ditchDikeSide = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide);
+ GeometryPoint ditchPolderSide = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide);
+ surfaceLine.RemoveSegmentIncluding(
+ surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchDikeSide).X,
+ surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide).X);
+ // Now restore characteristic points DikeToeAtPolder and SurfaceLevelInside if necessary
+ surfaceLine.EnsurePointOfType(dikeToeAtPolder.X, dikeToeAtPolder.Z, CharacteristicPointType.DikeToeAtPolder);
+ surfaceLine.EnsurePointOfType(surfaceLevelInside.X, surfaceLevelInside.Z, CharacteristicPointType.SurfaceLevelInside);
+ // Now restore points ditchDikeSide and ditchPolderSide
+ surfaceLine.EnsurePoint(ditchDikeSide.X, ditchDikeSide.Z);
+ surfaceLine.EnsurePoint(ditchPolderSide.X, ditchPolderSide.Z);
surfaceLine.SortPoints();
+ }
+ }
- // TODO: #the Following code is not correct; you should also look at the setting of Location.UseNewMinDistanceDikeToeStartDitch
- // First determine all coordinates
- if (distanceToNewToe < Location.NewMinDistanceDikeToeStartDitch && distanceToNewToe != ditchDefinition.Value.DistanceFromToe)
+ ///
+ /// Restores the ditch.
+ ///
+ /// The ditch definition.
+ ///
+ protected void RestoreDitch(DitchDefinition? ditchDefinition)
+ {
+ if (ditchDefinition == null)
+ {
+ return;
+ }
+
+ GeometryPoint dikeToeAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder);
+ double distanceToNewToe = ditchDefinition.Value.OriginalX - dikeToeAtPolder.X;
+ double xDitchDikeSide;
+ DitchCoordinates coors;
+ surfaceLine.SortPoints();
+
+ // TODO: #the Following code is not correct; you should also look at the setting of Location.UseNewMinDistanceDikeToeStartDitch
+ // First determine all coordinates
+ if (distanceToNewToe < Location.NewMinDistanceDikeToeStartDitch && distanceToNewToe != ditchDefinition.Value.DistanceFromToe)
+ {
+ // Ditch needs to be moved as it is less then the minimum required distance from the new toe
+ xDitchDikeSide = dikeToeAtPolder.X +
+ Location.NewMinDistanceDikeToeStartDitch;
+ if (Location.UseNewDitchDefinition)
{
- // Ditch needs to be moved as it is less then the minimum required distance from the new toe
- xDitchDikeSide = dikeToeAtPolder.X +
- Location.NewMinDistanceDikeToeStartDitch;
- if (Location.UseNewDitchDefinition)
- {
- // Use the new definition instead of the old shape
- coors = GetCoordinatesForNewShape(xDitchDikeSide);
- }
- else
- {
- // replace the ditch with the same shape.
- coors = GetCoordinatesForOldShape(xDitchDikeSide, ditchDefinition.Value);
- }
+ // Use the new definition instead of the old shape
+ coors = GetCoordinatesForNewShape(xDitchDikeSide);
}
else
{
- // replace the ditch with the same shape and same location.
- xDitchDikeSide = dikeToeAtPolder.X +
- distanceToNewToe;
+ // replace the ditch with the same shape.
coors = GetCoordinatesForOldShape(xDitchDikeSide, ditchDefinition.Value);
}
-
- // check if the new bottom is beneath the surface line. If not, the ditch must not be replaced at all
- if (coors.ZBottom >= surfaceLine.Geometry.GetZatX(coors.XBottomAtDike) ||
- coors.ZBottom >= surfaceLine.Geometry.GetZatX(coors.XBottomAtPolder))
- {
- return;
- }
-
- double surfaceLevelInsideX = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside).X;
- if (coors.XAtPolder > surfaceLevelInsideX)
- {
- throw new SurfaceLineAdapterException(Resources.SurfaceLineHeightAdapterDitchOutsideSurfaceLine);
- }
-
- // Add the outside points of the new ditch
- surfaceLine.EnsurePointOfType(coors.XAtDike, coors.ZAtDike, CharacteristicPointType.DitchDikeSide);
- surfaceLine.EnsurePointOfType(coors.XAtPolder, coors.ZAtPolder, CharacteristicPointType.DitchPolderSide);
- // Delete all existing points in the new ditch
- surfaceLine.RemoveSegmentBetween(coors.XAtDike, coors.XAtPolder);
- // Add the bottom of the ditch
- surfaceLine.EnsurePointOfType(coors.XBottomAtDike, coors.ZBottom, CharacteristicPointType.BottomDitchDikeSide);
- surfaceLine.EnsurePointOfType(coors.XBottomAtPolder, coors.ZBottom, CharacteristicPointType.BottomDitchPolderSide);
- surfaceLine.SortPoints();
}
+ else
+ {
+ // replace the ditch with the same shape and same location.
+ xDitchDikeSide = dikeToeAtPolder.X +
+ distanceToNewToe;
+ coors = GetCoordinatesForOldShape(xDitchDikeSide, ditchDefinition.Value);
+ }
- ///
- /// Store the parameters with which the traffic load can be restored.
- /// The traffic load will be retained relative to the buitenkruinlijn.
- /// If the traffic load is completly inside area between buitenkruinlijn and binnenkruinlijn the following will be done:
- /// - The traffic load will be retained relative to the binnenkruinlijn. If the leftside of the traffic load passes the buitenkruinlijn,
- /// the leftside of the traffic load will be placed on the buitenkruinlijn. It is possible that the rightside of the traffic load
- /// passes the buitenkruinlijn.
- /// See documentation in Issue [MWDAM-548]
- ///
- private void RetainTrafficLoad()
+ // check if the new bottom is beneath the surface line. If not, the ditch must not be replaced at all
+ if (coors.ZBottom >= surfaceLine.Geometry.GetZatX(coors.XBottomAtDike) ||
+ coors.ZBottom >= surfaceLine.Geometry.GetZatX(coors.XBottomAtPolder))
{
- GeometryPoint pointTrafficLoadInside = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.TrafficLoadInside);
- GeometryPoint pointTrafficLoadOutside = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.TrafficLoadOutside);
- GeometryPoint pointDikeTopAtRiver = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver);
- GeometryPoint pointDikeTopAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder);
+ return;
+ }
- hasTrafficLoad = ((pointTrafficLoadInside != null) && (pointTrafficLoadOutside != null));
- if (hasTrafficLoad)
- {
- trafficLoadOffsetXfromRiverside = pointTrafficLoadOutside.X - pointDikeTopAtRiver.X;
- trafficLoadOffsetXfromPolderside = pointDikeTopAtPolder.X - pointTrafficLoadInside.X;
- trafficLoadWidth = pointTrafficLoadInside.X - pointTrafficLoadOutside.X;
- isTrafficLoadOnCrest = (pointTrafficLoadOutside.X >= pointDikeTopAtRiver.X) && (pointTrafficLoadInside.X <= pointDikeTopAtPolder.X);
- }
+ double surfaceLevelInsideX = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside).X;
+ if (coors.XAtPolder > surfaceLevelInsideX)
+ {
+ throw new SurfaceLineAdapterException(Resources.SurfaceLineHeightAdapterDitchOutsideSurfaceLine);
}
- ///
- /// Throws an exception when the surface line does not comply to the specification
- ///
- ///
- /// The specification is that there:
- /// - There are should be at least 4 points in the surface line
- /// - must be a dike
- /// - that the point coords are non zero
- /// - There is a surface line when a shoulder exists
- ///
- /// The candidate to test
- private static void ThrowWhenSurfaceLineDoesNotSatisfyToSpecification(SurfaceLine2 surfaceLine)
+ // Add the outside points of the new ditch
+ surfaceLine.EnsurePointOfType(coors.XAtDike, coors.ZAtDike, CharacteristicPointType.DitchDikeSide);
+ surfaceLine.EnsurePointOfType(coors.XAtPolder, coors.ZAtPolder, CharacteristicPointType.DitchPolderSide);
+ // Delete all existing points in the new ditch
+ surfaceLine.RemoveSegmentBetween(coors.XAtDike, coors.XAtPolder);
+ // Add the bottom of the ditch
+ surfaceLine.EnsurePointOfType(coors.XBottomAtDike, coors.ZBottom, CharacteristicPointType.BottomDitchDikeSide);
+ surfaceLine.EnsurePointOfType(coors.XBottomAtPolder, coors.ZBottom, CharacteristicPointType.BottomDitchPolderSide);
+ surfaceLine.SortPoints();
+ }
+
+ ///
+ /// Store the parameters with which the traffic load can be restored.
+ /// The traffic load will be retained relative to the buitenkruinlijn.
+ /// If the traffic load is completly inside area between buitenkruinlijn and binnenkruinlijn the following will be done:
+ /// - The traffic load will be retained relative to the binnenkruinlijn. If the leftside of the traffic load passes the buitenkruinlijn,
+ /// the leftside of the traffic load will be placed on the buitenkruinlijn. It is possible that the rightside of the traffic load
+ /// passes the buitenkruinlijn.
+ /// See documentation in Issue [MWDAM-548]
+ ///
+ private void RetainTrafficLoad()
+ {
+ GeometryPoint pointTrafficLoadInside = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.TrafficLoadInside);
+ GeometryPoint pointTrafficLoadOutside = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.TrafficLoadOutside);
+ GeometryPoint pointDikeTopAtRiver = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver);
+ GeometryPoint pointDikeTopAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder);
+
+ hasTrafficLoad = ((pointTrafficLoadInside != null) && (pointTrafficLoadOutside != null));
+ if (hasTrafficLoad)
{
- ThrowWhenSurfaceLineHasNoOrLessThenFourPoints(surfaceLine.Geometry.Points);
- ThrowWhenSurfaceHasNoDike(surfaceLine);
- ThrowWhenSurfaceLineHasAShoulderInsideAndNoSurfaceLevel(surfaceLine,
- surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside));
+ trafficLoadOffsetXfromRiverside = pointTrafficLoadOutside.X - pointDikeTopAtRiver.X;
+ trafficLoadOffsetXfromPolderside = pointDikeTopAtPolder.X - pointTrafficLoadInside.X;
+ trafficLoadWidth = pointTrafficLoadInside.X - pointTrafficLoadOutside.X;
+ isTrafficLoadOnCrest = (pointTrafficLoadOutside.X >= pointDikeTopAtRiver.X) && (pointTrafficLoadInside.X <= pointDikeTopAtPolder.X);
+ }
+ }
- GeometryPoint p1 = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver);
- GeometryPoint p2 = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder);
+ ///
+ /// Throws an exception when the surface line does not comply to the specification
+ ///
+ ///
+ /// The specification is that there:
+ /// - There are should be at least 4 points in the surface line
+ /// - must be a dike
+ /// - that the point coords are non zero
+ /// - There is a surface line when a shoulder exists
+ ///
+ /// The candidate to test
+ private static void ThrowWhenSurfaceLineDoesNotSatisfyToSpecification(SurfaceLine2 surfaceLine)
+ {
+ ThrowWhenSurfaceLineHasNoOrLessThenFourPoints(surfaceLine.Geometry.Points);
+ ThrowWhenSurfaceHasNoDike(surfaceLine);
+ ThrowWhenSurfaceLineHasAShoulderInsideAndNoSurfaceLevel(surfaceLine,
+ surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside));
- var zeroPoint = new GeometryPoint();
+ GeometryPoint p1 = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver);
+ GeometryPoint p2 = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder);
- if (zeroPoint.LocationEquals(p1) || zeroPoint.LocationEquals(p2))
- {
- throw new SurfaceLineAdapterException(Resources.SurfaceLineAdapterDikeHeightError);
- }
+ var zeroPoint = new GeometryPoint();
- if (surfaceLine.HasShoulderInside())
- {
- p1 = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside);
- p2 = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside);
- if (zeroPoint.LocationEquals(p1) || zeroPoint.LocationEquals(p2))
- {
- throw new SurfaceLineAdapterException(Resources.SurfaceLineAdapterShoulderHeightError);
- }
- }
+ if (zeroPoint.LocationEquals(p1) || zeroPoint.LocationEquals(p2))
+ {
+ throw new SurfaceLineAdapterException(Resources.SurfaceLineAdapterDikeHeightError);
}
- private static void ThrowWhenSurfaceLineHasAShoulderInsideAndNoSurfaceLevel(SurfaceLine2 surfaceLine, GeometryPoint surfaceLevelPoint)
+ if (surfaceLine.HasShoulderInside())
{
- if (surfaceLine.HasShoulderInside() && surfaceLevelPoint == null)
+ p1 = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderTopInside);
+ p2 = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.ShoulderBaseInside);
+ if (zeroPoint.LocationEquals(p1) || zeroPoint.LocationEquals(p2))
{
- throw new SurfaceLineAdapterException(Resources.SurfaceLineAdapterSurfaceLevelError);
+ throw new SurfaceLineAdapterException(Resources.SurfaceLineAdapterShoulderHeightError);
}
}
+ }
- private static void ThrowWhenSurfaceHasNoDike(SurfaceLine2 surfaceLine)
+ private static void ThrowWhenSurfaceLineHasAShoulderInsideAndNoSurfaceLevel(SurfaceLine2 surfaceLine, GeometryPoint surfaceLevelPoint)
+ {
+ if (surfaceLine.HasShoulderInside() && surfaceLevelPoint == null)
{
- if (!surfaceLine.HasDike())
- {
- throw new SurfaceLineAdapterException(Resources.SurfaceLineAdapterInvalidDikeError);
- }
+ throw new SurfaceLineAdapterException(Resources.SurfaceLineAdapterSurfaceLevelError);
}
+ }
- private static void ThrowWhenSurfaceLineIsNull(SurfaceLine2 surfaceLine)
+ private static void ThrowWhenSurfaceHasNoDike(SurfaceLine2 surfaceLine)
+ {
+ if (!surfaceLine.HasDike())
{
- if (surfaceLine == null)
- {
- throw new ArgumentNullException(Resources.SurfaceLineAdapterNoDikeError);
- }
+ throw new SurfaceLineAdapterException(Resources.SurfaceLineAdapterInvalidDikeError);
}
+ }
- private static void ThrowWhenSurfaceLineHasNoOrLessThenFourPoints(ICollection points)
+ private static void ThrowWhenSurfaceLineIsNull(SurfaceLine2 surfaceLine)
+ {
+ if (surfaceLine == null)
{
- if (points == null || points.Count < 4)
- {
- throw new SurfaceLineAdapterException(Resources.SurfaceLineAdapterNoDikePointsError);
- }
+ throw new ArgumentNullException(Resources.SurfaceLineAdapterNoDikeError);
}
+ }
- private DitchCoordinates GetCoordinatesForOldShape(double xDitchDike, DitchDefinition ditchDefinition)
+ private static void ThrowWhenSurfaceLineHasNoOrLessThenFourPoints(ICollection points)
+ {
+ if (points == null || points.Count < 4)
{
- var res = new DitchCoordinates();
- res.XAtDike = xDitchDike;
- res.ZAtDike = surfaceLine.Geometry.GetZatX(res.XAtDike);
- res.XBottomAtDike = xDitchDike + ditchDefinition.DistanceToBottomDikeSide;
- res.ZBottom = res.ZAtDike - ditchDefinition.DepthBottomDikeSide;
- res.XBottomAtPolder = xDitchDike + ditchDefinition.DistanceToBottomPolderSide;
- res.XAtPolder = xDitchDike + ditchDefinition.DistanceToEndDitch;
- res.ZAtPolder = surfaceLine.Geometry.GetZatX(res.XAtPolder);
- return res;
+ throw new SurfaceLineAdapterException(Resources.SurfaceLineAdapterNoDikePointsError);
}
+ }
- private DitchCoordinates GetCoordinatesForNewShape(double xDitchDike)
- {
- var res = new DitchCoordinates();
- res.XAtDike = xDitchDike;
- res.ZAtDike = surfaceLine.Geometry.GetZatX(res.XAtDike);
- // Depth of the ditch is defined towards PolderLevel
- res.ZBottom = polderLevel - Location.NewDepthDitch;
- res.XBottomAtDike = xDitchDike + (res.ZAtDike - res.ZBottom) * Location.NewSlopeAngleDitch;
- res.XBottomAtPolder = res.XBottomAtDike + Location.NewWidthDitchBottom;
- var line = new Line
- {
- BeginPoint = new Point2D(res.XBottomAtPolder, res.ZBottom),
- EndPoint = new Point2D(res.XBottomAtPolder + offset,
- res.ZBottom + offset * Location.NewSlopeAngleDitch)
- };
- // Find the intersectionpoint(s) of the new ditch slope with the surface line
- IList intersectionpoints = surfaceLine.Geometry.IntersectionPointsXzWithLineXz(line);
- if (intersectionpoints.Count > 0)
- {
- res.XAtPolder = intersectionpoints[0].X;
- res.ZAtPolder = intersectionpoints[0].Z;
- }
- else
- {
- //new slope of ditch does not intersect with surface line (most probably because the bottom is too high)
- throw new SurfaceLineAdapterException(Resources.SurfaceLineAdapterDitchSlopeError);
- }
+ private DitchCoordinates GetCoordinatesForOldShape(double xDitchDike, DitchDefinition ditchDefinition)
+ {
+ var res = new DitchCoordinates();
+ res.XAtDike = xDitchDike;
+ res.ZAtDike = surfaceLine.Geometry.GetZatX(res.XAtDike);
+ res.XBottomAtDike = xDitchDike + ditchDefinition.DistanceToBottomDikeSide;
+ res.ZBottom = res.ZAtDike - ditchDefinition.DepthBottomDikeSide;
+ res.XBottomAtPolder = xDitchDike + ditchDefinition.DistanceToBottomPolderSide;
+ res.XAtPolder = xDitchDike + ditchDefinition.DistanceToEndDitch;
+ res.ZAtPolder = surfaceLine.Geometry.GetZatX(res.XAtPolder);
+ return res;
+ }
- return res;
+ private DitchCoordinates GetCoordinatesForNewShape(double xDitchDike)
+ {
+ var res = new DitchCoordinates();
+ res.XAtDike = xDitchDike;
+ res.ZAtDike = surfaceLine.Geometry.GetZatX(res.XAtDike);
+ // Depth of the ditch is defined towards PolderLevel
+ res.ZBottom = polderLevel - Location.NewDepthDitch;
+ res.XBottomAtDike = xDitchDike + (res.ZAtDike - res.ZBottom) * Location.NewSlopeAngleDitch;
+ res.XBottomAtPolder = res.XBottomAtDike + Location.NewWidthDitchBottom;
+ var line = new Line
+ {
+ BeginPoint = new Point2D(res.XBottomAtPolder, res.ZBottom),
+ EndPoint = new Point2D(res.XBottomAtPolder + offset,
+ res.ZBottom + offset * Location.NewSlopeAngleDitch)
+ };
+ // Find the intersectionpoint(s) of the new ditch slope with the surface line
+ IList intersectionpoints = surfaceLine.Geometry.IntersectionPointsXzWithLineXz(line);
+ if (intersectionpoints.Count > 0)
+ {
+ res.XAtPolder = intersectionpoints[0].X;
+ res.ZAtPolder = intersectionpoints[0].Z;
}
-
- private struct DitchCoordinates
+ else
{
- public double XAtDike;
- public double ZAtDike;
- public double XBottomAtDike;
- public double ZBottom;
- public double XBottomAtPolder;
- public double XAtPolder;
- public double ZAtPolder;
+ //new slope of ditch does not intersect with surface line (most probably because the bottom is too high)
+ throw new SurfaceLineAdapterException(Resources.SurfaceLineAdapterDitchSlopeError);
}
+
+ return res;
}
+
+ private struct DitchCoordinates
+ {
+ public double XAtDike;
+ public double ZAtDike;
+ public double XBottomAtDike;
+ public double ZBottom;
+ public double XBottomAtPolder;
+ public double XAtPolder;
+ public double ZAtPolder;
+ }
}
\ No newline at end of file