Index: dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2.cs =================================================================== diff -u -r282 -r303 --- dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2.cs (.../SurfaceLine2.cs) (revision 282) +++ dam engine/branches/Initial Source/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2.cs (.../SurfaceLine2.cs) (revision 303) @@ -1,8 +1,8 @@ // Copyright (C) Stichting Deltares 2017. All rights reserved. // -// This file is part of the Macro Stability kernel. +// This file is part of the DAM Engine. // -// The Macro Stability kernel is free software: you can redistribute it and/or modify +// The DAM Engine is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. @@ -184,6 +184,139 @@ return CharacteristicPoints.Geometry.GetGeometryBounds(); } return null; - } + } + + /// + /// Copy all characteristic point related data from another . + /// + /// Data source + public void Assign(SurfaceLine2 source) + { + SetValuesFromOtherSurfaceLine(source); + } + + /// + /// Sets the values from another surface line. + /// + /// The source. + /// If set to true, the of + /// will be deep cloned, otherwise the reference is shared. + private void SetValuesFromOtherSurfaceLine(SurfaceLine2 source, bool cloneGeometry = false) + { + CharacteristicPoints.Clear(); // clears the whole characteristic points state. + + Name = source.Name; + Geometry.Name = Name; + LandwardDirection = source.LandwardDirection; + + CharacteristicPoints.GeometryMustContainPoint = source.CharacteristicPoints.GeometryMustContainPoint; + Geometry = cloneGeometry ? source.Geometry.Clone() : source.Geometry; + + var geometryAnnotations = GetCharacteristicAnnotationsInSource(source, cloneGeometry); + + // Reconstruct annotation state from dictionary: + if (CharacteristicPoints.GeometryMustContainPoint) + { + foreach (var annotation in geometryAnnotations) + { + for (int i = 0; i < annotation.Value.Length; i++) + { + var index = -1; + for (int j = 0; j < CharacteristicPoints.Count; j++) + { + if (ReferenceEquals(CharacteristicPoints[j].GeometryPoint, annotation.Key)) + { + index = j; + break; + } + } + + if (i == 0) + { + // Reassign annotation of already created CharacteristicPoint: + CharacteristicPoints.Annotate(index, annotation.Value[i]); + } + else + { + // Add new CharacteristicPoint instance for all subsequent annotations and ensuring to keep the defined order: + CharacteristicPoints.Insert(index + i, new CharacteristicPoint(CharacteristicPoints, annotation.Key) + { + CharacteristicPointType = annotation.Value[i] + }); + } + } + } + } + else + { + foreach (var annotation in geometryAnnotations) + { + AddCharacteristicPoint((GeometryPoint)annotation.Key.Clone(), annotation.Value); + } + } + } + + /// + /// Collapses all characteristic point annotations in the given surfaceline into + /// a dictionary keyed on instances in that surfaceline + /// and their annotations. + /// + /// The referenced surfaceline. + /// True if should be a clone from + /// .; false if it should + /// take the same instance instead. + /// Dictionary keyed on instances in the surfaceline + /// that have annotations. + private Dictionary GetCharacteristicAnnotationsInSource(SurfaceLine2 source, bool cloneGeometry) + { + return CharacteristicPoints.GeometryMustContainPoint + ? GetCharacteristicAnnotationsInSource_GeometryMustContainPoints(source, cloneGeometry) + : GetCharacteristicAnnotationsInSource_GeometryMustNotContainPoints(source); + } + + /// + /// Handlers return value in case + /// is true. + /// + /// The referenced surfaceline. + /// True if should be a clone from + /// .; false if it should + /// take the same instance instead. + /// Dictionary keyed on instances in the surfaceline + /// that have annotations. + private Dictionary GetCharacteristicAnnotationsInSource_GeometryMustContainPoints(SurfaceLine2 source, bool cloneGeometry) + { + var geometryAnnotations = new Dictionary(); + for (int i = 0; i < source.Geometry.Count; i++) + { + var annotationsForPoint = source.GetCharacteristicPoints(source.Geometry.Points[i]).Where(cpt => cpt != CharacteristicPointType.None).ToArray(); + if (annotationsForPoint.Length > 0) + { + geometryAnnotations[Geometry.Points[i]] = annotationsForPoint; + } + } + return geometryAnnotations; + } + + /// + /// Handles return value in case + /// is false. + /// + /// The referenced surfaceline. + /// Dictionary keyed on instances in the surfaceline + /// that have annotations. + private static Dictionary GetCharacteristicAnnotationsInSource_GeometryMustNotContainPoints(SurfaceLine2 source) + { + var geometryAnnotations = new Dictionary(); + foreach (var characteristicPoint in source.CharacteristicPoints) + { + if (!geometryAnnotations.ContainsKey(characteristicPoint.GeometryPoint)) + { + geometryAnnotations[characteristicPoint.GeometryPoint] = + source.GetCharacteristicPoints(characteristicPoint.GeometryPoint).ToArray(); + } + } + return geometryAnnotations; + } } } \ No newline at end of file