// Copyright (C) Stichting Deltares 2020. All rights reserved.
//
// This file is part of the Layer On Slope Tool.
//
// The Layer On Slope Tool is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
//
// All names, logos, and references to "Deltares" are registered trademarks of
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
using System;
using Deltares.LayerOnSlopeTool.Data;
namespace Deltares.LayerOnSlopeTool.LayerCreator
{
///
public class SurfaceLineProcessor
{
private const double Tolerance = 1e-4;
private const double HorizontalOffset = 0.01;
private readonly SurfaceLine surfaceLine;
private readonly SurfaceLinePoint dikeTopPolder;
private readonly SurfaceLinePoint dikeToePolder;
/// Initializes a new instance of the class.
/// The org surface line.
public SurfaceLineProcessor(SurfaceLine orgSurfaceLine)
{
surfaceLine = orgSurfaceLine;
dikeTopPolder = surfaceLine.GetSurfaceLinePointByType(CharacteristicPointType.DikeTopAtPolder);
if (dikeTopPolder == null)
{
throw new Exception(string.Format("Surface line {0} has no Dike Top.", surfaceLine.SurfaceLineId));
}
dikeToePolder = surfaceLine.GetSurfaceLinePointByType(CharacteristicPointType.DikeToeAtPolder);
if (dikeToePolder == null)
{
throw new Exception(string.Format("Surface line {0} has no Dike Toe.", surfaceLine.SurfaceLineId));
}
}
/// Creates the lowered surface line.
/// The layer thickness.
///
public SurfaceLine CreateLoweredSurfaceLine(double layerThickness)
{
var loweredSurfaceLine = new SurfaceLine();
foreach (var point in surfaceLine.SurfaceLinePoints)
{
if (point.XCoordinate <= dikeTopPolder.XCoordinate)
{
HandlePointsUpToAndIncludingDikeTopPolder(layerThickness, point, loweredSurfaceLine);
}
else
{
if (point.XCoordinate > dikeTopPolder.XCoordinate + HorizontalOffset &&
point.XCoordinate < dikeToePolder.XCoordinate - HorizontalOffset)
{
HandlePointsBetweenDikeTopPolderAndDikeToePolder(layerThickness, point, loweredSurfaceLine);
}
else
{
HandlePointsAtDikeToePolderAndBeyond(layerThickness, point, loweredSurfaceLine);
}
}
}
loweredSurfaceLine.SurfaceLineId = surfaceLine.SurfaceLineId + "_low";
return loweredSurfaceLine;
}
private static void HandlePointsBetweenDikeTopPolderAndDikeToePolder(double layerThickness,
SurfaceLinePoint point, SurfaceLine loweredSurfaceLine)
{
var newPointLowered = new SurfaceLinePoint
{
XCoordinate = point.XCoordinate,
ZCoordinate = point.ZCoordinate - layerThickness,
PointType = point.PointType
};
loweredSurfaceLine.SurfaceLinePoints.Add(newPointLowered);
}
private void HandlePointsAtDikeToePolderAndBeyond(double layerThickness,
SurfaceLinePoint point, SurfaceLine loweredSurfaceLine)
{
if (Math.Abs(point.XCoordinate - dikeToePolder.XCoordinate) < Tolerance)
{
var newPointAtDikeToe = new SurfaceLinePoint
{
XCoordinate = point.XCoordinate - HorizontalOffset,
ZCoordinate = point.ZCoordinate - layerThickness,
PointType = CharacteristicPointType.None
};
loweredSurfaceLine.SurfaceLinePoints.Add(newPointAtDikeToe);
}
if (point.XCoordinate >= dikeToePolder.XCoordinate)
{
var newPointBeyondDikeToe = new SurfaceLinePoint
{
XCoordinate = point.XCoordinate,
ZCoordinate = point.ZCoordinate,
PointType = point.PointType
};
loweredSurfaceLine.SurfaceLinePoints.Add(newPointBeyondDikeToe);
}
}
private void HandlePointsUpToAndIncludingDikeTopPolder(double layerThickness, SurfaceLinePoint point,
SurfaceLine loweredSurfaceLine)
{
var newPointUpToDikeTop = new SurfaceLinePoint
{
XCoordinate = point.XCoordinate,
ZCoordinate = point.ZCoordinate,
PointType = point.PointType
};
loweredSurfaceLine.SurfaceLinePoints.Add(newPointUpToDikeTop);
if (Math.Abs(point.XCoordinate - dikeTopPolder.XCoordinate) < Tolerance)
{
var newPointAtDikeTop = new SurfaceLinePoint
{
XCoordinate = point.XCoordinate + HorizontalOffset,
ZCoordinate = point.ZCoordinate - layerThickness,
PointType = CharacteristicPointType.None
};
loweredSurfaceLine.SurfaceLinePoints.Add(newPointAtDikeTop);
}
}
}
}