using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Linq; using System.Windows.Forms; using System.Xml.Serialization; using Deltares.DSoilModel.Data; using Deltares.DSoilModel.Forms.Properties; using Deltares.Geometry; using Deltares.Geotechnics; using Deltares.Geotechnics.ConePenetrationTest; using Deltares.Geotechnics.Forms; using Deltares.Geotechnics.GeotechnicalGeometry; using Deltares.Geotechnics.IO; using Deltares.Standard; using Deltares.Standard.Attributes; using Deltares.Standard.EventPublisher; using Deltares.Standard.Forms; using Deltares.Standard.Forms.DExpress; using Deltares.Standard.Language; using Deltares.Standard.Reflection; namespace Deltares.DSoilModel.Forms { /// /// The D-Soil Model Geometry Editor /// public class DSoilModelGeometryEditor : IVisibleEnabled, IDisposable { private readonly List boringLookup1Ds = new List(); private readonly List boringLookup2Ds = new List(); private readonly List cptLookup1Ds = new List(); private readonly List cptLookup2Ds = new List(); private readonly GeometryEditor geometryEditor; private readonly MainForm mainForm; private readonly Panel panel = new Panel(); private readonly List soilprofile1DLookup2Ds = new List(); private readonly SpatialEditor spatialEditor; private readonly List specificMechanismPointLocations = new List(); private CenterCrestLocation localCenterCrestLocation; private bool allowEdit = true; private DSoilModelProject project; private GeometryData selectedGeom; private bool updateForCenterCrestLocation; /// /// Initializes a new instance of the class. /// /// The main form to be able to set the caption of the geometry dock panel. public DSoilModelGeometryEditor(MainForm theMainForm) { mainForm = theMainForm; geometryEditor = theMainForm.GeometryEditor; spatialEditor = geometryEditor.SpatialEditor; // maybe this can move to the Geotechnics plugin later spatialEditor.RegisterShapeType(typeof(ConePenetrationTestData), typeof(DrawingCPT)); spatialEditor.RegisterShapeType(typeof(ConePenetrationTestLookup1D), typeof(DrawingCPT)); spatialEditor.RegisterShapeType(typeof(ConePenetrationTestLookup2D), typeof(DrawingCPT)); //spatialEditor.RegisterShapeType(typeof (Boring), typeof (DrawingBoring)); spatialEditor.RegisterShapeType(typeof(BoringLookup1D), typeof(DrawingBoring)); spatialEditor.RegisterShapeType(typeof(BoringLookup2D), typeof(DrawingBoring)); spatialEditor.RegisterShapeType(typeof(SoilProfile1DLookup2D), typeof(DrawingSoilProfile1D)); spatialEditor.RegisterShapeType(typeof(SpecificMechanismPointLocation), typeof(DrawingSpecificMechanismPointLocation)); spatialEditor.RegisterShapeType(typeof(CenterCrestLocation), typeof(DrawingCenterCrestLocation)); //Next was commented out in Geotechnics plugin because RingToets doesn't need it anymore spatialEditor.RegisterShapeType(typeof(SurfaceLine2), typeof(DrawingSurfaceLine2)); //Next can not be moved to Geotechnics spatialEditor.RegisterShapeType(typeof(SosSoilLayer1D), typeof(DrawingSosSoilLayer1D)); spatialEditor.RegisterShapeType(typeof(BoringLayer), typeof(DrawingBoringLayer)); spatialEditor.MarginBottom = 55; spatialEditor.ShapeRemoved += spatialEditor_ShapeRemoved; DataEventPublisher.OnSelectionChanged += DataEventPublisherOnSelectionChanged; DataEventPublisher.OnAfterChange += DataEventPublisherOnOnAfterChange; DataEventPublisher.OnDataListModified += DataEventPublisher_OnDataListModified; AddUiItems(); } /// /// Gets or sets the project. /// public DSoilModelProject Project { get { return project; } set { if (value != project) { spatialEditor.Clear(); } project = value; } } /// /// Gets or sets a call back method to call when a cpt is added to the geometry editor. /// [XmlIgnore] [Browsable(false)] public Func AddCPTCallback { get; set; } /// /// Creates a Polyline. /// /// /// true if polyline is created; otherwise, false. /// [Label("Create polyline")] public bool CreatePolyline { get { return geometryEditor.SpatialEditor.InsertType != null && geometryEditor.SpatialEditor.InsertType.Equals(BasicGeometryType.GeometryCurve); } set { if (value) { geometryEditor.SpatialEditor.InsertMode = ShapeInsertMode.PolyLine; geometryEditor.SpatialEditor.InsertRepeatMode = ShapeInsertRepeatMode.Connect; geometryEditor.SpatialEditor.InsertIncrease = false; geometryEditor.SpatialEditor.InsertType = BasicGeometryType.GeometryCurve; geometryEditor.SetInsertMode(false); geometryEditor.InsertShapeMethod = selectedGeom.CreateGeometryObject; geometryEditor.StatusString = LocalizationManager.GetTranslatedText(this, "AddGeometryPolylines"); } } } /// /// Creates a point in the line. /// /// /// true if create point in line; otherwise, false. /// [Label("Create point in line")] public bool CreatePointInLine { get { return geometryEditor.SpatialEditor.InsertType != null && geometryEditor.SpatialEditor.InsertType.Equals(BasicGeometryType.GeometryPoint); } set { if (value) { geometryEditor.SpatialEditor.InsertMode = ShapeInsertMode.Point; geometryEditor.SpatialEditor.InsertRepeatMode = ShapeInsertRepeatMode.Repeat; geometryEditor.SpatialEditor.InsertIncrease = false; geometryEditor.SpatialEditor.InsertType = BasicGeometryType.GeometryPoint; geometryEditor.SetInsertMode(false); geometryEditor.InsertShapeMethod = selectedGeom.CreateGeometryObject; geometryEditor.StatusString = LocalizationManager.GetTranslatedText(this, "AddGeometryPointInCurve"); } } } /// /// Gets or sets the is visible callback. /// /// /// The is visible callback. /// [XmlIgnore] [Browsable(false)] public Func IsVisibleCallback { get; set; } public bool AllowEdit { get { return allowEdit; } set { allowEdit = value; } } /// /// Allow the plugin to show the currently selected soil segment which possibly has a stochastic soil /// model. This stochastic soil model can have a possibly currently selected stochastic soil profile. /// If the currently selected stochastic soil profile is undefined, the first profile is selected. /// /// The segment to show, possibly with a stochastic soil model. /// The possible selected soil segment to show. public void ShowSoilSegment(SoilSegment selectedSegment, StochasticSoilProfile selectedSoilProfile) { if (selectedSegment == null) { return; } if (selectedSoilProfile == null) { SetCaption(string.Format(LocalizationManager.GetTranslatedText(this, "ShowSegment"), selectedSegment.Name)); Clear(); return; } // Draw the Stochastic Soil Profile and set the appropriate caption var profile1D = selectedSoilProfile.Profile as SoilProfile1D; if (profile1D != null) { ShowSoilProfile1D(profile1D, null); SetCaption(string.Format(LocalizationManager.GetTranslatedText(this, "ShowSoilProfile1D"), selectedSoilProfile)); } else { var profile2D = selectedSoilProfile.Profile as SoilProfile2D; if (profile2D != null) { ShowSoilProfile2D(profile2D); SetCaption(string.Format(LocalizationManager.GetTranslatedText(this, "ShowSoilProfile2D"), selectedSoilProfile)); } } } /// /// Inserts mechanism point location. /// [Label("Insert mechanism location")] public void InsertSpecificMechanismPointLocation() { if (project != null) { AddSpecificMechanismPointLocation(); } } /// /// Adds the center crest location to 2d profile. /// public void AddCenterCrestLocationTo2DProfile() { if (project != null) { updateForCenterCrestLocation = true; AddCenterCrestLocation(); } } /// /// Adds the surface line to the existing 2D to create new 2D profile. /// public void AddSurfaceLineToCreateNew2DProfile() { var currentProfile2D = (spatialEditor.EmptySelection.DataObject as SoilProfile2D); // Create a 2D profile from current 2D and selected surfaceline if (project != null) { string item = HandleModalListSelection(project.SurfaceLines.Where(p => p.HasDike()).OrderBy(p => p.Name).Select(p => p.Name).ToList(), "SelectSurfaceLine"); if (item != null) { SurfaceLine2 surfaceLine2 = project.SurfaceLines.First(p => p.Name == item); CreateNew2DProfileFromSoilProfile2DAndSurfaceLine2(currentProfile2D, surfaceLine2); } } } public void Dispose() { spatialEditor.ShapeRemoved -= spatialEditor_ShapeRemoved; DataEventPublisher.OnDataListModified -= DataEventPublisher_OnDataListModified; DataEventPublisher.OnAfterChange -= DataEventPublisherOnOnAfterChange; DataEventPublisher.OnSelectionChanged -= DataEventPublisherOnSelectionChanged; } public bool IsVisible(string property) { if (IsVisibleCallback != null) { return IsVisibleCallback(property); } bool dataObjectEmptySelectionIsSoilProfile = spatialEditor.EmptySelection != null && spatialEditor.EmptySelection.DataObject is SoilProfile; bool dataObjectEmptySelectionIsSoilProfile2D = spatialEditor.EmptySelection != null && spatialEditor.EmptySelection.DataObject is SoilProfile2D; bool dataObjectEmptySelectionIsFilledSoilProfile1D = spatialEditor.EmptySelection != null && spatialEditor.EmptySelection.DataObject is SoilProfile1D && (spatialEditor.EmptySelection.DataObject as SoilProfile1D).LayerCount > 0; bool dataObjectEmptySelectionIsFilledSurfaceLine2 = spatialEditor.EmptySelection != null && spatialEditor.EmptySelection.DataObject is SurfaceLine2 && (spatialEditor.EmptySelection.DataObject as SurfaceLine2).CharacteristicPoints.Count > 1; bool projectHasSurfaceLinesWithDikes = project != null && project.SurfaceLines != null && project.SurfaceLines.Count > 0 && project.SurfaceLines.Count(p => p.HasDike()) > 0; bool isCenterCrestDefined = dataObjectEmptySelectionIsSoilProfile2D && !double.IsNaN(((SoilProfile2D) spatialEditor.EmptySelection.DataObject).CenterCrestLocation); switch (property) { case "CreatePointInLine": case "CreatePolyline": return allowEdit && selectedGeom != null; case "InsertCpt": return dataObjectEmptySelectionIsSoilProfile && project.CPTs.Count > 0; case "InsertBoring": return dataObjectEmptySelectionIsSoilProfile && project.Borings.Count > 0; case "InsertSoilProfile1D": return dataObjectEmptySelectionIsSoilProfile2D && project.SoilProfiles1D.Count > 0; case "InsertSpecificMechanismPointLocation": return dataObjectEmptySelectionIsSoilProfile2D; case "AddCenterCrestLocationTo2DProfile": return dataObjectEmptySelectionIsSoilProfile2D && !isCenterCrestDefined; case "AddSurfaceLineToCreateNew2DProfile": return dataObjectEmptySelectionIsSoilProfile2D && projectHasSurfaceLinesWithDikes && isCenterCrestDefined; case "AddSurfaceLineToCreate2DProfile": return dataObjectEmptySelectionIsFilledSoilProfile1D && project.SurfaceLines.Count > 0; case "Add1DProfileToCreate2DProfile": return dataObjectEmptySelectionIsFilledSurfaceLine2 && project.SoilProfiles1D.Count > 0; default: return true; } } public bool IsEnabled(string property) { return true; } /// /// Select and inserts a CPT. /// [Label("Insert CPT")] private void InsertCpt() { if (project != null) { string item = HandleModalListSelection(project.CPTs.OrderBy(p => p.Name).Select(p => p.Name).ToList(), "SelectCPT"); if (item != null) { ConePenetrationTestData conePenetrationTestData = project.CPTs.First(p => p.Name == item); AddCPT(conePenetrationTestData); } } } /// /// Select and insert a boring. /// [Label("Insert Boring")] private void InsertBoring() { if (project != null) { string item = HandleModalListSelection(project.Borings.OrderBy(p => p.Name).Select(p => p.Name).ToList(), "SelectBoring"); if (item != null) { Boring boring = project.Borings.First(p => p.Name == item); AddBoring(boring); } } } /// /// Select and insert a SoilProfile1D. /// [Label("Insert 1D Soil profile")] private void InsertSoilProfile1D() { if (project != null) { string item = HandleModalListSelection(project.SoilProfiles1D.OrderBy(p => p.Name).Select(p => p.Name).ToList(), "SelectProfile1D"); if (item != null) { SoilProfile1D profile1D = project.SoilProfiles1D.First(p => p.Name == item); AddSoilProfile1D(profile1D); } } } private void DataEventPublisherOnSelectionChanged(object sender, PublishEventArgs e) { selectedGeom = null; object selectedObj = (spatialEditor.EmptySelection == null) ? null : spatialEditor.EmptySelection.DataObject; if (sender is SoilProfile1D) { ShowSoilProfile1D(sender, selectedObj); } else if (sender is SoilProfile2D) { ShowSoilProfile2D(sender); } else if (sender is SpecificMechanismPointLocation) { ShowSoilProfile2D(((SpecificMechanismPointLocation)sender).SoilProfile2D); } else if (sender is CenterCrestLocation) { ShowSoilProfile2D(((CenterCrestLocation)sender).SoilProfile2D); } else if (sender is ConePenetrationTestData) { ShowCpt(sender, selectedObj); } else if (sender is Boring) { ShowBoring(sender, selectedObj); } else if (sender is SurfaceLine2) { ShowSurfaceLine(sender, selectedObj); } else { return; } DataEventPublisher.AfterChange(this); } private void DataEventPublisherOnOnAfterChange(object sender, PublishEventArgs publishEventArgs) { if (sender is CenterCrestLocation) { var ccl = sender as CenterCrestLocation; ccl.SoilProfile2D.CenterCrestLocation = ccl.Location; } if (ReferenceEquals(sender, spatialEditor) && publishEventArgs.Property == spatialEditor.GetMemberName(x => x.InsertType)) { DataEventPublisher.AfterChange(this); } } private void DataEventPublisher_OnDataListModified(object sender, PublishEventArgs e) { if (sender == RealTimeBackgroundValidator.ValidationResults) { foreach (var shape in spatialEditor.Shapes.Where(x => x is DrawingSpecificMechanismPointLocation).ToList()) { spatialEditor.Remove(shape); spatialEditor.AddShape(shape); } } else if (project != null && sender == project.SoilProfiles2D) { if (spatialEditor.EmptySelection != null) { var currentSoilProfile = spatialEditor.EmptySelection.DataObject as SoilProfile2D; if (currentSoilProfile != null) { // check whether the current displayed object has been removed bool removed = !project.SoilProfiles2D.Contains(currentSoilProfile); if (removed) { spatialEditor.Clear(); spatialEditor.Refresh(); } } } } } private void AddUiItems() { // Add buttons to be able to manipulate the geometry of SoilProfiles2D, insert CPT's and Borings and Piping Location BindSupport.Bind(panel, geometryEditor.CreateButton(Resources.CreatePolyline), typeof(DSoilModelGeometryEditor), "CreatePolyline"); BindSupport.Bind(panel, geometryEditor.CreateButton(Resources.CreatePointInLine), typeof(DSoilModelGeometryEditor), "CreatePointInLine"); // Add popup context menu for adding items to a 2D Soilprofile view var insertCptMenuItem = new ToolStripMenuItem("Insert CPT"); var insertBoringMenuItem = new ToolStripMenuItem("Insert Boring"); var insertSoilProfile1DMenuItem = new ToolStripMenuItem("Insert 1D soil profile"); var insertSpecificMechanismPointLocationMenuItem = new ToolStripMenuItem("Insert mechanism location"); var addCenterCrestLocationTo2DProfileMenuItem = new ToolStripMenuItem("Add center of crest"); var addSurfaceLineToCreateNew2DProfileMenuItem = new ToolStripMenuItem("Add surfaceLine to create new 2D profile"); var addSurfaceLineToCreate2DProfileMenuItem = new ToolStripMenuItem("Add surfaceLine to create 2D profile"); var add1DProfileToCreate2DProfileMenuItem = new ToolStripMenuItem("Add 1D profile to create 2D profile"); spatialEditor.ContextMenuStrip.Items.Add(insertCptMenuItem); spatialEditor.ContextMenuStrip.Items.Add(insertBoringMenuItem); spatialEditor.ContextMenuStrip.Items.Add(insertSoilProfile1DMenuItem); spatialEditor.ContextMenuStrip.Items.Add(insertSpecificMechanismPointLocationMenuItem); spatialEditor.ContextMenuStrip.Items.Add(addCenterCrestLocationTo2DProfileMenuItem); spatialEditor.ContextMenuStrip.Items.Add(addSurfaceLineToCreateNew2DProfileMenuItem); spatialEditor.ContextMenuStrip.Items.Add(addSurfaceLineToCreate2DProfileMenuItem); spatialEditor.ContextMenuStrip.Items.Add(add1DProfileToCreate2DProfileMenuItem); BindSupport.Bind(panel, insertCptMenuItem, ge => ge.InsertCpt()); BindSupport.Bind(panel, insertBoringMenuItem, ge => ge.InsertBoring()); BindSupport.Bind(panel, insertSoilProfile1DMenuItem, ge => ge.InsertSoilProfile1D()); BindSupport.Bind(panel, insertSpecificMechanismPointLocationMenuItem, ge => ge.InsertSpecificMechanismPointLocation()); BindSupport.Bind(panel, addCenterCrestLocationTo2DProfileMenuItem, ge => ge.AddCenterCrestLocationTo2DProfile()); BindSupport.Bind(panel, addSurfaceLineToCreateNew2DProfileMenuItem, ge => ge.AddSurfaceLineToCreateNew2DProfile()); BindSupport.Bind(panel, addSurfaceLineToCreate2DProfileMenuItem, ge => ge.AddSurfaceLineToCreate2DProfile()); BindSupport.Bind(panel, add1DProfileToCreate2DProfileMenuItem, ge => ge.Add1DProfileToCreate2DProfile()); BindSupport.Assign(panel, this); } private void spatialEditor_ShapeRemoved(object sender, ShapeEventArgs e) { // if a CPT/Boring/Soilprofile Lookup is deleted, remove it from the project object dataObject = e.Shape.DataObject; if (dataObject is ConePenetrationTestLookup1D) { project.CptLookup1Ds.Remove((ConePenetrationTestLookup1D)dataObject); } if (dataObject is ConePenetrationTestLookup2D) { project.CptLookup2Ds.Remove((ConePenetrationTestLookup2D)dataObject); } if (dataObject is BoringLookup1D) { project.BoringLookup1Ds.Remove((BoringLookup1D)dataObject); } if (dataObject is BoringLookup2D) { project.BoringLookup2Ds.Remove((BoringLookup2D)dataObject); } if (dataObject is SoilProfile1DLookup2D) { project.Soilprofile1DLookup2Ds.Remove((SoilProfile1DLookup2D)dataObject); } if (dataObject is SpecificMechanismPointLocation) { project.SpecificMechanismPointLocations.Remove((SpecificMechanismPointLocation)dataObject); } if (dataObject is CenterCrestLocation) { ((CenterCrestLocation) dataObject).SoilProfile2D.CenterCrestLocation = double.NaN; localCenterCrestLocation = null; } var surfaceLine2 = dataObject as SurfaceLine2; if (null != surfaceLine2) { project.SurfaceLines.Remove(surfaceLine2); surfaceLine2.Dispose(); } } private void ShowCpt(object sender, object selectedObj) { var cpt = (ConePenetrationTestData)sender; if (spatialEditor.EmptySelection == null || spatialEditor.EmptySelection.DataObject == null || !(spatialEditor.EmptySelection.DataObject is ConePenetrationTestData) || (spatialEditor.EmptySelection.DataObject as ConePenetrationTestData).Name != cpt.Name) { Clear(); AddCPT(cpt); spatialEditor.EmptySelection = new EmptyShape(sender); spatialEditor.Refresh(); if (selectedObj == null || selectedObj is SoilProfile2D) { spatialEditor.ZoomToExtents(true); } else { UpdateExtents(true); } } // Always reset caption SetCaption(string.Format(LocalizationManager.GetTranslatedText(this, "ShowCpt"), cpt.Name)); } private void ShowBoring(object sender, object selectedObj) { var boring = (Boring)sender; if (spatialEditor.EmptySelection == null || spatialEditor.EmptySelection.DataObject == null || !(spatialEditor.EmptySelection.DataObject is Boring) || (spatialEditor.EmptySelection.DataObject as Boring).Name != boring.Name) { Clear(); AddBoring(boring); spatialEditor.EmptySelection = new EmptyShape(sender); spatialEditor.Refresh(); Boring selectedBoring = null; if (selectedObj is Boring) { selectedBoring = (Boring)selectedObj; } if (selectedObj == null || selectedBoring == null || (boring.Name != selectedBoring.Name)) { spatialEditor.ZoomToExtents(true); } else { UpdateExtents(true); } } SetCaption(string.Format(LocalizationManager.GetTranslatedText(this, "ShowBoring"), boring.Name)); } private void ShowSurfaceLine(object sender, object selectedObj) { var surfaceLine = (SurfaceLine2)sender; if (spatialEditor.EmptySelection == null || spatialEditor.EmptySelection.DataObject == null || !(spatialEditor.EmptySelection.DataObject is SurfaceLine2) || (spatialEditor.EmptySelection.DataObject as SurfaceLine2).Name != surfaceLine.Name) { Clear(); AddSurfaceLine(surfaceLine); spatialEditor.EmptySelection = new EmptyShape(sender); spatialEditor.Refresh(); UpdateExtents(true); } SetCaption(string.Format(LocalizationManager.GetTranslatedText(this, "ShowSurfaceLine"), surfaceLine.Name)); } private void ShowSoilProfile1D(object sender, object selectedObj) { var soilProfile1D = (SoilProfile1D)sender; if (spatialEditor.EmptySelection == null || spatialEditor.EmptySelection.DataObject == null || !(spatialEditor.EmptySelection.DataObject is SoilProfile1D) || (spatialEditor.EmptySelection.DataObject as SoilProfile1D).Name != soilProfile1D.Name) { Clear(); AddSoilProfile1D(soilProfile1D); spatialEditor.EmptySelection = new EmptyShape(sender); spatialEditor.Refresh(); if (selectedObj == null || selectedObj is SoilProfile2D) { spatialEditor.ZoomToExtents(true); } else { UpdateExtents(true); } } SetCaption(string.Format(LocalizationManager.GetTranslatedText(this, "ShowSoilProfile1D"), soilProfile1D.Name)); } private void ShowSoilProfile2D(object sender) { var soilProfile2D = (SoilProfile2D)sender; selectedGeom = soilProfile2D.Geometry; geometryEditor.DeleteShapeMethod = selectedGeom.DeleteGeometryObjects; if (spatialEditor.EmptySelection == null || spatialEditor.EmptySelection.DataObject == null || !(spatialEditor.EmptySelection.DataObject is SoilProfile2D) || (spatialEditor.EmptySelection.DataObject as SoilProfile2D).Name != soilProfile2D.Name || updateForCenterCrestLocation) { updateForCenterCrestLocation = false; if (soilProfile2D.Geometry.Points.Count == 0 && Math.Abs(soilProfile2D.Geometry.Bottom - Double.MaxValue) < Double.Epsilon) { soilProfile2D.Geometry.Left = GeometryConstants.DefaultLeftLimitGeometry; soilProfile2D.Geometry.Right = GeometryConstants.DefaultRightLimitGeometry; soilProfile2D.Geometry.Bottom = GeometryConstants.DefaultBottomLimitGeometry; } Clear(); AddSoilProfile2D(soilProfile2D); spatialEditor.EmptySelection = new EmptyShape(sender); spatialEditor.Refresh(); spatialEditor.ZoomToExtents(false); } SetCaption(string.Format(LocalizationManager.GetTranslatedText(this, "ShowSoilProfile2D"), soilProfile2D.Name)); } private void AddSoilProfile1D(SoilProfile1D soilProfile) { if (spatialEditor.EmptySelection == null) { spatialEditor.AddObject(soilProfile); spatialEditor.AddList(soilProfile.Layers); // reconnect CPT and Boring lookups ? foreach (var lookup in project.CptLookup1Ds.Where(p => p.SoilProfile1D == soilProfile)) { cptLookup1Ds.Add(lookup); } foreach (var boring in project.BoringLookup1Ds.Where(p => p.SoilProfile1D == soilProfile)) { boringLookup1Ds.Add(boring); } spatialEditor.AddList(cptLookup1Ds); spatialEditor.AddList(boringLookup1Ds); } else if (spatialEditor.EmptySelection.DataObject is SoilProfile2D) { var soilProfile2D = spatialEditor.EmptySelection.DataObject as SoilProfile2D; var lookup = new SoilProfile1DLookup2D { SoilProfile1D = soilProfile, SoilProfile2D = soilProfile2D, Xlocal = (soilProfile2D.Geometry.Right - soilProfile2D.Geometry.Left) * 0.5 }; UndoRedoManager.Instance.BeginAction(); DataEventPublisher.BeforeChange(soilprofile1DLookup2Ds); DataEventPublisher.BeforeChange(project.Soilprofile1DLookup2Ds); soilprofile1DLookup2Ds.Add(lookup); project.Soilprofile1DLookup2Ds.Add(lookup); DataEventPublisher.DataListModified(soilprofile1DLookup2Ds); DataEventPublisher.DataListModified(project.Soilprofile1DLookup2Ds); UndoRedoManager.Instance.EndAction(); } } private void AddSoilProfile2D(SoilProfile2D soilProfile) { spatialEditor.AddObject(soilProfile); spatialEditor.AddObject(soilProfile.Geometry); spatialEditor.AddList(soilProfile.Surfaces); spatialEditor.AddList(soilProfile.Geometry.Curves); spatialEditor.AddList(soilProfile.Geometry.Points); if (soilProfile.PreconsolidationStresses != null) { spatialEditor.AddList(soilProfile.PreconsolidationStresses); } // reconnect CPT and Boring lookups ? foreach (var lookup in project.CptLookup2Ds.Where(p => p.SoilProfile2D == soilProfile)) { cptLookup2Ds.Add(lookup); } foreach (var boring in project.BoringLookup2Ds.Where(p => p.SoilProfile2D == soilProfile)) { boringLookup2Ds.Add(boring); } // reconnect linked 1D profiles ? foreach (var lookup in project.Soilprofile1DLookup2Ds.Where(l => l.SoilProfile2D == soilProfile)) { soilprofile1DLookup2Ds.Add(lookup); } // reconnect specific SpecificMechanismPointLocation definitions ? foreach (var location in project.SpecificMechanismPointLocations.Where(l => l.SoilProfile2D == soilProfile)) { specificMechanismPointLocations.Add(location); } // set the proper localCenterCrestLocation if (!double.IsNaN(soilProfile.CenterCrestLocation)) { localCenterCrestLocation = new CenterCrestLocation { SoilProfile2D = soilProfile, Location = soilProfile.CenterCrestLocation }; } spatialEditor.AddObject(localCenterCrestLocation); spatialEditor.AddList(cptLookup2Ds); spatialEditor.AddList(boringLookup2Ds); spatialEditor.AddList(soilprofile1DLookup2Ds); spatialEditor.AddList(specificMechanismPointLocations); selectedGeom = soilProfile.Geometry; } private void AddCPT(ConePenetrationTestData conePenetrationTestData) { if (spatialEditor.EmptySelection == null) { spatialEditor.AddObject(conePenetrationTestData); } else if (AddCPTCallback != null) { AddCPTCallback(conePenetrationTestData); } else if (spatialEditor.EmptySelection.DataObject is SoilProfile2D) { var soilProfile2D = spatialEditor.EmptySelection.DataObject as SoilProfile2D; var lookup = new ConePenetrationTestLookup2D { ConePenetrationTestData = conePenetrationTestData, SoilProfile2D = soilProfile2D, Xlocal = (soilProfile2D.Geometry.Right - soilProfile2D.Geometry.Left) * 0.5, Zlocal = 0.0d, }; DataEventPublisher.BeforeChange(cptLookup2Ds); DataEventPublisher.BeforeChange(project.CptLookup2Ds); cptLookup2Ds.Add(lookup); project.CptLookup2Ds.Add(lookup); DataEventPublisher.DataListModified(cptLookup2Ds); DataEventPublisher.DataListModified(project.CptLookup2Ds); } else if (spatialEditor.EmptySelection.DataObject is SoilProfile1D) { var lookup = new ConePenetrationTestLookup1D { ConePenetrationTestData = conePenetrationTestData, SoilProfile1D = spatialEditor.EmptySelection.DataObject as SoilProfile1D, }; DataEventPublisher.BeforeChange(cptLookup1Ds); DataEventPublisher.BeforeChange(project.CptLookup1Ds); cptLookup1Ds.Add(lookup); project.CptLookup1Ds.Add(lookup); DataEventPublisher.DataListModified(cptLookup1Ds); DataEventPublisher.DataListModified(project.CptLookup1Ds); } } private void AddBoring(Boring boring) { if (spatialEditor.EmptySelection == null) { spatialEditor.AddObject(boring); spatialEditor.AddList(boring.BoringLayers); } else if (spatialEditor.EmptySelection.DataObject is SoilProfile2D) { var soilProfile2D = spatialEditor.EmptySelection.DataObject as SoilProfile2D; var lookup = new BoringLookup2D { Boring = boring, SoilProfile2D = soilProfile2D, Xlocal = (soilProfile2D.Geometry.Right - soilProfile2D.Geometry.Left) * 0.5, Zlocal = 0.0d }; UndoRedoManager.Instance.BeginAction(); DataEventPublisher.BeforeChange(boringLookup2Ds); DataEventPublisher.BeforeChange(project.BoringLookup2Ds); boringLookup2Ds.Add(lookup); project.BoringLookup2Ds.Add(lookup); DataEventPublisher.DataListModified(boringLookup2Ds); DataEventPublisher.DataListModified(project.BoringLookup2Ds); UndoRedoManager.Instance.EndAction(); } else if (spatialEditor.EmptySelection.DataObject is SoilProfile1D) { var lookup = new BoringLookup1D { Boring = boring, SoilProfile1D = spatialEditor.EmptySelection.DataObject as SoilProfile1D, }; UndoRedoManager.Instance.BeginAction(); DataEventPublisher.BeforeChange(boringLookup1Ds); DataEventPublisher.BeforeChange(project.BoringLookup1Ds); boringLookup1Ds.Add(lookup); project.BoringLookup1Ds.Add(lookup); DataEventPublisher.DataListModified(boringLookup1Ds); DataEventPublisher.DataListModified(project.BoringLookup1Ds); UndoRedoManager.Instance.EndAction(); } } private void AddSurfaceLine(SurfaceLine2 surfaceLine) { if (spatialEditor.EmptySelection == null) { spatialEditor.AddObject(surfaceLine); } List characteristicPoints = surfaceLine.CharacteristicPoints.Where( characteristicPoint => characteristicPoint.CharacteristicPointType != CharacteristicPointType.None).ToList(); spatialEditor.AddList(characteristicPoints); } private void AddSpecificMechanismPointLocation() { if (spatialEditor.EmptySelection != null && spatialEditor.EmptySelection.DataObject is SoilProfile2D) { var soilProfile2D = spatialEditor.EmptySelection.DataObject as SoilProfile2D; var lookup = new SpecificMechanismPointLocation { SoilProfile2D = soilProfile2D, XCoordinate = (soilProfile2D.Geometry.Right - soilProfile2D.Geometry.Left) * 0.5 }; UndoRedoManager.Instance.BeginAction(); DataEventPublisher.BeforeChange(specificMechanismPointLocations); DataEventPublisher.BeforeChange(project.SpecificMechanismPointLocations); specificMechanismPointLocations.Add(lookup); project.SpecificMechanismPointLocations.Add(lookup); DataEventPublisher.DataListModified(specificMechanismPointLocations); DataEventPublisher.DataListModified(project.SpecificMechanismPointLocations); DataEventPublisher.SelectionChanged(lookup); UndoRedoManager.Instance.EndAction(); } } private void AddCenterCrestLocation() { if (spatialEditor.EmptySelection != null && spatialEditor.EmptySelection.DataObject is SoilProfile2D) { var soilProfile2D = spatialEditor.EmptySelection.DataObject as SoilProfile2D; if (localCenterCrestLocation == null) { localCenterCrestLocation = new CenterCrestLocation(); } UndoRedoManager.Instance.BeginAction(); DataEventPublisher.BeforeChange(soilProfile2D); DataEventPublisher.BeforeChange(project.SoilProfiles2D); soilProfile2D.CenterCrestLocation = (soilProfile2D.Geometry.Right - soilProfile2D.Geometry.Left) * 0.5; localCenterCrestLocation.SoilProfile2D = soilProfile2D; localCenterCrestLocation.Location = soilProfile2D.CenterCrestLocation; DataEventPublisher.DataListModified(project.SoilProfiles2D); DataEventPublisher.SelectionChanged(localCenterCrestLocation); UndoRedoManager.Instance.EndAction(); } } private void UpdateExtents(bool maintainAspectRatio) { Projection cs = spatialEditor.CoordinateSystem; Rectangle bounds = spatialEditor.Bounds; foreach (var shape in spatialEditor.Shapes) { Rectangle? extents = shape.GetExtents(cs); if (extents != null) { if (!bounds.Contains(extents.Value)) { spatialEditor.ZoomToExtents(maintainAspectRatio); return; } } } spatialEditor.CenterExtents(); } private void SetCaption(string caption) { mainForm.GeometryDockPanel.Text = caption; } private void Clear() { geometryEditor.Clear(); cptLookup1Ds.Clear(); cptLookup2Ds.Clear(); boringLookup1Ds.Clear(); boringLookup2Ds.Clear(); soilprofile1DLookup2Ds.Clear(); specificMechanismPointLocations.Clear(); localCenterCrestLocation = null; } private void AddSurfaceLineToCreate2DProfile() { var currentProfile1D = (spatialEditor.EmptySelection.DataObject as SoilProfile1D); // Create a 2D profile from current 1D and selected surfaceline if (project != null) { string item = HandleModalListSelection(project.SurfaceLines.OrderBy(p => p.Name).Select(p => p.Name).ToList(), "SelectSurfaceLine"); if (item != null) { SurfaceLine2 surfaceLine2 = project.SurfaceLines.First(p => p.Name == item); Create2DProfileFromSoilProfile1DAndSurfaceLine2(currentProfile1D, surfaceLine2); } } } private void Add1DProfileToCreate2DProfile() { var currentSurfaceLine2 = (spatialEditor.EmptySelection.DataObject as SurfaceLine2); // Create a 2D profile from current surfaceline and selected 1D if (project != null) { string item = HandleModalListSelection(project.SoilProfiles1D.OrderBy(p => p.Name).Select(p => p.Name).ToList(), "SelectProfile1D"); if (item != null) { SoilProfile1D profile1D = project.SoilProfiles1D.First(p => p.Name == item); Create2DProfileFromSoilProfile1DAndSurfaceLine2(profile1D, currentSurfaceLine2); } } } // TODO: Implement ? private void CreateNew2DProfileFromSoilProfile2DAndSurfaceLine2(SoilProfile2D profile2D, SurfaceLine2 surfaceLine2) { // Determine the requested shift of the geometry var dtrx = surfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).X; var dtpx = surfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X; var cloneProfile = (SoilProfile2D)profile2D.Clone(); var shift = ((dtrx + dtpx) * 0.5) - cloneProfile.CenterCrestLocation; foreach (var point in cloneProfile.Geometry.Points) { point.X += shift; } cloneProfile.Geometry.Rebox(); var utils = new GeotechnicsUtilities(); var soilProfile2D = utils.CombineSurfaceLineWithSoilProfile2D(surfaceLine2.Geometry, cloneProfile, null); soilProfile2D.Name = profile2D.Name + surfaceLine2.Name; AddSoilProfile2DToProjectAndUpdateUI(soilProfile2D); } private void Create2DProfileFromSoilProfile1DAndSurfaceLine2(SoilProfile1D profile1D, SurfaceLine2 surfaceLine2) { var soilSurfaceProfile = new SoilSurfaceProfile { SoilProfile = profile1D, SurfaceLine2 = surfaceLine2, Name = surfaceLine2.Name + "_" + profile1D.Name, CreateSettlementZones = true }; // Convert the soilsurfacesoilprofile to a SoilProfile2D to be able to edit it properly. var soilProfile2D = soilSurfaceProfile.ConvertToSoilProfile2D(); // Determine center of crest if possible if (surfaceLine2.HasDike()) { soilProfile2D.CenterCrestLocation = (surfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).X + surfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X)*0.5; } soilSurfaceProfile.Dispose(); AddSoilProfile2DToProjectAndUpdateUI(soilProfile2D); } private void AddSoilProfile2DToProjectAndUpdateUI(SoilProfile2D soilProfile2D) { DataEventPublisher.BeforeChange(project.SoilProfiles2D); UniqueNameProvider.ProvideUniqueName(project.SoilProfiles2D, soilProfile2D); project.SoilProfiles2D.Add(soilProfile2D); DataEventPublisher.DataListModified(project.SoilProfiles2D); var table = mainForm.DynamicTableControl.TabControl.Controls.Find("2DProfiles", true).FirstOrDefault(); if (table != null) { mainForm.SetAsActiveTable(table); DataEventPublisher.SelectionChanged(soilProfile2D); } } private string HandleModalListSelection(List items, string caption) { var modalList = new ModalListBox { Text = LocalizationManager.GetTranslatedText(this, caption), Items = items }; if (modalList.ShowDialog() == DialogResult.OK) { return modalList.SelectedItem; } return null; } } }