// 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; using System.Collections.Generic; using System.Linq; using Core.Common.Base.Geometry; using Core.Common.Geometry; using Core.Components.Charting.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(RingtoetsMacroStabilityInwardsSurfaceLine surfaceLine) { return surfaceLine?.ProjectGeometryToLZ().ToArray() ?? new Point2D[0]; } /// /// Create an entry point in 2D space based on the provided . /// /// The to create the entry point for. /// An array with an entry point in 2D space or an empty array when: /// /// is null; /// the in is null; /// the entry point in equals double.NaN. /// /// public static Point2D[] CreateEntryPointPoint(MacroStabilityInwardsInput macroStabilityInwardsInput) { return macroStabilityInwardsInput?.SurfaceLine != null && !double.IsNaN(macroStabilityInwardsInput.EntryPointL) ? new[] { new Point2D(macroStabilityInwardsInput.EntryPointL, macroStabilityInwardsInput.SurfaceLine.GetZAtL(macroStabilityInwardsInput.EntryPointL)) } : new Point2D[0]; } /// /// Create an exit point in 2D space based on the provided . /// /// The to create the exit point for. /// An array with an exit point in 2D space or an empty array when: /// /// is null; /// the in is null; /// the exit point in equals double.NaN. /// /// public static Point2D[] CreateExitPointPoint(MacroStabilityInwardsInput macroStabilityInwardsInput) { return macroStabilityInwardsInput?.SurfaceLine != null && !double.IsNaN(macroStabilityInwardsInput.ExitPointL) ? new[] { new Point2D(macroStabilityInwardsInput.ExitPointL, macroStabilityInwardsInput.SurfaceLine.GetZAtL(macroStabilityInwardsInput.ExitPointL)) } : new Point2D[0]; } /// /// Create a ditch polder side point in 2D space based on the provided . /// /// The 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(RingtoetsMacroStabilityInwardsSurfaceLine surfaceLine) { return surfaceLine?.DitchPolderSide != null ? new[] { surfaceLine.GetLocalPointFromGeometry(surfaceLine.DitchPolderSide) } : new Point2D[0]; } /// /// Create a bottom ditch polder side point in 2D space based on the provided . /// /// The 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(RingtoetsMacroStabilityInwardsSurfaceLine surfaceLine) { return surfaceLine?.BottomDitchPolderSide != null ? new[] { surfaceLine.GetLocalPointFromGeometry(surfaceLine.BottomDitchPolderSide) } : new Point2D[0]; } /// /// Create a bottom ditch dike side point in 2D space based on the provided . /// /// The 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(RingtoetsMacroStabilityInwardsSurfaceLine surfaceLine) { return surfaceLine?.BottomDitchDikeSide != null ? new[] { surfaceLine.GetLocalPointFromGeometry(surfaceLine.BottomDitchDikeSide) } : new Point2D[0]; } /// /// Create a ditch dike side point in 2D space based on the provided . /// /// The 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(RingtoetsMacroStabilityInwardsSurfaceLine surfaceLine) { return surfaceLine?.DitchDikeSide != null ? new[] { surfaceLine.GetLocalPointFromGeometry(surfaceLine.DitchDikeSide) } : new Point2D[0]; } /// /// Create a dike toe at river point in 2D space based on the provided . /// /// The 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(RingtoetsMacroStabilityInwardsSurfaceLine surfaceLine) { return surfaceLine?.DikeToeAtRiver != null ? new[] { surfaceLine.GetLocalPointFromGeometry(surfaceLine.DikeToeAtRiver) } : new Point2D[0]; } /// /// Create a dike toe at polder point in 2D space based on the provided . /// /// The 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(RingtoetsMacroStabilityInwardsSurfaceLine surfaceLine) { return surfaceLine?.DikeToeAtPolder != null ? new[] { surfaceLine.GetLocalPointFromGeometry(surfaceLine.DikeToeAtPolder) } : new Point2D[0]; } /// /// Create a collection of soil layer points (areas) in 2D space based on the provided and . /// /// The to create the soil layer points for. /// The that contains . /// The that may intersect with /// the and by doing that restricts the drawn height of it. /// A collection which contains one or more (in the case of /// splitting the layer in multiple parts) arrays of points in 2D space or an empty array when: /// /// is null; /// is null; /// is null; /// the is below the . /// /// public static IEnumerable CreateSoilLayerAreas(MacroStabilityInwardsSoilLayer soilLayer, MacroStabilityInwardsSoilProfile soilProfile, RingtoetsMacroStabilityInwardsSurfaceLine surfaceLine) { if (soilLayer == null || soilProfile == null || surfaceLine == null) { return Enumerable.Empty(); } Point2D[] surfaceLineLocalGeometry = surfaceLine.ProjectGeometryToLZ().ToArray(); if (IsSurfaceLineAboveSoilLayer(surfaceLineLocalGeometry, soilLayer)) { return new List { CreateSurfaceLineWideSoilLayer(surfaceLineLocalGeometry, soilLayer, soilProfile) }; } if (IsSurfaceLineBelowSoilLayer(surfaceLineLocalGeometry, soilLayer, soilProfile)) { return Enumerable.Empty(); } return GetSoilLayerWithSurfaceLineIntersection(surfaceLineLocalGeometry, soilLayer, soilProfile); } private static IEnumerable GetSoilLayerWithSurfaceLineIntersection(Point2D[] surfaceLineLocalGeometry, MacroStabilityInwardsSoilLayer soilLayer, MacroStabilityInwardsSoilProfile soilProfile) { Point2D[] surfaceLineAsPolygon = CreateSurfaceLinePolygonAroundSoilLayer(surfaceLineLocalGeometry, soilLayer, soilProfile); Point2D[] soilLayerAsPolygon = CreateSurfaceLineWideSoilLayer(surfaceLineLocalGeometry, soilLayer, soilProfile); return AdvancedMath2D.PolygonIntersectionWithPolygon(surfaceLineAsPolygon, soilLayerAsPolygon); } private static bool IsSurfaceLineAboveSoilLayer(IEnumerable surfaceLineLocalGeometry, MacroStabilityInwardsSoilLayer soilLayer) { double surfaceLineLowestPointY = surfaceLineLocalGeometry.Select(p => p.Y).Min(); double topLevel = soilLayer.Top; return surfaceLineLowestPointY >= topLevel; } private static bool IsSurfaceLineBelowSoilLayer(Point2D[] surfaceLineLocalGeometry, MacroStabilityInwardsSoilLayer soilLayer, MacroStabilityInwardsSoilProfile soilProfile) { double topLevel = soilLayer.Top; return surfaceLineLocalGeometry.Select(p => p.Y).Max() <= topLevel - soilProfile.GetLayerThickness(soilLayer); } private static Point2D[] CreateSurfaceLinePolygonAroundSoilLayer(Point2D[] surfaceLineLocalGeometry, MacroStabilityInwardsSoilLayer soilLayer, MacroStabilityInwardsSoilProfile soilProfile) { List surfaceLineAsPolygon = surfaceLineLocalGeometry.ToList(); double topLevel = soilLayer.Top; double bottomLevel = topLevel - soilProfile.GetLayerThickness(soilLayer); double surfaceLineLowestPointY = surfaceLineAsPolygon.Select(p => p.Y).Min(); double closingSurfaceLineToPolygonBottomLevel = Math.Min(surfaceLineLowestPointY, bottomLevel) - 1; surfaceLineAsPolygon.Add(new Point2D(surfaceLineAsPolygon.Last().X, closingSurfaceLineToPolygonBottomLevel)); surfaceLineAsPolygon.Add(new Point2D(surfaceLineAsPolygon.First().X, closingSurfaceLineToPolygonBottomLevel)); return surfaceLineAsPolygon.ToArray(); } private static Point2D[] CreateSurfaceLineWideSoilLayer(Point2D[] surfaceLineLocalGeometry, MacroStabilityInwardsSoilLayer soilLayer, MacroStabilityInwardsSoilProfile soilProfile) { Point2D firstSurfaceLinePoint = surfaceLineLocalGeometry.First(); Point2D lastSurfaceLinePoint = surfaceLineLocalGeometry.Last(); double startX = firstSurfaceLinePoint.X; double endX = lastSurfaceLinePoint.X; double topLevel = soilLayer.Top; double bottomLevel = topLevel - soilProfile.GetLayerThickness(soilLayer); return new[] { new Point2D(startX, topLevel), new Point2D(endX, topLevel), new Point2D(endX, bottomLevel), new Point2D(startX, bottomLevel) }; } } }