// Copyright (C) Stichting Deltares 2016. 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.Piping.Data;
using Ringtoets.Piping.Primitives;
namespace Ringtoets.Piping.Forms.Views
{
///
/// Factory for creating arrays of to use in
/// (created via ).
///
public static class PipingChartDataPointsFactory
{
///
/// 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(RingtoetsPipingSurfaceLine surfaceLine)
{
return surfaceLine != null
? 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(PipingInput pipingInput)
{
return pipingInput != null && pipingInput.SurfaceLine != null && !double.IsNaN(pipingInput.EntryPointL)
? new[]
{
new Point2D(pipingInput.EntryPointL, pipingInput.SurfaceLine.GetZAtL(pipingInput.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(PipingInput pipingInput)
{
return pipingInput != null && pipingInput.SurfaceLine != null && !double.IsNaN(pipingInput.ExitPointL)
? new[]
{
new Point2D(pipingInput.ExitPointL, pipingInput.SurfaceLine.GetZAtL(pipingInput.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(RingtoetsPipingSurfaceLine surfaceLine)
{
return surfaceLine != null && 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(RingtoetsPipingSurfaceLine surfaceLine)
{
return surfaceLine != null && 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(RingtoetsPipingSurfaceLine surfaceLine)
{
return surfaceLine != null && 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(RingtoetsPipingSurfaceLine surfaceLine)
{
return surfaceLine != null && 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(RingtoetsPipingSurfaceLine surfaceLine)
{
return surfaceLine != null && 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(RingtoetsPipingSurfaceLine surfaceLine)
{
return surfaceLine != null && 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(PipingSoilLayer soilLayer, PipingSoilProfile soilProfile, RingtoetsPipingSurfaceLine surfaceLine)
{
if (soilLayer == null || soilProfile == null || surfaceLine == null)
{
return Enumerable.Empty();
}
var 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, PipingSoilLayer soilLayer, PipingSoilProfile soilProfile)
{
var surfaceLineAsPolygon = CreateSurfaceLinePolygonAroundSoilLayer(surfaceLineLocalGeometry, soilLayer, soilProfile);
var soilLayerAsPolygon = CreateSurfaceLineWideSoilLayer(surfaceLineLocalGeometry, soilLayer, soilProfile);
return AdvancedMath2D.PolygonIntersectionWithPolygon(surfaceLineAsPolygon, soilLayerAsPolygon);
}
private static bool IsSurfaceLineAboveSoilLayer(IEnumerable surfaceLineLocalGeometry, PipingSoilLayer soilLayer)
{
var surfaceLineLowestPointY = surfaceLineLocalGeometry.Select(p => p.Y).Min();
var topLevel = soilLayer.Top;
return surfaceLineLowestPointY >= topLevel;
}
private static bool IsSurfaceLineBelowSoilLayer(Point2D[] surfaceLineLocalGeometry, PipingSoilLayer soilLayer, PipingSoilProfile soilProfile)
{
var topLevel = soilLayer.Top;
return surfaceLineLocalGeometry.Select(p => p.Y).Max() <= topLevel - soilProfile.GetLayerThickness(soilLayer);
}
private static Point2D[] CreateSurfaceLinePolygonAroundSoilLayer(Point2D[] surfaceLineLocalGeometry, PipingSoilLayer soilLayer, PipingSoilProfile soilProfile)
{
var surfaceLineAsPolygon = surfaceLineLocalGeometry.ToList();
var topLevel = soilLayer.Top;
var bottomLevel = topLevel - soilProfile.GetLayerThickness(soilLayer);
var 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, PipingSoilLayer soilLayer, PipingSoilProfile soilProfile)
{
var firstSurfaceLinePoint = surfaceLineLocalGeometry.First();
var lastSurfaceLinePoint = surfaceLineLocalGeometry.Last();
var startX = firstSurfaceLinePoint.X;
var endX = lastSurfaceLinePoint.X;
var topLevel = soilLayer.Top;
var bottomLevel = topLevel - soilProfile.GetLayerThickness(soilLayer);
return new[]
{
new Point2D(startX, topLevel),
new Point2D(endX, topLevel),
new Point2D(endX, bottomLevel),
new Point2D(startX, bottomLevel)
};
}
}
}