// 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 } }