/// <summary> /// Works out positions for this subdivision op and draws them. Before calling /// this function, a call to <c>GetDistances</c> is required. /// </summary> List <IPosition> AddPoints() { // Return if there is nothing to add (we need at least 2 distances). if (m_Distances == null || m_Distances.Count <= 1) { return(null); } // Get adjusted lengths for each section (on the map projection, not the ground) double[] lens = LineSubdivisionFace.GetAdjustedLengths(m_Line, m_Distances.ToArray()); List <IPosition> pts = new List <IPosition>(lens.Length); double tot = (m_FromStart ? 0.0 : m_Line.Length.Meters); foreach (double d in lens) { if (m_FromStart) { tot += d; } else { tot -= d; } IPosition p; if (m_Line.LineGeometry.GetPosition(new Length(tot), out p)) { pts.Add(p); } } return(pts); }
/// <summary> /// Parses the distances list box. /// </summary> /// <returns>The parsed distances.</returns> Distance[] GetDistances() { string entryString = GetEntryString(); DistanceUnit defaultEntryUnit = EditingController.Current.EntryUnit; return(LineSubdivisionFace.GetDistances(entryString, defaultEntryUnit, !m_FromStart)); }
private void LineSubdivisionUpdateForm_Shown(object sender, EventArgs e) { // Get the object that was selected for update. Feature feat = m_UpdCmd.GetUpdate(); if (feat == null) { throw new InvalidOperationException("Unexpected update object"); } // Get the edit that created the primary face m_pop = (feat.Creator as LineSubdivisionOperation); Debug.Assert(m_pop != null); if (!m_pop.IsPrimaryFace) { m_pop = m_pop.OtherSide; Debug.Assert(m_pop != null); Debug.Assert(m_pop.IsPrimaryFace); } // Grab something we throw away if the user decides to cancel m_Face1 = CreateWorkingFace(m_pop.Face, true); m_Face2 = (m_pop.OtherSide == null ? null : CreateWorkingFace(m_pop.OtherSide.Face, false)); // If we have two faces, the "New Face" button means you want to switch to the other face. if (m_Face2 != null) { newFaceButton.Text = "&Other Face"; } // Default to the face containing the initially selected feature m_CurrentFace = (feat.Creator == m_pop ? m_Face1 : m_Face2); // If a line was selected, remember where it is in our working copy (and if it's actually on // the alternate face, make that the initial face for editing). m_SelectedLine = null; LineFeature selectedLine = (feat as LineFeature); if (selectedLine != null) { LineFeature[] sections = (m_CurrentFace == m_Face1 ? m_pop.Face.Sections : m_pop.OtherSide.Face.Sections); int lineIndex = Array.FindIndex <LineFeature>(sections, t => t == selectedLine); if (lineIndex >= 0) { m_SelectedLine = m_CurrentFace.Sections[lineIndex]; } } // Disable the option to flip annotation if annotation is currently invisible if (!EditingController.Current.AreLineAnnotationsDrawn) { flipDistButton.Enabled = false; } // Reload the list and repaint RefreshList(); }
/// <summary> /// Initialize the sections for a working copy of a subdivision face. /// </summary> /// <param name="face">A transient face to create sections for</param> /// <param name="isPrimaryFace">Is the specified face the primary face?</param> void InitializeWorkingFace(LineSubdivisionFace face, bool isPrimaryFace) { // Create throwaway line sections (without any feature IDs, not associated with any session, // not in spatial index). FeatureFactory ff = new ThrowawayFeatureFactory(m_pop); ff.LineType = m_pop.Parent.EntityType; face.CreateSections(m_pop.Parent, ff, isPrimaryFace); // And calculate initial geometry face.CalculateGeometry(m_pop.Parent, null); }
/// <summary> /// Initializes a new instance of the <see cref="LegFace"/> class /// using the data read from persistent storage. /// </summary> /// <param name="editDeserializer">The mechanism for reading back content.</param> internal LegFace(EditDeserializer editDeserializer) { // Only connection paths should generate LegFace instances PathOperation op = (editDeserializer.CurrentEdit as PathOperation); if (op == null) { throw new ApplicationException("Unexpected creating edit for a leg face"); } this.Sequence = editDeserializer.ReadInternalId(DataField.Id); if (editDeserializer.IsNextField(DataField.PrimaryFaceId)) { InternalIdValue primaryFaceId = editDeserializer.ReadInternalId(DataField.PrimaryFaceId); LegFace face = op.FindFace(primaryFaceId); if (face == null) { throw new ApplicationException("Cannot locate primary face " + primaryFaceId); } Leg = face.Leg; Leg.AlternateFace = this; } else { // This should never happen. Primary faces are not serialized using the LegFace // class (we only use LegFace as part of a PathOperation to simplify import of // extra legs from old CEdit files). throw new ApplicationException(); } // Convert the data entry string into observed spans string entryString = editDeserializer.ReadString(DataField.EntryString); DistanceUnit defaultEntryUnit = EditingController.Current.EntryUnit; Distance[] dists = LineSubdivisionFace.GetDistances(entryString, defaultEntryUnit, false); m_Spans = new SpanInfo[dists.Length]; for (int i = 0; i < m_Spans.Length; i++) { m_Spans[i] = new SpanInfo() { ObservedDistance = dists[i] }; } }
/// <summary> /// Saves a new edit that defines an alternate face for a previously subdivided line. /// </summary> /// <param name="firstSide">The edit that initially subdivided the line.</param> /// <param name="altFace">The definition of the alternate face</param> void AddOtherSide(LineSubdivisionOperation firstSide, LineSubdivisionFace altFace) { try { LineSubdivisionOperation op = new LineSubdivisionOperation(firstSide.Parent, altFace.ObservedLengths, altFace.IsEntryFromEnd); op.OtherSide = firstSide; op.Execute(); firstSide.OtherSide = op; } catch (Exception ex) { MessageBox.Show(ex.StackTrace, ex.Message); } }
/// <summary> /// Creates a working copy of an existing face. /// </summary> /// <param name="face">The face to copy</param> /// <param name="isPrimaryFace">Is the specified face the primary face?</param> /// <returns>The working copy</returns> LineSubdivisionFace CreateWorkingFace(LineSubdivisionFace face, bool isPrimaryFace) { if (face == null) { return(null); } // Make a copy of the distance observations from the source face Distance[] distances = CopyDistances(face); LineSubdivisionFace result = new LineSubdivisionFace(distances, face.IsEntryFromEnd); // Create sections and calculate geometry InitializeWorkingFace(result, isPrimaryFace); return(result); }
/// <summary> /// Obtains the distances for one subdivision face (along with a note as /// to whether the annotation has been flipped or not). /// </summary> /// <param name="face">The face of interest (may be null)</param> /// <returns>A copy of the distances along the face (null if the supplied face is null).</returns> Distance[] CopyDistances(LineSubdivisionFace face) { if (face == null) { return(null); } Distance[] current = face.ObservedLengths; Distance[] result = new Distance[current.Length]; for (int i = 0; i < result.Length; i++) { result[i] = new Distance(current[i]); } return(result); }
/// <summary> /// Parses the distances list box. /// </summary> /// <returns>The total distance entered, in meters.</returns> double GetDistances() { m_Distances = null; try { string entryString = GetEntryString(); DistanceUnit defaultEntryUnit = EditingController.Current.EntryUnit; m_Distances = LineSubdivisionFace.GetDistances(entryString, defaultEntryUnit, false); // Return the total length (in meters) double result = 0.0; foreach (Distance d in m_Distances) { result += d.Meters; } return(result); } catch { } return(0.0); }
internal override bool DialFinish(Control wnd) { if (m_Dialog == null && m_UpDial == null) { throw new Exception("LineSubdivisionUI.DialFinish - No dialog!"); } UpdateUI up = this.Update; bool doAbort = false; if (up != null) { // Get the original operation. LineSubdivisionOperation pop = (up.GetOp() as LineSubdivisionOperation); if (pop == null) { MessageBox.Show("LineSubdivisionUI.DialFinish - Unexpected edit type."); return(false); } // Ensure we've got the edit for the primary face if (!pop.IsPrimaryFace) { pop = pop.OtherSide; Debug.Assert(pop != null); Debug.Assert(pop.IsPrimaryFace); } // Package up any changes to the primary face UpdateItemCollection changes = pop.GetUpdateItems(m_UpDial.WorkingFace1); if (changes.Count > 0) { up.AddUpdate(pop, changes); } // If a second face has just been defined, append a new edit. LineSubdivisionFace face2 = m_UpDial.WorkingFace2; if (face2 != null) { if (pop.OtherSide == null) { AddOtherSide(pop, face2); } else { changes = pop.OtherSide.GetUpdateItems(face2); if (changes.Count > 0) { up.AddUpdate(pop.OtherSide, changes); } } } // If all we've done is add a new face, UpdateUI.AddUpdate wouldn't have been // called, which will later lead to an exception from UpdateUI.FinishCommand (via // the FinishCommand done below). So remember to abort in that case. doAbort = (up.HasRevisions == false); } else { // Ensure that the parent line has been de-selected by the view. Controller.ClearSelection(); // Get the dialog to save. m_Dialog.Save(); } // Destroy the dialog(s). KillDialogs(); // Get the base class to finish up. if (doAbort) { return(AbortCommand()); } else { return(FinishCommand()); } }
private void newFaceButton_Click(object sender, EventArgs e) { // If we previously highlighted something, draw it normally (since it cannot exist as part of any other face). m_SelectedLine = null; // If a second face doesn't already exist, get the user to specify the distances. if (m_Face2 == null) { try { this.WindowState = FormWindowState.Minimized; // Get the distance observations using (LegForm dial = new LegForm(GetObservedLength())) { if (dial.ShowDialog() != DialogResult.OK) { return; } // Must be at least two distances Distance[] dists = dial.Distances; if (dists == null || dists.Length < 2) { MessageBox.Show("The new face must have at least two spans"); return; } // Default annotations to the flip side foreach (Distance d in dists) { d.IsAnnotationFlipped = true; } // Create the new face (for use in preview only) m_Face2 = new LineSubdivisionFace(dists, m_Face1.IsEntryFromEnd); InitializeWorkingFace(m_Face2, false); newFaceButton.Text = "&Other Face"; } } finally { this.WindowState = FormWindowState.Normal; } } // Switch to the other face (possibly the one just added) if (m_CurrentFace == m_Face1) { m_CurrentFace = m_Face2; } else { m_CurrentFace = m_Face1; } RefreshList(); }