using System;
using System.Collections.Generic;
using System.Linq;
using Core.Common.Base.Geometry;
using Ringtoets.Common.Forms.Helpers;
using Ringtoets.Piping.Data;
using Ringtoets.Piping.Primitives;
namespace Ringtoets.Piping.Forms
{
///
/// Class holds methods to help views when dealing with
///
public static class PipingCalculationConfigurationHelper
{
///
/// Creates a structure of and based on combination of the
/// and the .
///
/// Surface lines to generate the structure for and to use to configure
/// with.
/// The soil models from which profiles are taken to configure with.
/// General input to assign to each generated piping calculation.
/// Semi probabilistic input to assign to each generated piping calculation.
/// A structure or matching combinations of and
/// profiles of intersecting .
/// Throw when either:
///
/// - is null
/// - is null
/// - is null
/// - is null
///
public static IEnumerable GenerateCalculationsStructure(IEnumerable surfaceLines, IEnumerable soilModels, GeneralPipingInput generalInput, SemiProbabilisticPipingInput semiProbabilisticInput)
{
if (surfaceLines == null)
{
throw new ArgumentNullException("surfaceLines");
}
if (soilModels == null)
{
throw new ArgumentNullException("soilModels");
}
if (generalInput == null)
{
throw new ArgumentNullException("generalInput");
}
if (semiProbabilisticInput == null)
{
throw new ArgumentNullException("semiProbabilisticInput");
}
return surfaceLines.Select(sl => CreateCalculationGroup(sl, soilModels, generalInput, semiProbabilisticInput));
}
///
/// Gets the piping soil profiles matching the input of a calculation.
///
/// The surface line used to match a .
/// The available soil models.
/// The (sub)set of soil profiles from
/// or empty if no matching instances can be found
/// or when there is not enough information to associate soil profiles to the calculation.
public static IEnumerable GetPipingSoilProfilesForSurfaceLine(RingtoetsPipingSurfaceLine surfaceLine, IEnumerable availableSoilModels)
{
if (surfaceLine == null)
{
return Enumerable.Empty();
}
Segment2D[] surfaceLineSegments = Math2D.ConvertLinePointsToLineSegments(surfaceLine.Points.Select(p => new Point2D(p.X, p.Y))).ToArray();
var soilProfileObjectsForCalculation = new List();
foreach (StochasticSoilModel stochasticSoilModel in availableSoilModels.Where(sm => sm.StochasticSoilProfiles.Any()))
{
if (DoesSoilModelGeometryIntersectWithSurfaceLineGeometry(stochasticSoilModel, surfaceLineSegments))
{
soilProfileObjectsForCalculation.AddRange(stochasticSoilModel.StochasticSoilProfiles.Select(ssp => ssp.SoilProfile));
}
}
return soilProfileObjectsForCalculation;
}
private static IPipingCalculationItem CreateCalculationGroup(RingtoetsPipingSurfaceLine surfaceLine, IEnumerable soilModels, GeneralPipingInput generalInput, SemiProbabilisticPipingInput semiProbabilisticInput)
{
var pipingCalculationGroup = new PipingCalculationGroup(surfaceLine.Name, true);
foreach (var profile in GetPipingSoilProfilesForSurfaceLine(surfaceLine, soilModels))
{
pipingCalculationGroup.Children.Add(CreatePipingCalculation(surfaceLine, profile, pipingCalculationGroup.Children, generalInput, semiProbabilisticInput));
}
return pipingCalculationGroup;
}
private static IPipingCalculationItem CreatePipingCalculation(RingtoetsPipingSurfaceLine surfaceLine, PipingSoilProfile profile, IEnumerable calculations, GeneralPipingInput generalInput, SemiProbabilisticPipingInput semiProbabilisticInput)
{
var nameBase = string.Format("{0} {1}", surfaceLine.Name, profile.Name);
var name = NamingHelper.GetUniqueName(calculations, nameBase, c => c.Name);
return new PipingCalculation(generalInput, semiProbabilisticInput)
{
Name = name,
InputParameters =
{
SurfaceLine = surfaceLine,
SoilProfile = profile
}
};
}
private static bool DoesSoilModelGeometryIntersectWithSurfaceLineGeometry(StochasticSoilModel stochasticSoilModel, Segment2D[] surfaceLineSegments)
{
IEnumerable soilProfileGeometrySegments = Math2D.ConvertLinePointsToLineSegments(stochasticSoilModel.Geometry);
return soilProfileGeometrySegments.Any(s => DoesSegmentIntersectWithSegmentArray(s, surfaceLineSegments));
}
private static bool DoesSegmentIntersectWithSegmentArray(Segment2D segment, Segment2D[] segmentArray)
{
// Consider intersections and overlaps similarly
return segmentArray.Any(sls => Math2D.GetIntersectionBetweenSegments(segment, sls).IntersectionType != Intersection2DType.DoesNotIntersect);
}
}
}