private void noTerminalCheckBox_CheckedChanged(object sender, EventArgs e) { // If we previously had a terminal line, erase the terminal // position and unhighlight the arc. ISpatialDisplay draw = m_Cmd.ActiveDisplay; if (m_Line != null) { m_Cmd.ErasePainting(); } m_Line = null; ParallelLineUI cmd = Command; // Draw the parallel point instead. if (m_IsLast) { m_Terminal = cmd.ParallelTwo; } else { m_Terminal = cmd.ParallelOne; } EditingController.Current.Style(Color.Yellow).Render(draw, m_Terminal); }
/// <summary> /// Tries to find a terminal line to end the parallel on. /// </summary> /// <returns>False if parallel positions are not available. True /// otherwise (that does not mean that a terminal was actually found). /// </returns> bool FindTerminal() { // Get the position of the parallel point. ParallelLineUI cmd = this.Command; IPosition parpos; if (m_IsLast) { parpos = cmd.ParallelTwo; } else { parpos = cmd.ParallelOne; } // The parallel point HAS to be known. if (parpos == null) { MessageBox.Show("Parallel point has not been calculated"); return(false); } // Treat the parallel point as the initial terminal. m_Terminal = parpos; // Get the offset to the parallel. double offset = cmd.GetPlanarOffset(); // Figure out a search radius (the smaller of half the offset, // or half a centimetre at the current draw scale). double scale = cmd.ActiveDisplay.MapScale; ILength tol = new Length(Math.Min(offset * 0.5, scale * 0.005)); // Search for the line closest to the parallel point, and // within the search radius. The line has to be visible // and selectable. CadastralMapModel map = CadastralMapModel.Current; //m_Line = map.FindClosestLine(parpos, tol, true); m_Line = (map.Index.QueryClosest(parpos, tol, SpatialType.Line) as LineFeature); // If we found something, highlight it (after confirming that // it really does intersect the parallel). if (m_Line != null) { IPosition xsect = cmd.GetIntersect(m_Line, m_IsLast); if (xsect == null) { m_Line = null; } else { //pView->UnHighlight(m_pArc); //pView->Highlight(*m_pArc); m_Terminal = xsect; } } return(true); }
/// <summary> /// Delegate that's called whenever the index finds a line. /// </summary> /// <param name="item">The item to process</param> /// <returns>True (always), indicating that the query should continue.</returns> private bool CheckLine(ISpatialObject item) { Debug.Assert(item is LineFeature); LineFeature line = (LineFeature)item; // Return if the line is non-topological if (!line.IsTopological) { return(true); } Topology t = line.Topology; if (t != null) { foreach (IDivider d in t) { CheckType types = (m_Options & DividerCheck.Check(d)); if (types != CheckType.Null) { DividerCheck check = new DividerCheck(d, types); m_Result.Add(check); } } } return(OnCheck()); }
/// <summary> /// /// </summary> /// <param name="line"></param> internal void OnLineDeactivation(LineFeature line) { // Remove the reference the intersection has to the line Remove(line); // If the intersection now refers only to one line, it's no longer // an intersection, so remove it from the spatial index and merge // the sections incident on the intersection. if (m_Lines.Count <= 1) { if (IsIndexed) { CadastralMapModel map = line.MapModel; EditingIndex index = map.EditingIndex; index.RemoveIntersection(this); } if (m_Lines.Count > 0) { Topology t = m_Lines[0].Topology; if (t != null) { // Merge the two sections - if we end up with just one // section covering the whole line, replace list topology // with fresh topology for the whole line. if (t.MergeSections(this) == 1) { m_Lines[0].SetTopology(true); } } } } }
internal LineSubdivisionControl(LineSubdivisionUI cmd, LineFeature line, Operation recall) { InitializeComponent(); // Remember the command. m_Cmd = cmd; // Remember the line involved & its length (in meters) m_Line = line; m_GroundLength = line.GroundLength.Meters; // No distances so far. m_Distances = null; m_FromStart = true; // If we are recalling a previous operation, grab the observed distances from there (only the primary face) LineSubdivisionOperation op = (recall as LineSubdivisionOperation); if (op!=null) { LineFeature[] sections = op.Face.Sections; m_Distances = new List<Distance>(sections.Length); foreach (LineFeature s in sections) m_Distances.Add(new Distance(s.ObservedLength)); } }
/// <summary> /// Creates a new <c>IntersectionFinder</c> for the specified line feature. /// Use this constructor when intersecting something that has already been added to /// the map model. This ensures that the line is not intersected with itself. /// </summary> /// <param name="line">The line feature to intersect.</param> /// <param name="wantEndEnd">Specify true if you want end-to-end intersections in the results.</param> internal IntersectionFinder(LineFeature line, bool wantEndEnd) { m_Line = line; ISpatialIndex index = CadastralMapModel.Current.Index; m_Intersects = new FindIntersectionsQuery(index, line, wantEndEnd).Result; }
/// <summary> /// Convenience method that marks a line as "moved" (first checks whether /// the specified line is null). This is normally called by implementations /// of the <c>Intersect</c> method. /// </summary> /// <param name="line">The line to mark as moved (may be null)</param> protected void SetMoved(LineFeature line) { if (line != null) { line.IsMoved = true; } }
/// <summary> /// Creates a new line section /// </summary> /// <param name="itemName">The name for the item involved</param> /// <param name="baseLine">The line that this section is part of</param> /// <param name="from">The point at the start of the section</param> /// <param name="to">The point at the end of the section</param> /// <returns>The created section (never null)</returns> internal override LineFeature CreateSection(string itemName, LineFeature baseLine, PointFeature from, PointFeature to) { IFeature f = new FeatureStub(this.Creator, InternalIdValue.Empty, baseLine.EntityType, null); return(new LineFeature(f, baseLine, from, to, baseLine.IsTopological)); }
/// <summary> /// Reacts to action that concludes the command dialog. /// </summary> /// <param name="wnd">The dialog window where the action originated (not used)</param> /// <returns>True if command finished ok. This implementation returns the /// result of a call to <see cref="FinishCommand"/>.</returns> internal override bool DialFinish(Control wnd) { // Ensure any reserved ID has been returned to the pool m_PolygonId.DiscardReservedId(); // Ensure any text outline has been erased. EraseRect(); // Clear any polygon fill DrawPolygon(false); // And un-highlight any orientation line if (m_Orient != null) { ErasePainting(); m_Orient = null; } // If the last row we created was not associated with a label, get rid of it now. //if (m_pLastRow && !m_pLastRow->GetpId()) //{ // delete m_pLastRow; // m_pLastRow = 0; //} // Get the base class to finish up. return(base.DialFinish(wnd)); }
/// <summary> /// Creates a new <c>AttachPointUI</c> /// </summary> /// <param name="action">The action that initiated the command</param> internal AttachPointUI(IUserAction action) : base(action) { m_PointType = null; m_Repeat = false; m_Line = null; }
/// <summary> /// Rollback this operation (occurs when a user undoes the last edit). /// </summary> internal override void Undo() { base.OnRollback(); // Get rid of the observation m_Direction.OnRollback(this); // Cut direct refs made by this operation. if (m_Line != null) { m_Line.CutOp(this); } if (m_CloseTo != null) { m_CloseTo.CutOp(this); } // Undo the intersect point and any lines Rollback(m_Intersection); Rollback(m_DirLine); Rollback(m_LineA); Rollback(m_LineB); // If we actually did a split, re-activate the original line. if (m_LineA != null || m_LineB != null) { m_LineA = null; m_LineB = null; m_Line.Restore(); } }
void InitUpdate(LineExtensionOperation pop) { Form parent = ParentForm; parent.Text = "Update Line Extension"; m_ExtendLine = pop.ExtendedLine; m_IsExtendFromEnd = pop.IsExtendFromEnd; m_Length = new Distance(pop.Length); // Was an extension line added? m_WantLine = (pop.NewLine != null); // Scroll the entity combo to the previously defined // entity type for the extension point. PointFeature point = pop.NewPoint; IEntity ent = point.EntityType; if (ent != null) { pointTypeComboBox.SelectEntity(ent); } // Display the original observed length. lengthTextBox.Text = m_Length.Format(); // Display the point key (if any) idComboBox.DropDownStyle = ComboBoxStyle.DropDown; idComboBox.Text = point.FormattedKey; }
/// <summary> /// Creates new topology for the specified line. /// </summary> /// <param name="line">The line the topology is associated with</param> /// <returns>New topology for the line (with undefined topological relationships)</returns> internal static Topology CreateTopology(LineFeature line) { // Return topology that's suitable for representing the complete line. This // may need to be converted into a SectionTopologyList once we get around to // calculating intersections. return new LineDivider(line); }
/// <summary> /// Initializes a new instance of the <see cref="LineSubdivisionOperation"/> class /// using the data read from persistent storage. /// </summary> /// <param name="editDeserializer">The mechanism for reading back content.</param> internal LineSubdivisionOperation(EditDeserializer editDeserializer) : base(editDeserializer) { m_Line = editDeserializer.ReadFeatureRef <LineFeature>(DataField.Line); m_Face = editDeserializer.ReadPersistent <LineSubdivisionFace>(DataField.Face); //FeatureStub[] sections = editDeserializer.ReadFeatureStubArray(DataField.Result); if (editDeserializer.IsNextField(DataField.OtherSide)) { InternalIdValue id = editDeserializer.ReadInternalId(DataField.OtherSide); OtherSide = (LineSubdivisionOperation)editDeserializer.MapModel.FindOperation(id); Debug.Assert(OtherSide != null); OtherSide.OtherSide = this; } Project p = editDeserializer.Project; IEntity pointType = editDeserializer.ReadEntity(DataField.PointType); FeatureStub[] sections = CreateStubs(p, pointType, m_Line.EntityType); DeserializationFactory result = new DeserializationFactory(this, sections); ProcessFeatures(result); // Apply any IDs if (editDeserializer.IsNextField(DataField.Ids)) { editDeserializer.ReadIdMappings(DataField.Ids); } }
/// <summary> /// Attempts to calculate the position of the intersect, using the currently /// entered information. /// </summary> /// <returns>The position of the intersect (null if there isn't one)</returns> internal override IPosition CalculateIntersect() { Direction dir = getDirection.Direction; if (dir == null) { return(null); } LineFeature line = getLine.Line; if (line == null) { return(null); } // The closest point may be null if the finish page has never been shown PointFeature closeTo = intersectInfo.ClosestPoint; IPosition xsect; PointFeature closest; dir.Intersect(line, closeTo, out xsect, out closest); return(xsect); /* * * // If we got an intersection, and we did not previously have * // a close-to point, define that now. * if (ok && !m_pCloseTo) * { * m_pCloseTo = pClosest; * ShowCloseTo(); * } */ }
Image GetImage(Operation op, LineFeature line) { // If the creating op can't be updated, use a no-entry sign. if (!(op is IRevisable)) { return(smallImageList.Images["NoEntry"]); } // If the line is not a circular curve, use the line icon. ArcFeature arc = (line as ArcFeature); if (arc == null) { return(smallImageList.Images["Line"]); } // This leaves us with either a circle, or gray circle. if (arc.Circle.Creator == op) { return(smallImageList.Images["Circle"]); } else { return(smallImageList.Images["GrayCircle"]); } }
/// <summary> /// Attempts to locate a superseded (inactive) line that was the parent of /// a specific line. /// </summary> /// <param name="line">The line of interest</param> /// <returns>The superseded line that the line of interest was derived from. Null if /// this edit did not create the line of interest.</returns> internal override LineFeature GetPredecessor(LineFeature line) { // No predecessors (for same reason that DeletionOperation does // not return predecessors)? Not sure about this. return(null); }
/// <summary> /// Checks if an object is acceptable for trimming. /// </summary> /// <param name="thing">The candidate object.</param> /// <returns>The supplied candidate, cast to a line (given that the candidate is /// suitable for trimming). Null if the candidate is not a line, or not suitable /// for trimming.</returns> static LineFeature PreCheck(ISpatialObject thing) { // It has no be a line LineFeature line = (thing as LineFeature); if (line == null) { return(null); } // It has to be topological Topology t = line.Topology; if (t == null) { return(null); } // The line should have system-defined topological line // sections (if it doesn't that would mean that the complete // line dangles). SectionTopologyList sectionList = (t as SectionTopologyList); if (sectionList == null) { return(null); } if (sectionList.CanTrim()) { return(line); } return(null); }
/// <summary> /// Initializes a new instance of the <see cref="NewLineOperation"/> class /// using the data read from persistent storage. /// </summary> /// <param name="editDeserializer">The mechanism for reading back content.</param> protected NewLineOperation(EditDeserializer editDeserializer) : base(editDeserializer) { // Bit of a hack - does NewCircleOperation actually need to extend NewLineOperation? if (!(this is NewCircleOperation) && !(this is NewArcOperation)) m_NewLine = editDeserializer.ReadPersistent<LineFeature>(DataField.Line); }
/// <summary> /// Initializes a new instance of the <see cref="LineSubdivisionOperation"/> class /// using the data read from persistent storage. /// </summary> /// <param name="editDeserializer">The mechanism for reading back content.</param> internal LineSubdivisionOperation(EditDeserializer editDeserializer) : base(editDeserializer) { m_Line = editDeserializer.ReadFeatureRef<LineFeature>(DataField.Line); m_Face = editDeserializer.ReadPersistent<LineSubdivisionFace>(DataField.Face); //FeatureStub[] sections = editDeserializer.ReadFeatureStubArray(DataField.Result); if (editDeserializer.IsNextField(DataField.OtherSide)) { InternalIdValue id = editDeserializer.ReadInternalId(DataField.OtherSide); OtherSide = (LineSubdivisionOperation)editDeserializer.MapModel.FindOperation(id); Debug.Assert(OtherSide != null); OtherSide.OtherSide = this; } Project p = editDeserializer.Project; IEntity pointType = editDeserializer.ReadEntity(DataField.PointType); FeatureStub[] sections = CreateStubs(p, pointType, m_Line.EntityType); DeserializationFactory result = new DeserializationFactory(this, sections); ProcessFeatures(result); // Apply any IDs if (editDeserializer.IsNextField(DataField.Ids)) editDeserializer.ReadIdMappings(DataField.Ids); }
internal LineSubdivisionControl(LineSubdivisionUI cmd, LineFeature line, Operation recall) { InitializeComponent(); // Remember the command. m_Cmd = cmd; // Remember the line involved & its length (in meters) m_Line = line; m_GroundLength = line.GroundLength.Meters; // No distances so far. m_Distances = null; m_FromStart = true; // If we are recalling a previous operation, grab the observed distances from there (only the primary face) LineSubdivisionOperation op = (recall as LineSubdivisionOperation); if (op != null) { LineFeature[] sections = op.Face.Sections; m_Distances = new List <Distance>(sections.Length); foreach (LineFeature s in sections) { m_Distances.Add(new Distance(s.ObservedLength)); } } }
/// <summary> /// Displays info about any previous incarnations of the feature /// currently selected for update. /// </summary> internal void Predecessors() { // Return if there is no predecessor. LineFeature prevLine = GetPredecessor(m_SelectedFeature); if (prevLine == null) { return; } // Get a list of all the predecessor lines List <LineFeature> prev = new List <LineFeature>(); while (prevLine != null) { prev.Add(prevLine); prevLine = prevLine.GetPredecessor(); } // Display list of the edits using (PickPredecessorForm dial = new PickPredecessorForm(prev.ToArray(), true)) { if (dial.ShowDialog() == DialogResult.OK) { Run(dial.SelectedLine); } } }
private void PickPredecessorForm_Shown(object sender, EventArgs e) { grid.RowCount = m_Lines.Length; for (int i = 0; i < m_Lines.Length; i++) { LineFeature line = m_Lines[i]; Operation op = line.Creator; DataGridViewRow row = grid.Rows[i]; row.Tag = line; row.Cells["imageColumn"].Value = GetImage(op, line); row.Cells["opIdColumn"].Value = op.InternalId; row.Cells["operationColumn"].Value = op.Name; row.Cells["createdColumn"].Value = op.Session.StartTime.ToShortDateString(); row.Cells["editorColumn"].Value = op.Session.User; // If the line was created by a connection path, display the precision. if (op is PathOperation) { PathOperation path = (PathOperation)op; row.Cells["precisionColumn"].Value = path.GetPrecision(); } } grid.CurrentCell = null; }
/// <summary> /// Creates a new <c>Topology</c> that relates to the specified line. /// </summary> /// <param name="line">The line the topology relates to (not null)</param> internal Topology(LineFeature line) { if (line==null) throw new ArgumentNullException(); m_Line = line; }
internal void Resolve(CadastralMapModel model) { IFeatureRef fr = m_LineRef.ReferenceFrom; Debug.Assert(fr is Operation); Feature f = model.Find <Feature>(m_LineRef.InternalId); if (f == null) { throw new ApplicationException("Cannot locate forward reference " + m_LineRef.InternalId); } // Only IntersectDirectionAndLineOperation has forward splits, so follow that logic LineFeature line = (LineFeature)f; var dff = new DeserializationFactory(fr as Operation); dff.AddLineSplit(line, DataField.SplitBefore, m_SplitBeforeId); dff.AddLineSplit(line, DataField.SplitAfter, m_SplitAfterId); IntersectOperation xop = (IntersectOperation)fr; LineFeature lineBefore, lineAfter; dff.MakeSections(line, DataField.SplitBefore, xop.IntersectionPoint, DataField.SplitAfter, out lineBefore, out lineAfter); }
/// <summary> /// Initializes a new instance of the <see cref="SimpleLineSubdivisionOperation"/> class /// </summary> /// <param name="splitLine">The line to split.</param> /// <param name="dist">The distance to the split point.</param> /// <param name="isFromEnd">Is the distance observed from the end of the line?</param> internal SimpleLineSubdivisionOperation(LineFeature splitLine, Distance dist, bool isFromEnd) : base() { m_Line = splitLine; m_Distance = dist; m_IsFromEnd = isFromEnd; }
/* * * // * // @parm AutoCad entity. * // @parm Cross-reference of CED entity types to AutoCad layers. * // @parm The style for the annotations. * // @parm The point involved. * // * // @rdesc TRUE if annotation was written. * LOGICAL CeAutoCad::ExportAngles ( const AD_DB_HANDLE DwgHandle * , AD_VMADDR pEntityList * , PAD_ENT_HDR pEntityHeader * , PAD_ENT pEntity * , CacadLayerEntitySet* pLESet * , AD_SHPTB* pStyle * , const CePoint& pt ) const { * * // Skip if there is no AutoCad layer for the specified point * // (the annotations will be going onto the same layer). * AD_OBJHANDLE* pLayerHandle = pLESet->GetpLayerHandle(&pt, * m_ContinuousLineTypeHandle,TRUE); * if ( !pLayerHandle ) return FALSE; * * // Get the point to create a set of miscellaneous text * // objects. * CPtrList text; * UINT4 nAngle = pt.CreateAngleText(text,FALSE); * if ( nAngle==0 ) return FALSE; * * // Export each item of text (deleting each item as we go). * POSITION pos = text.GetHeadPosition(); * while ( pos ) { * CeMiscText* pText = (CeMiscText*)text.GetNext(pos); * * // What's the actual text string? * CString text; * pText->GetText(text); * * // If the text position is to the west of the point, * // align it on the right. * FLOAT8 xt = pText->GetEasting(); * FLOAT8 yt = pText->GetNorthing(); * INT4 halign = AD_TEXT_JUST_LEFT; * * // Take special care with vertical text (allow up to 1mm * // of roundoff). * if ( (xt+0.001) < pt.GetEasting() ) halign = AD_TEXT_JUST_RIGHT; * * // Pull out values for function call below. * CeVertex posn(xt,yt); * FLOAT8 grheight = pText->GetHeight(); * FLOAT8 rotation = pText->GetRotation(); * * CacadText AcadText(DwgHandle,pEntityList,pEntityHeader,pEntity); * AcadText.ExportAngleDistText(pStyle,pLayerHandle,pText,text,posn * ,grheight,rotation * ,halign,AD_TEXT_VALIGN_MIDDLE); * * delete pText; * } * * // Ensure pointer to the text have been removed too. * text.RemoveAll(); * * return TRUE; */ bool WriteLine(ISpatialObject item) { LineFeature line = (LineFeature)item; WriteLineGeometry(line.LineGeometry); return(true); }
/// <summary> /// Performs the data processing associated with this face. /// </summary> /// <param name="parentLine">The line that is being subdivided</param> /// <param name="ctx">The context in which the geometry is being calculated.</param> internal void CalculateGeometry(LineFeature parentLine, EditingContext ctx) { // Get adjusted lengths for each section double[] adjray = GetAdjustedLengths(parentLine, m_Distances); double edist = 0.0; // Distance to end of section. PointFeature start = parentLine.StartPoint; LineGeometry lineGeom = parentLine.LineGeometry; for (int i = 0; i < adjray.Length; i++) { // Calculate the position at the end of the span edist += adjray[i]; IPosition to; if (!lineGeom.GetPosition(new Length(edist), out to)) { throw new Exception("Cannot adjust line section"); } // Get the point feature at the end of the span LineFeature line = m_Sections[i]; PointFeature end = line.EndPoint; // Assign the calculated position so long as we're not at // the end of the line if (end != parentLine.EndPoint) { end.ApplyPointGeometry(ctx, PointGeometry.Create(to)); } // The end of the current span is the start of the next one start = end; } }
/// <summary> /// Reacts to the selection of a line feature. /// </summary> /// <param name="line">The line (if any) that has been selected.</param> internal override void OnSelectLine(LineFeature line) { if (getDirection.Visible) { getDirection.OnSelectLine(line); } }
/// <summary> /// Calculates positions that are parallel to a line. /// </summary> /// <param name="line">The reference line.</param> /// <param name="offset">The observed offset (either a <c>Distance</c> or an <c>OffsetPoint</c>).</param> /// <param name="sres">The position of the start of the parallel.</param> /// <param name="eres">The position of the end of the parallel.</param> /// <returns>True if positions calculated ok</returns> internal static bool Calculate(LineFeature line, Observation offset, out IPosition sres, out IPosition eres) { sres = eres = null; // Can't calculate if there is insufficient data. if (line == null || offset == null) { return(false); } // Is it an observed distance? Distance dist = (offset as Distance); if (dist != null) { return(ParallelLineUI.Calculate(line, dist, out sres, out eres)); } // The only other thing it could be is an offset point. OffsetPoint offPoint = (offset as OffsetPoint); if (offPoint != null) { PointFeature point = offPoint.Point; return(ParallelLineUI.Calculate(line, point, out sres, out eres)); } MessageBox.Show("ParallelLineUI.Calculate - Unexpected sort of observation"); return(false); }
internal override void MouseMove(IPosition p) { // The following is pretty much the same as what the controller would do to // cover auto-select... // The ground tolerance is 1mm at the draw scale. ISpatialDisplay draw = ActiveDisplay; ILength tol = new Length(0.001 * draw.MapScale); // Just return if we previously selected something, and the // search point lies within tolerance. if (m_Line != null) { ILength dist = m_Line.Distance(p); if (dist.Meters < tol.Meters) { return; } // Ensure the previously select line gets un-highlighted m_Line = null; ErasePainting(); } // Ask the map to find the closest line (if any) ISpatialIndex index = CadastralMapModel.Current.Index; m_Line = (index.QueryClosest(p, tol, SpatialType.Line) as LineFeature); Highlight(m_Line); }
/// <summary> /// Displays info for a specific line. /// </summary> /// <param name="line">The selected line.</param> /// <param name="wantsplit">True if the line should be split.</param> void ShowLine(LineFeature line, bool wantsplit) { // Define the selected line and whether it should be split. OnSelectLine(line); SetWantSplit(wantsplit); }
/// <summary> /// Reacts to the selection of a line feature. /// </summary> /// <param name="line">The line (if any) that has been selected.</param> internal override void OnSelectLine(LineFeature line) { if (m_Dialog != null) { m_Dialog.OnSelectLine(line); } }
/// <summary> /// Creates a new <c>SetTopologyUI</c> /// </summary> /// <param name="action">The action that initiated this command</param> /// <param name="line">The line to change topological status (not null)</param> internal SetTopologyUI(IUserAction action, LineFeature line) : base(action) { if (line==null) throw new ArgumentNullException(); m_Line = line; }
public GetLineControl() { InitializeComponent(); m_Line = null; m_WantSplit = 0; m_LineColor = Color.Magenta; }
internal TerminalControl(ParallelLineUI cmd, bool isLast) { InitializeComponent(); m_Cmd = cmd; m_IsLast = isLast; m_Line = null; m_Terminal = null; }
/// <summary> /// Initializes a new instance of the <see cref="SetTopologyOperation"/> class. /// </summary> /// <param name="line">The line that needs to be changed.</param> internal SetTopologyOperation(LineFeature line) : base() { if (line == null) throw new ArgumentNullException(); m_Line = line; m_Topological = !line.IsTopological; }
/// <summary> /// Constructor for a new line subdivision. /// </summary> /// <param name="cc">The container for any dialogs</param> /// <param name="action">The action that initiated this command</param> /// <exception cref="InvalidOperationException">If a specific line is not currently selected</exception> internal LineSubdivisionUI(IControlContainer cc, IUserAction action) : base(cc, action) { LineFeature selLine = EditingController.SelectedLine; if (selLine == null) throw new InvalidOperationException("You must initially select the line you want to subdivide."); m_Parent = selLine; }
internal TerminalControl(UpdateUI updcmd, bool isLast) { InitializeComponent(); m_Cmd = updcmd; m_IsLast = isLast; m_Line = null; m_Terminal = null; }
/// <summary> /// Constructor for doing an update. /// </summary> /// <param name="editId">The ID of the edit this command deals with.</param> /// <param name="updcmd">The update command.</param> internal LineSubdivisionUI(IControlContainer cc, EditingActionId editId, UpdateUI updcmd) : base(cc, editId, updcmd) { // The dialog will be created by Run() m_Dialog = null; m_UpDial = null; // The line being subdivided is known via the update. m_Parent = null; }
/// <summary> /// Initializes a new instance of the <see cref="AttachPointOperation"/> class. /// </summary> /// <param name="line">The line the point should appear on.</param> /// <param name="positionRatio">The position ratio of the attached point. A point coincident with the start /// of the line is a value of 0. A point at the end of the line is a value of /// 1 billion (1,000,000,000).</param> internal AttachPointOperation(LineFeature line, uint positionRatio) : base() { if (line == null) throw new ArgumentNullException(); m_Line = line; m_PositionRatio = positionRatio; m_Point = null; }
/// <summary> /// Constructor to subdivide the currently selected line. /// </summary> /// <param name="cc">The container for any dialogs</param> /// <param name="action">The action that initiated this command</param> internal SimpleLineSubdivisionUI(IControlContainer cc, IUserAction action) : base(cc, action) { LineFeature line = EditingController.SelectedLine; if (line == null) throw new InvalidOperationException("You must initially select the line you want to subdivide."); SetInitialValues(); m_Line = line; }
/// <summary> /// Initializes a new instance of the <see cref="LineExtensionOperation"/> class /// </summary> /// <param name="extendLine">The line that's being extended.</param> /// <param name="isFromEnd">True if extending from the end | False from the start.</param> /// <param name="length">The length of the extension.</param> internal LineExtensionOperation(LineFeature extendLine, bool isFromEnd, Distance length) : base() { m_ExtendLine = extendLine; m_IsExtendFromEnd = isFromEnd; m_Length = length; m_NewLine = null; m_NewPoint = null; }
internal LineExtensionControl(LineExtensionUI cmd, LineFeature extendLine, Operation recall) { InitializeComponent(); Zero(); m_Cmd = cmd; m_ExtendLine = extendLine; LineExtensionOperation op = (recall as LineExtensionOperation); if (op!=null) { m_IsExtendFromEnd = op.IsExtendFromEnd; m_Length = new Distance(op.Length); m_WantLine = (op.NewLine!=null); } }
/// <summary> /// Constructor to extend the currently selected line. /// </summary> /// <param name="cc">The container for any dialogs</param> /// <param name="action">The action that initiated this command</param> /// <exception cref="InvalidOperationException">If a line is not currently selected</exception> internal LineExtensionUI(IControlContainer cc, IUserAction action) : base(cc, action) { LineFeature line = EditingController.SelectedLine; if (line == null) throw new InvalidOperationException("You must initially select the line you want to extend."); // The dialog will be created by Run(). m_Dialog = null; // Remember the line that is being extended. m_ExtendLine = line; // And initialize the parameters for the operation's Execute() call. m_Length = null; m_IsExtendFromEnd = true; m_LineType = null; }
/// <summary> /// Tries to find a terminal line to end the parallel on. /// </summary> /// <returns>False if parallel positions are not available. True /// otherwise (that does not mean that a terminal was actually found). /// </returns> bool FindTerminal() { // Get the position of the parallel point. ParallelLineUI cmd = this.Command; IPosition parpos; if (m_IsLast) parpos = cmd.ParallelTwo; else parpos = cmd.ParallelOne; // The parallel point HAS to be known. if (parpos==null) { MessageBox.Show("Parallel point has not been calculated"); return false; } // Treat the parallel point as the initial terminal. m_Terminal = parpos; // Get the offset to the parallel. double offset = cmd.GetPlanarOffset(); // Figure out a search radius (the smaller of half the offset, // or half a centimetre at the current draw scale). double scale = cmd.ActiveDisplay.MapScale; ILength tol = new Length(Math.Min(offset*0.5, scale*0.005)); // Search for the line closest to the parallel point, and // within the search radius. The line has to be visible // and selectable. CadastralMapModel map = CadastralMapModel.Current; //m_Line = map.FindClosestLine(parpos, tol, true); m_Line = (map.Index.QueryClosest(parpos, tol, SpatialType.Line) as LineFeature); // If we found something, highlight it (after confirming that // it really does intersect the parallel). if (m_Line!=null) { IPosition xsect = cmd.GetIntersect(m_Line, m_IsLast); if (xsect==null) m_Line = null; else { //pView->UnHighlight(m_pArc); //pView->Highlight(*m_pArc); m_Terminal = xsect; } } return true; }
int InitUpdate() { // Get the creating op. ParallelLineOperation op = UpdateOp; if (op==null) return 0; ISpatialDisplay view = m_Cmd.ActiveDisplay; ParallelLineUI cmd = Command; // The originally produced parallel may have been // changed to have a different offset. // Get the line that the parallel originally terminated on (if any). if (m_IsLast) m_Line = op.Terminal2; else m_Line = op.Terminal1; // If we didn't terminate on any particular line, that's // the way it will remain, Otherwise confirm that the // parallel continues to intersect it. In the event that // the parallel no longer intersects, get another // terminal position (and maybe a different terminal line). if (m_Line != null) { m_Terminal = cmd.GetIntersect(m_Line, m_IsLast); if (m_Terminal != null) { // The parallel still intersects the terminal line that was originally specified, // so highlight the terminal line (having de-selected and unhighlighted // anything that was previously highlighted). m_Line.Render(view, new HighlightStyle()); } else { // Get a new terminal position (preferably coincident with some other line). // DON'T try to find a new terminal if the op is being corrected due to a // problem in rollforward preview. In that case, we want the user to see // where the old terminal was ... well, leave that nicety for now. if (!FindTerminal()) return -1; } } else { // Parallel did not terminate on a line, so grab the start or end of the parallel line LineFeature parLine = op.ParallelLine; if (m_IsLast) m_Terminal = parLine.EndPoint; else m_Terminal = parLine.StartPoint; } return 1; }
internal void OnSelectLine(LineFeature line) { // Return if line is not defined. if (line==null) return; // If the focus is in the backsight field, and the selected // line connects to the from-point, define the backsight to // be the point at the other end of the line. if (m_From==null || m_Focus!=backsightTextBox) return; PointFeature point = null; if (m_From.IsCoincident(line.StartPoint)) point = line.EndPoint; else if (m_From.IsCoincident(line.EndPoint)) point = line.StartPoint; // Return if a connected point cannot be found. if (point==null) { MessageBox.Show("Cannot locate backsight point."); return; } OnSelectPoint(point); }
/// <summary> /// Reacts to the selection of a line feature. /// </summary> /// <param name="line">The line (if any) that has been selected.</param> internal void SelectLine(LineFeature line) { ISpatialDisplay view = m_Cmd.ActiveDisplay; IPosition xsect = null; ParallelLineUI cmd = Command; // Confirm that the line actually intersects the parallel. if (line!=null) { xsect = cmd.GetIntersect(line, m_IsLast); if (xsect==null) { MessageBox.Show("Selected line does not intersect the parallel"); // De-select the line the user picked EditingController.Current.ClearSelection(); // Re-highlight the arc if had originally (if any). if (m_Line!=null) EditingController.Current.Select(m_Line); return; } } // Ensure everything is erased. m_Cmd.ErasePainting(); // Hold on to new terminal position. if (xsect!=null) m_Terminal = xsect; else if (m_IsLast) m_Terminal = cmd.ParallelTwo; else m_Terminal = cmd.ParallelOne; // If we previously had an arc selected (and it's not the // newly selected line), ensure that it's been unhighlighted. //if (m_pArc && m_pArc != pArc) m_pArc->UnHighlight(); // Hold on to the new terminal arc (if any). m_Line = line; // If it's defined, ensure the "don't use terminal" check // box is clear. And change the static text that tells the // user what to do. if (m_Line!=null) { noTerminalCheckBox.Checked = false; messageLabel2.Text = "If you want to terminate on a different line, select it."; } // Ensure everything is drawn as expected. cmd.Draw(); // Resume focus on the Next/Finish button. okButton.Focus(); }
/// <summary> /// Attempts to locate a superseded (inactive) line that was the parent of /// a specific line. /// </summary> /// <param name="line">The line of interest</param> /// <returns>The superseded line that the line of interest was derived from. Null if /// this edit did not create the line of interest.</returns> internal override LineFeature GetPredecessor(LineFeature line) { // This edit doesn't supersede anything return null; }
/// <summary> /// Calculates the start and end positions of a straight line extension. /// </summary> /// <param name="extendLine">The line being extended.</param> /// <param name="isFromEnd">True if extending from the end of the line.</param> /// <param name="dist">The length of the extension.</param> /// <param name="start">The position of the start of the extension.</param> /// <param name="end">The position of the end of the extension.</param> /// <returns>True if position have been worked out. False if there is insufficient data, /// or the extension is not straight (in that case, the start and end positions come /// back as nulls)</returns> internal static bool Calculate(LineFeature extendLine, bool isFromEnd, Distance dist, out IPosition start, out IPosition end) { start = end = null; // Can't calculate if there is insufficient data. if (extendLine==null || dist==null) return false; // The length must be defined. if (!dist.IsDefined) return false; // The line that's being extended can't be a circular arc. if (extendLine is ArcFeature) return false; // Get the point we're extending from. start = (isFromEnd ? extendLine.EndPoint : extendLine.StartPoint); // Get the point we're extending to ... // Get the orientation point. For multi-segments, we use the // point prior to the appropriate end point. IPosition orient = extendLine.LineGeometry.GetOrient(!isFromEnd, 0.0); // Get the bearing from the orientation point to the start of the extension. Turn turn = new Turn(orient, start); double bearing = turn.BearingInRadians; // Get the distance on the mapping plane. double plandist = dist.GetPlanarMetric(start, bearing, extendLine.SpatialSystem); // Figure out the end of the extension. end = Geom.Polar(start, bearing, plandist); return true; }
/// <summary> /// Calculates the start and end positions of an extension to a circular arc. /// </summary> /// <param name="extendLine">The line being extended.</param> /// <param name="isFromEnd">True if extending from the end of the line.</param> /// <param name="dist">The length of the extension.</param> /// <param name="start">The position of the start of the extension.</param> /// <param name="end">The position of the end of the extension.</param> /// <param name="center">The center of the circle on which the arc lies.</param> /// <param name="iscw">Is the circular arc directed clockwise?</param> /// <returns>True if position have been worked out. False if there is insufficient data, /// or the extension is not on a circular arc, or the length is more than the circumference /// of the circle (in those cases, the start and end positions come back as nulls)</returns> internal static bool Calculate(LineFeature extendLine, bool isFromEnd, Distance dist, out IPosition start, out IPosition end, out IPosition center, out bool iscw) { start = end = null; center = null; iscw = true; // Can't calculate if there is insufficient data. if (extendLine==null || dist==null) return false; // The length must be defined. if (!dist.IsDefined) return false; // The line that's being extended must be a circular arc. ArcFeature arc = (extendLine as ArcFeature); if (arc==null) return false; center = arc.Circle.Center; double radius = arc.Circle.Radius; iscw = arc.IsClockwise; // Get the length of the arc extension, in meters on the ground. double arclen = dist.Meters; // If the arc length exceeds the length of the circumference, // the end point can't be calculated. double circumf = Constants.PIMUL2 * radius; if (arclen > circumf) return false; // If we're extending from the start of the arc, the curve direction has // to be reversed too. if (!isFromEnd) iscw = !iscw; // Get the point we're extending from. start = (isFromEnd ? extendLine.EndPoint : extendLine.StartPoint); // Get the point we're extending to ... // Get the bearing from the center of the circle to the start of the arc. Turn turn = new Turn(center, start); double sbearing = turn.BearingInRadians; // Get the sector angle (in radians). double sector = arclen / radius; double ebearing = sbearing; if (iscw) ebearing += sector; else ebearing -= sector; end = Geom.Polar(center, ebearing, radius); // Re-calculate the arc length on the mapping plane, arclen = dist.GetPlanarMetric(start, end, extendLine.SpatialSystem); // And adjust the end position accordingly. sector = arclen / radius; if (iscw) ebearing = sbearing + sector; else ebearing = sbearing - sector; end = Geom.Polar(center, ebearing, radius); return true; }
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(); }
private void noTerminalCheckBox_CheckedChanged(object sender, EventArgs e) { // If we previously had a terminal line, erase the terminal // position and unhighlight the arc. ISpatialDisplay draw = m_Cmd.ActiveDisplay; if (m_Line!=null) m_Cmd.ErasePainting(); m_Line = null; ParallelLineUI cmd = Command; // Draw the parallel point instead. if (m_IsLast) m_Terminal = cmd.ParallelTwo; else m_Terminal = cmd.ParallelOne; EditingController.Current.Style(Color.Yellow).Render(draw, m_Terminal); }
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(); }
private void listBox_SelectedValueChanged(object sender, EventArgs e) { // Get the currently selected line (if any). m_SelectedLine = GetSelectedLine(); // Ensure stuff gets repainted in idle time m_UpdCmd.ErasePainting(); }
/// <summary> /// Constructor for doing an update. /// </summary> /// <param name="editId">The ID of the edit this command deals with.</param> /// <param name="updcmd">The update command.</param> internal LineExtensionUI(IControlContainer cc, EditingActionId editId, UpdateUI updcmd) : base(cc, editId, updcmd) { // The dialog will be created by Run(). m_Dialog = null; // The line we extended is known via the update. m_ExtendLine = null; // And initialize the parameters for the operation's Execute() call. m_Length = null; m_IsExtendFromEnd = true; m_LineType = null; }
internal override void MouseMove(IPosition p) { // The following is pretty much the same as what the controller would do to // cover auto-select... // The ground tolerance is 1mm at the draw scale. ISpatialDisplay draw = ActiveDisplay; ILength tol = new Length(0.001 * draw.MapScale); // Just return if we previously selected something, and the // search point lies within tolerance. if (m_Line!=null) { ILength dist = m_Line.Distance(p); if (dist.Meters < tol.Meters) return; // Ensure the previously select line gets un-highlighted m_Line = null; ErasePainting(); } // Ask the map to find the closest line (if any) ISpatialIndex index = CadastralMapModel.Current.Index; m_Line = (index.QueryClosest(p, tol, SpatialType.Line) as LineFeature); Highlight(m_Line); }