// Copyright (C) Stichting Deltares 2017. All rights reserved.
//
// This file is part of Ringtoets.
//
// Ringtoets is free software: you can redistribute it and/or modify
// it under the terms of the GNU 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 General Public License for more details.
//
// You should have received a copy of the GNU 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.Collections.Generic;
using System.Linq;
using Core.Common.Base.Data;
using Core.Common.Base.Geometry;
using Core.Components.Chart.Data;
using Ringtoets.MacroStabilityInwards.Data;
using Ringtoets.MacroStabilityInwards.Primitives;
namespace Ringtoets.MacroStabilityInwards.Forms.Factories
{
///
/// Factory for creating arrays of to use in
/// (created via ).
///
internal static class MacroStabilityInwardsChartDataPointsFactory
{
///
/// Create surface line points in 2D space based on the provided .
///
/// The to create the surface line points for.
/// An array of points in 2D space or an empty array when is null.
public static Point2D[] CreateSurfaceLinePoints(MacroStabilityInwardsSurfaceLine surfaceLine)
{
return surfaceLine?.LocalGeometry.ToArray() ?? new Point2D[0];
}
///
/// Create a surface level outside point in 2D space based on the provided .
///
/// The surface line to create the surface level outside point for.
/// An array with a surface level outside point in 2D space or an empty array when:
///
/// - is null;
/// - the surface level outside point in is null.
///
///
public static Point2D[] CreateSurfaceLevelOutsidePoint(MacroStabilityInwardsSurfaceLine surfaceLine)
{
return GetLocalPointsFromGeometry(surfaceLine, surfaceLine?.SurfaceLevelOutside);
}
///
/// Create a dike top at river point in 2D space based on the provided .
///
/// The surface line to create the dike top at river point for.
/// An array with a dike top at river point in 2D space or an empty array when:
///
/// - is null;
/// - the dike top at river point in is null.
///
///
public static Point2D[] CreateDikeTopAtRiverPoint(MacroStabilityInwardsSurfaceLine surfaceLine)
{
return GetLocalPointsFromGeometry(surfaceLine, surfaceLine?.DikeTopAtRiver);
}
///
/// Create a dike toe at river point in 2D space based on the provided .
///
/// The surface line to create the dike toe at river point for.
/// An array with a dike toe at river point in 2D space or an empty array when:
///
/// - is null;
/// - the dike toe at river point in is null.
///
///
public static Point2D[] CreateDikeToeAtRiverPoint(MacroStabilityInwardsSurfaceLine surfaceLine)
{
return GetLocalPointsFromGeometry(surfaceLine, surfaceLine?.DikeToeAtRiver);
}
///
/// Create a dike top at polder point in 2D space based on the provided .
///
/// The surface line to create the dike top at polder point for.
/// An array with a dike top at polder point in 2D space or an empty array when:
///
/// - is null;
/// - the dike top at polder point in is null.
///
///
public static Point2D[] CreateDikeTopAtPolderPoint(MacroStabilityInwardsSurfaceLine surfaceLine)
{
return GetLocalPointsFromGeometry(surfaceLine, surfaceLine?.DikeTopAtPolder);
}
///
/// Create a shoulder base inside point in 2D space based on the provided .
///
/// The surface line to create the shoulder base inside point for.
/// An array with a shoulder base inside point in 2D space or an empty array when:
///
/// - is null;
/// - the shoulder base inside point in is null.
///
///
public static Point2D[] CreateShoulderBaseInsidePoint(MacroStabilityInwardsSurfaceLine surfaceLine)
{
return GetLocalPointsFromGeometry(surfaceLine, surfaceLine?.ShoulderBaseInside);
}
///
/// Create a shoulder top inside point in 2D space based on the provided .
///
/// The surface line to create the shoulder top inside point for.
/// An array with a shoulder top inside point in 2D space or an empty array when:
///
/// - is null;
/// - the shoulder top inside point in is null.
///
///
public static Point2D[] CreateShoulderTopInsidePoint(MacroStabilityInwardsSurfaceLine surfaceLine)
{
return GetLocalPointsFromGeometry(surfaceLine, surfaceLine?.ShoulderTopInside);
}
///
/// Create a dike toe at polder point in 2D space based on the provided .
///
/// The surface line to create the dike toe at polder point for.
/// An array with a dike toe at polder point in 2D space or an empty array when:
///
/// - is null;
/// - the dike toe at polder point in is null.
///
///
public static Point2D[] CreateDikeToeAtPolderPoint(MacroStabilityInwardsSurfaceLine surfaceLine)
{
return GetLocalPointsFromGeometry(surfaceLine, surfaceLine?.DikeToeAtPolder);
}
///
/// Create a ditch dike side point in 2D space based on the provided .
///
/// The surface line to create the ditch dike side point for.
/// An array with a ditch dike side point in 2D space or an empty array when:
///
/// - is null;
/// - the ditch dike side point in is null.
///
///
public static Point2D[] CreateDitchDikeSidePoint(MacroStabilityInwardsSurfaceLine surfaceLine)
{
return GetLocalPointsFromGeometry(surfaceLine, surfaceLine?.DitchDikeSide);
}
///
/// Create a bottom ditch dike side point in 2D space based on the provided .
///
/// The surface line to create the bottom ditch dike side point for.
/// An array with a bottom ditch dike side point in 2D space or an empty array when:
///
/// - is null;
/// - the bottom ditch dike side point in is null.
///
///
public static Point2D[] CreateBottomDitchDikeSidePoint(MacroStabilityInwardsSurfaceLine surfaceLine)
{
return GetLocalPointsFromGeometry(surfaceLine, surfaceLine?.BottomDitchDikeSide);
}
///
/// Create a bottom ditch polder side point in 2D space based on the provided .
///
/// The surface line to create the bottom ditch polder side point for.
/// An array with a bottom ditch polder side point in 2D space or an empty array when:
///
/// - is null;
/// - the bottom ditch polder side point in is null.
///
///
public static Point2D[] CreateBottomDitchPolderSidePoint(MacroStabilityInwardsSurfaceLine surfaceLine)
{
return GetLocalPointsFromGeometry(surfaceLine, surfaceLine?.BottomDitchPolderSide);
}
///
/// Create a surface level inside point in 2D space based on the provided .
///
/// The surface line to create the surface level inside point for.
/// An array with a surface level inside point in 2D space or an empty array when:
///
/// - is null;
/// - the surface level inside point in is null.
///
///
public static Point2D[] CreateSurfaceLevelInsidePoint(MacroStabilityInwardsSurfaceLine surfaceLine)
{
return GetLocalPointsFromGeometry(surfaceLine, surfaceLine?.SurfaceLevelInside);
}
///
/// Create a ditch polder side point in 2D space based on the provided .
///
/// The surface line to create the ditch polder side point for.
/// An array with a ditch polder side point in 2D space or an empty array when:
///
/// - is null;
/// - the ditch polder side point in is null.
///
///
public static Point2D[] CreateDitchPolderSidePoint(MacroStabilityInwardsSurfaceLine surfaceLine)
{
return GetLocalPointsFromGeometry(surfaceLine, surfaceLine?.DitchPolderSide);
}
///
/// Create areas of holes in 2D space based on the provided .
///
/// The soil profile to create the holes for.
/// An array with an array of points in 2D space or an empty array when
/// is null.
public static IEnumerable CreateHolesAreas(IMacroStabilityInwardsSoilProfileUnderSurfaceLine soilProfile)
{
return soilProfile?.Layers.SelectMany(l => l.Holes).ToArray() ?? new Point2D[0][];
}
///
/// Create points of the outer ring in 2D space based on the provided .
///
/// The soil layer to create the outer ring for.
/// An array of points in 2D space or an empty array when
/// is null.
public static IEnumerable CreateOuterRingPoints(IMacroStabilityInwardsSoilLayerUnderSurfaceLine soilLayer)
{
return soilLayer != null
? new[]
{
soilLayer.OuterRing
}
: new Point2D[0][];
}
#region SoilLayers and Surface Line Helpers
private static Point2D[] GetLocalPointsFromGeometry(MacroStabilityInwardsSurfaceLine surfaceLine,
Point3D worldCoordinate)
{
if (surfaceLine == null || worldCoordinate == null)
{
return new Point2D[0];
}
return new[]
{
surfaceLine.GetLocalPointFromGeometry(worldCoordinate)
};
}
#endregion
#region Grid Helpers
///
/// Creates grid points in 2D space based on the provided .
///
/// The grid to create the grid points for.
/// The grid determination type.
/// An array of interpolated points in 2D space based on the provided
/// or an empty array when:
///
/// - is null;
/// - is ;
/// - the grid settings are invalid:
///
/// - the grid boundaries are ;
/// - the number of horizontal or vertical points are not greater than zero.
///
///
///
///
public static Point2D[] CreateGridPoints(MacroStabilityInwardsGrid grid, MacroStabilityInwardsGridDeterminationType gridDeterminationType)
{
if (grid == null
|| gridDeterminationType == MacroStabilityInwardsGridDeterminationType.Automatic
|| !AreGridSettingsValid(grid))
{
return new Point2D[0];
}
var points = new List();
IEnumerable interPolatedVerticalPositions = GetInterPolatedVerticalPositions(grid.ZBottom,
grid.ZTop,
grid.NumberOfVerticalPoints);
foreach (RoundedDouble interPolatedVerticalPosition in interPolatedVerticalPositions)
{
points.AddRange(GetInterPolatedHorizontalPoints(grid.XLeft,
grid.XRight,
interPolatedVerticalPosition,
grid.NumberOfHorizontalPoints));
}
return points.ToArray();
}
private static bool AreGridSettingsValid(MacroStabilityInwardsGrid grid)
{
return grid.NumberOfHorizontalPoints > 0
&& grid.NumberOfVerticalPoints > 0
&& !double.IsNaN(grid.XLeft)
&& !double.IsNaN(grid.XRight)
&& !double.IsNaN(grid.ZTop)
&& !double.IsNaN(grid.ZBottom);
}
private static IEnumerable GetInterPolatedVerticalPositions(RoundedDouble startPoint,
RoundedDouble endPoint,
int nrOfPoints)
{
if (nrOfPoints <= 1)
{
yield return startPoint;
yield break;
}
int nrofInterPolatedPoints = nrOfPoints - 1;
RoundedDouble deltaZ = endPoint - startPoint;
RoundedDouble deltaZBetweenPoints = nrOfPoints < 2
? (RoundedDouble) 0.0
: (RoundedDouble) (deltaZ / nrofInterPolatedPoints);
RoundedDouble z = startPoint;
int nrOfRepetitions = nrofInterPolatedPoints < 0
? 0
: nrofInterPolatedPoints;
for (var i = 0; i < nrOfRepetitions + 1; i++)
{
yield return z;
z += deltaZBetweenPoints;
}
}
private static IEnumerable GetInterPolatedHorizontalPoints(RoundedDouble startPoint,
RoundedDouble endPoint,
RoundedDouble zPoint,
int nrOfPoints)
{
if (nrOfPoints <= 1)
{
yield return new Point2D(startPoint, zPoint);
yield break;
}
int nrofInterPolatedPoints = nrOfPoints - 1;
RoundedDouble deltaX = endPoint - startPoint;
RoundedDouble deltaXBetweenPoints = nrOfPoints < 2
? (RoundedDouble) 0
: (RoundedDouble) (deltaX / nrofInterPolatedPoints);
RoundedDouble x = startPoint;
int nrOfRepetitions = nrofInterPolatedPoints < 0
? 0
: nrofInterPolatedPoints;
for (var i = 0; i < nrOfRepetitions + 1; i++)
{
yield return new Point2D(x, zPoint);
x += deltaXBetweenPoints;
}
}
#endregion
}
}