Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/CharacteristicPointSet.cs =================================================================== diff -u -r3893 -r4000 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/CharacteristicPointSet.cs (.../CharacteristicPointSet.cs) (revision 3893) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/CharacteristicPointSet.cs (.../CharacteristicPointSet.cs) (revision 4000) @@ -34,7 +34,6 @@ public class CharacteristicPointSet : IList, IList { private readonly List annotations; - private readonly object syncRoot = new object(); private readonly Dictionary typeCache; private GeometryPointString geometry; private bool geometryMustContainPoint; @@ -117,6 +116,7 @@ { Geometry.SortPointsByXAscending(); } + annotations.Sort(); } @@ -134,20 +134,110 @@ UpdateTypeCache(annotations[index]); } - #region Implementation: IList, IList - /// - /// Gets an object that can be used to synchronize access to the . + /// Snaps the characteristic point height to if it's not part + /// of it, or set it to in case no + /// is available. /// - public object SyncRoot + /// The characteristic point whose height is to be updated. + private void UpdateCharacteristicPointHeight(CharacteristicPoint characteristicPoint) { - get + if (geometry == null) { - return syncRoot; + characteristicPoint.Z = double.NaN; } + else if (!geometry.Points.Contains(characteristicPoint.GeometryPoint)) + { + if (double.IsNaN(characteristicPoint.X)) + { + characteristicPoint.Z = double.NaN; + } + else + { + // Note: Cannot use GeometryPointString.GetZAtX due to its requirement + // that Geometry.Points is sorted on X. + characteristicPoint.Z = geometry.GetZAtUnsortedX(characteristicPoint.X); + } + } + // Else: Keep Z the same as in Geometry } + private void FullSyncWithGeometry() + { + if (GeometryMustContainPoint) + { + // Resync with geometry; Do not keep previous data: + ClearCharacteristicPointSet(); + + if (geometry == null) + { + return; + } + + foreach (GeometryPoint geometryPoint in geometry.Points) + { + Add(new CharacteristicPoint + { + GeometryPoint = geometryPoint, + CharacteristicPointType = CharacteristicPointType.None + }); + } + } + else + { + // Remove all characteristic points whose GeometryPoint are part of Geometry + // as per required by the value of GeometryMustContainPoint. All other + // characteristic points should have their height updated: + foreach (CharacteristicPoint characteristicPoint in annotations.ToArray()) + { + if (geometry != null && geometry.Points.Contains(characteristicPoint.GeometryPoint)) + { + Remove(characteristicPoint); + } + else + { + UpdateCharacteristicPointHeight(characteristicPoint); + } + } + } + } + + private void ClearCharacteristicPointSet() + { + ClearAnnotations(); + typeCache.Clear(); + } + + private void ClearAnnotations() + { + annotations.Clear(); + } + + private void UpdateTypeCache(CharacteristicPoint item) + { + if (item.CharacteristicPointType != CharacteristicPointType.None) + { + // Prevent duplication: + CharacteristicPoint alreadyDefined = annotations.FirstOrDefault(cp => cp.CharacteristicPointType == item.CharacteristicPointType && + !ReferenceEquals(cp.GeometryPoint, item.GeometryPoint)); + if (alreadyDefined != null) + { + alreadyDefined.CharacteristicPointType = CharacteristicPointType.None; + } + + // Set new annotation definition: + typeCache[item.CharacteristicPointType] = item.GeometryPoint; + } + } + + #region Implementation: IList, IList + /// + /// Gets an object that can be used to synchronize access to the . + /// + public object SyncRoot { get; } = new object(); + + /// /// Gets a value indicating whether access to the is synchronized (thread safe). /// public bool IsSynchronized @@ -307,22 +397,22 @@ /// public bool Remove(CharacteristicPoint item) { - var removed = PerformCollectionRemoveWithEvents(annotations, item); + bool removed = PerformCollectionRemoveWithEvents(annotations, item); if (removed) { typeCache.Remove(item.CharacteristicPointType); - var removeGeometryPoint = GeometryMustContainPoint && Geometry != null && - Geometry.Points.Contains(item.GeometryPoint) && - !annotations.Any(cp => ReferenceEquals(cp.GeometryPoint, item.GeometryPoint)); + bool removeGeometryPoint = GeometryMustContainPoint && Geometry != null && + Geometry.Points.Contains(item.GeometryPoint) && + !annotations.Any(cp => ReferenceEquals(cp.GeometryPoint, item.GeometryPoint)); if (removeGeometryPoint) { - PerformCollectionRemoveWithEvents(Geometry.Points, item.GeometryPoint); + PerformCollectionRemoveWithEvents(Geometry.Points, item.GeometryPoint); } } - + return removed; } @@ -394,14 +484,15 @@ { item.PointSet = this; } - var itemAtIndex = index < annotations.Count ? annotations[index].GeometryPoint : null; + + GeometryPoint itemAtIndex = index < annotations.Count ? annotations[index].GeometryPoint : null; PerformListInsertWithEvents(annotations, item, index); if (GeometryMustContainPoint && Geometry != null && !Geometry.Points.Contains(item.GeometryPoint)) { - var geometryIndex = Geometry.Points.Count; + int geometryIndex = Geometry.Points.Count; if (null != itemAtIndex) { - for (int i = 0; i < Geometry.Points.Count; i++) + for (var i = 0; i < Geometry.Points.Count; i++) { if (ReferenceEquals(Geometry.Points[i], itemAtIndex)) { @@ -410,10 +501,11 @@ } } } + // Check if point at same position already exists and set that point to the existing point // Do this to avoid points in Surfaceline.Geometry with the same location - bool IsPointExist = false; - for (int i = 0; i < Geometry.Points.Count; i++) + var IsPointExist = false; + for (var i = 0; i < Geometry.Points.Count; i++) { if (Geometry.Points[i].LocationEquals(item.GeometryPoint)) { @@ -422,6 +514,7 @@ break; } } + if (!IsPointExist) { // Only add new point if no point on same location was found @@ -433,7 +526,8 @@ { UpdateCharacteristicPointHeight(item); } - UpdateTypeCache(item); + + UpdateTypeCache(item); } /// @@ -479,112 +573,16 @@ /// Index where the item is inserted. private static void PerformListInsertWithEvents(IList list, T item, int index) { - list.Insert(index, item); + list.Insert(index, item); } private static bool PerformCollectionRemoveWithEvents(ICollection list, T item) { - var removed = list.Remove(item); + bool removed = list.Remove(item); return removed; } #endregion - - /// - /// Snaps the characteristic point height to if it's not part - /// of it, or set it to in case no - /// is available. - /// - /// The characteristic point whose height is to be updated. - private void UpdateCharacteristicPointHeight(CharacteristicPoint characteristicPoint) - { - if (geometry == null) - { - characteristicPoint.Z = double.NaN; - } - else if (!geometry.Points.Contains(characteristicPoint.GeometryPoint)) - { - if (double.IsNaN(characteristicPoint.X)) - { - characteristicPoint.Z = double.NaN; - } - else - { - // Note: Cannot use GeometryPointString.GetZAtX due to its requirement - // that Geometry.Points is sorted on X. - characteristicPoint.Z = geometry.GetZAtUnsortedX(characteristicPoint.X); - } - } - // Else: Keep Z the same as in Geometry - } - - private void FullSyncWithGeometry() - { - if (GeometryMustContainPoint) - { - // Resync with geometry; Do not keep previous data: - ClearCharacteristicPointSet(); - - if (geometry == null) - { - return; - } - - foreach (var geometryPoint in geometry.Points) - { - Add(new CharacteristicPoint - { - GeometryPoint = geometryPoint, - CharacteristicPointType = CharacteristicPointType.None - }); - } - } - else - { - // Remove all characteristic points whose GeometryPoint are part of Geometry - // as per required by the value of GeometryMustContainPoint. All other - // characteristic points should have their height updated: - foreach (var characteristicPoint in annotations.ToArray()) - { - if (geometry != null && geometry.Points.Contains(characteristicPoint.GeometryPoint)) - { - Remove(characteristicPoint); - } - else - { - UpdateCharacteristicPointHeight(characteristicPoint); - } - } - } - } - - private void ClearCharacteristicPointSet() - { - ClearAnnotations(); - typeCache.Clear(); - } - - private void ClearAnnotations() - { - annotations.Clear(); - } - - private void UpdateTypeCache(CharacteristicPoint item) - { - if (item.CharacteristicPointType != CharacteristicPointType.None) - { - // Prevent duplication: - var alreadyDefined = annotations.FirstOrDefault(cp => cp.CharacteristicPointType == item.CharacteristicPointType && - !ReferenceEquals(cp.GeometryPoint, item.GeometryPoint)); - if (alreadyDefined != null) - { - alreadyDefined.CharacteristicPointType = CharacteristicPointType.None; - } - - // Set new annotation definition: - typeCache[item.CharacteristicPointType] = item.GeometryPoint; - } - } } } \ No newline at end of file