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