// 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.Chart.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?.LocalGeometry.ToArray() ?? 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(MacroStabilityInwardsSoilLayer1D soilLayer,
MacroStabilityInwardsSoilProfile1D soilProfile,
RingtoetsMacroStabilityInwardsSurfaceLine surfaceLine)
{
if (soilLayer == null || soilProfile == null || surfaceLine == null)
{
return Enumerable.Empty();
}
Point2D[] surfaceLineLocalGeometry = surfaceLine.LocalGeometry.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);
}
///
/// 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(RingtoetsMacroStabilityInwardsSurfaceLine surfaceLine)
{
return GetLocalPointsFromGeometry(surfaceLine, surfaceLine?.SurfaceLevelOutside);
}
///
/// 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(RingtoetsMacroStabilityInwardsSurfaceLine surfaceLine)
{
return GetLocalPointsFromGeometry(surfaceLine, surfaceLine?.DikeToeAtRiver);
}
///
/// Create a traffic load outside point in 2D space based on the provided .
///
/// The surface line to create the traffic load outside point for.
/// An array with a traffic load outside point in 2D space or an empty array when:
///
/// - is null;
/// - the traffic load outside point in is null.
///
///
public static Point2D[] CreateTrafficLoadOutsidePoint(RingtoetsMacroStabilityInwardsSurfaceLine surfaceLine)
{
return GetLocalPointsFromGeometry(surfaceLine, surfaceLine?.TrafficLoadOutside);
}
///
/// Create a traffic load inside point in 2D space based on the provided .
///
/// The surface line to create the traffic load inside point for.
/// An array with a traffic load inside point in 2D space or an empty array when:
///
/// - is null;
/// - the traffic load inside point in is null.
///
///
public static Point2D[] CreateTrafficLoadInsidePoint(RingtoetsMacroStabilityInwardsSurfaceLine surfaceLine)
{
return GetLocalPointsFromGeometry(surfaceLine, surfaceLine?.TrafficLoadInside);
}
///
/// 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(RingtoetsMacroStabilityInwardsSurfaceLine 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(RingtoetsMacroStabilityInwardsSurfaceLine 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(RingtoetsMacroStabilityInwardsSurfaceLine 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(RingtoetsMacroStabilityInwardsSurfaceLine 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(RingtoetsMacroStabilityInwardsSurfaceLine 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(RingtoetsMacroStabilityInwardsSurfaceLine 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(RingtoetsMacroStabilityInwardsSurfaceLine 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(RingtoetsMacroStabilityInwardsSurfaceLine 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(RingtoetsMacroStabilityInwardsSurfaceLine surfaceLine)
{
return GetLocalPointsFromGeometry(surfaceLine, surfaceLine?.DitchPolderSide);
}
private static Point2D[] GetLocalPointsFromGeometry(RingtoetsMacroStabilityInwardsSurfaceLine surfaceLine,
Point3D worldCoordinate)
{
if (surfaceLine == null || worldCoordinate == null)
{
return new Point2D[0];
}
return new[]
{
surfaceLine.GetLocalPointFromGeometry(worldCoordinate)
};
}
private static IEnumerable GetSoilLayerWithSurfaceLineIntersection(Point2D[] surfaceLineLocalGeometry,
MacroStabilityInwardsSoilLayer1D soilLayer,
MacroStabilityInwardsSoilProfile1D soilProfile)
{
Point2D[] surfaceLineAsPolygon = CreateSurfaceLinePolygonAroundSoilLayer(surfaceLineLocalGeometry, soilLayer, soilProfile);
Point2D[] soilLayerAsPolygon = CreateSurfaceLineWideSoilLayer(surfaceLineLocalGeometry, soilLayer, soilProfile);
return AdvancedMath2D.PolygonIntersectionWithPolygon(surfaceLineAsPolygon, soilLayerAsPolygon);
}
private static bool IsSurfaceLineAboveSoilLayer(IEnumerable surfaceLineLocalGeometry,
MacroStabilityInwardsSoilLayer1D soilLayer)
{
double surfaceLineLowestPointY = surfaceLineLocalGeometry.Select(p => p.Y).Min();
double topLevel = soilLayer.Top;
return surfaceLineLowestPointY >= topLevel;
}
private static bool IsSurfaceLineBelowSoilLayer(Point2D[] surfaceLineLocalGeometry,
MacroStabilityInwardsSoilLayer1D soilLayer,
MacroStabilityInwardsSoilProfile1D soilProfile)
{
double topLevel = soilLayer.Top;
return surfaceLineLocalGeometry.Select(p => p.Y).Max() <= topLevel - soilProfile.GetLayerThickness(soilLayer);
}
private static Point2D[] CreateSurfaceLinePolygonAroundSoilLayer(Point2D[] surfaceLineLocalGeometry,
MacroStabilityInwardsSoilLayer1D soilLayer,
MacroStabilityInwardsSoilProfile1D 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,
MacroStabilityInwardsSoilLayer1D soilLayer,
MacroStabilityInwardsSoilProfile1D 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)
};
}
}
}