Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilSurfaceProfile.cs =================================================================== diff -u -r3258 -r3259 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilSurfaceProfile.cs (.../SoilSurfaceProfile.cs) (revision 3258) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilSurfaceProfile.cs (.../SoilSurfaceProfile.cs) (revision 3259) @@ -142,6 +142,76 @@ } /// + /// Updates the layers. + /// + private void Create2DGeometryBasedOn1DProfileAndSurfaceLine() + { + var filteredSoilLayers = FilterSoilLayersToConvert(originalSoilProfile1D, surfaceLine2); + + var xCoordinatesToTraverse = GetXCoordinates(filteredSoilLayers, surfaceLine2).ToArray(); + var layerData = CreateLayerData(filteredSoilLayers, surfaceLine2, xCoordinatesToTraverse); + + BuildGeometryModel(Geometry, layerData, originalSoilProfile1D, surfaceLine2); + BuildSoilLayer2D(Surfaces, layerData, Geometry); + } + + + private void BuildGeometryModel(GeometryData geometryData, + IEnumerable layers, + SoilProfile1D profile, + SurfaceLine2 surfaceLine) + { + if (surfaceLine.Geometry == null + || profile == null + || profile.Layers.Count == 0 + || surfaceLine.Geometry.GetMaxZ() < profile.BottomLevel + || surfaceLine.Geometry.Points.Count < 2) + { + return; + } + + GeometryBounds bounds = surfaceLine.Geometry.GetGeometryBounds(); + double minX = bounds.Left; + double maxX = bounds.Right; + + geometryData.Clear(); + geometryData.Left = minX; + geometryData.Right = maxX; + geometryData.Bottom = Math.Min(profile.BottomLevel, surfaceLine2.Geometry.GetMinZ() - 1); + + var pointsToBeAdded = layers.SelectMany(l => l.Points); + var curvesToBeAdded = layers.SelectMany(l => l.Curves); + geometryData.NewlyEffectedPoints.AddRange(pointsToBeAdded); + geometryData.NewlyEffectedCurves.AddRange(curvesToBeAdded); + geometryData.RegenerateGeometry(); + } + + private void BuildSoilLayer2D(ICollection soilLayer2Ds, + IEnumerable layers, + GeometryData geometryData) + { + soilLayer2Ds.Clear(); + + foreach (GeometrySurface surface in geometryData.Surfaces) + { + GeometryBounds bounds = surface.GetGeometryBounds(); + double z = (bounds.Top + bounds.Bottom) * 0.5; + + LayerData layerData = layers.FirstOrDefault(l => l.IsZLocatedInLayer(z)); + if (layerData != null) + { + Surfaces.Add(new SoilLayer2D + { + GeometrySurface = surface, + IsAquifer = layerData.IsAquifer, + WaterpressureInterpolationModel = layerData.WaterpressureInterpolationModel, + Soil = layerData.Soil + }); + } + } + } + + /// /// Gets the collection of to convert based on the input arguments. /// /// The to retrieve the layers for. @@ -180,6 +250,59 @@ copiedLayer.WaterpressureInterpolationModel = originalLayer.WaterpressureInterpolationModel; } + private static bool IsLayerBelowSurfaceLine(SoilLayer1D soilLayer, SurfaceLine2 surfaceLine) + { + return surfaceLine.Geometry.GetMinZ() > soilLayer.TopLevel; + } + + private static bool IsLayerAboveSurfaceLine(SoilLayer1D soilLayer, SurfaceLine2 surfaceLine2) + { + return soilLayer.BottomLevel > surfaceLine2.Geometry.GetMaxZ(); + } + + /// + /// Gets the X coordinates to determine the coordinates for through each layer. + /// + /// The collection of . + /// The . + /// A collection of unique x coordinates, in an ascending order. + /// This function is necessary, because the algorithm in recognizing + /// surfaces requires that curves are overlapping. Curves cannot be a subset (e.g, there is one + /// curve definition that span two other curves, because the algorithm will not + /// be able to determine a surface from it. + private static IEnumerable GetXCoordinates(IEnumerable soilLayers, SurfaceLine2 surfaceLine) + { + var xCoordinates = new List(surfaceLine.Geometry.CalcPoints.Select(p => p.X)); + + foreach (SoilLayer1D layer in soilLayers) + { + xCoordinates.AddRange(GetUniqueXCoordinatesWithIntersections(surfaceLine, layer.TopLevel, layer.BottomLevel)); + } + + return xCoordinates.OrderBy(x => x).Distinct(); + } + + private static IEnumerable GetUniqueXCoordinatesWithIntersections(SurfaceLine2 surfaceLine, double layerTopLevel, double layerBottomLevel) + { + GeometryPointString surfaceLineGeometry = surfaceLine.Geometry; + double minXCoordinate = surfaceLineGeometry.GetMinX(); + double maxXCoordinate = surfaceLineGeometry.GetMaxX(); + + // Create lines to determine intersections + var topLeft = new Point2D(minXCoordinate, layerTopLevel); + var topRight = new Point2D(maxXCoordinate, layerTopLevel); + var topLine = new Line(topLeft, topRight); + + var bottomLeft = new Point2D(minXCoordinate, layerBottomLevel); + var bottomRight = new Point2D(maxXCoordinate, layerBottomLevel); + var bottomLine = new Line(bottomLeft, bottomRight); + + var xCoordinates = surfaceLineGeometry.IntersectionPointsXzWithLineXz(topLine).Select(p => p.X).ToList(); + xCoordinates.AddRange(surfaceLineGeometry.IntersectionPointsXzWithLineXz(bottomLine).Select(p => p.X)); + + return xCoordinates.Distinct(); + } + private static IEnumerable CreateLayerData(IEnumerable soilLayers, SurfaceLine2 surfaceLine, IEnumerable xCoordinates) { @@ -199,16 +322,6 @@ return layerData; } - private static bool IsLayerBelowSurfaceLine(SoilLayer1D soilLayer, SurfaceLine2 surfaceLine) - { - return surfaceLine.Geometry.GetMinZ() > soilLayer.TopLevel; - } - - private static bool IsLayerAboveSurfaceLine(SoilLayer1D soilLayer, SurfaceLine2 surfaceLine2) - { - return soilLayer.BottomLevel > surfaceLine2.Geometry.GetMaxZ(); - } - private static LayerData CreateSurfaceLineWideSoilLayer(SoilLayer1D soilLayer, IEnumerable xCoordinates) { // A single square definition does not suffice for the area definition. The @@ -286,7 +399,6 @@ { currentArea.AddCoordinate(new Point2D(xCoordinate, currentZCoordinate)); } - } previousZCoordinate = currentZCoordinate; @@ -438,118 +550,5 @@ coordinates.Add(coordinate); } } - - /// - /// Updates the layers. - /// - private void Create2DGeometryBasedOn1DProfileAndSurfaceLine() - { - var filteredSoilLayers = FilterSoilLayersToConvert(originalSoilProfile1D, surfaceLine2); - - var xCoordinatesToTraverse = GetXCoordinates(filteredSoilLayers, surfaceLine2).ToArray(); - var layerData = CreateLayerData(filteredSoilLayers, surfaceLine2, xCoordinatesToTraverse); - - BuildGeometryModel(Geometry, layerData, originalSoilProfile1D, surfaceLine2); - BuildSoilLayer2D(Surfaces, layerData, Geometry); - } - - - /// - /// Gets the X coordinates to determine the coordinates for through each layer. - /// - /// The collection of . - /// The . - /// A collection of unique x coordinates, in an ascending order. - /// This function is necessary, because the algorithm in recognizing - /// surfaces requires that curves are overlapping. Curves cannot be a subset (e.g, there is one - /// curve definition that span two other curves, because the algorithm will not - /// be able to determine a surface from it. - private static IEnumerable GetXCoordinates(IEnumerable soilLayers, SurfaceLine2 surfaceLine) - { - var xCoordinates = new List(surfaceLine.Geometry.CalcPoints.Select(p => p.X)); - - foreach (SoilLayer1D layer in soilLayers) - { - xCoordinates.AddRange(GetUniqueXCoordinatesWithIntersections(surfaceLine, layer.TopLevel, layer.BottomLevel)); - } - - return xCoordinates.OrderBy(x => x).Distinct(); - } - - private static IEnumerable GetUniqueXCoordinatesWithIntersections(SurfaceLine2 surfaceLine, double layerTopLevel, double layerBottomLevel) - { - GeometryPointString surfaceLineGeometry = surfaceLine.Geometry; - double minXCoordinate = surfaceLineGeometry.GetMinX(); - double maxXCoordinate = surfaceLineGeometry.GetMaxX(); - - // Create lines to determine intersections - var topLeft = new Point2D(minXCoordinate, layerTopLevel); - var topRight = new Point2D(maxXCoordinate, layerTopLevel); - var topLine = new Line(topLeft, topRight); - - var bottomLeft = new Point2D(minXCoordinate, layerBottomLevel); - var bottomRight = new Point2D(maxXCoordinate, layerBottomLevel); - var bottomLine = new Line(bottomLeft, bottomRight); - - var xCoordinates = surfaceLineGeometry.IntersectionPointsXzWithLineXz(topLine).Select(p => p.X).ToList(); - xCoordinates.AddRange(surfaceLineGeometry.IntersectionPointsXzWithLineXz(bottomLine).Select(p => p.X)); - - return xCoordinates.OrderBy(x => x).Distinct(); - } - - private void BuildGeometryModel(GeometryData geometryData, - IEnumerable layers, - SoilProfile1D profile, - SurfaceLine2 surfaceLine) - { - if (surfaceLine.Geometry == null - || profile == null - || profile.Layers.Count == 0 - || surfaceLine.Geometry.GetMaxZ() < profile.BottomLevel - || surfaceLine.Geometry.Points.Count < 2) - { - return; - } - - GeometryBounds bounds = surfaceLine.Geometry.GetGeometryBounds(); - double minX = bounds.Left; - double maxX = bounds.Right; - - geometryData.Clear(); - geometryData.Left = minX; - geometryData.Right = maxX; - geometryData.Bottom = Math.Min(profile.BottomLevel, surfaceLine2.Geometry.GetMinZ() - 1); - - var pointsToBeAdded = layers.SelectMany(l => l.Points); - var curvesToBeAdded = layers.SelectMany(l => l.Curves); - geometryData.NewlyEffectedPoints.AddRange(pointsToBeAdded); - geometryData.NewlyEffectedCurves.AddRange(curvesToBeAdded); - geometryData.RegenerateGeometry(); - } - - private void BuildSoilLayer2D(ICollection soilLayer2Ds, - IEnumerable layers, - GeometryData geometryData) - { - soilLayer2Ds.Clear(); - - foreach (GeometrySurface surface in geometryData.Surfaces) - { - GeometryBounds bounds = surface.GetGeometryBounds(); - double z = (bounds.Top + bounds.Bottom) * 0.5; - - LayerData layerData = layers.FirstOrDefault(l => l.IsZLocatedInLayer(z)); - if (layerData != null) - { - Surfaces.Add(new SoilLayer2D - { - GeometrySurface = surface, - IsAquifer = layerData.IsAquifer, - WaterpressureInterpolationModel = layerData.WaterpressureInterpolationModel, - Soil = layerData.Soil - }); - } - } - } } } \ No newline at end of file