/// <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); } } } } }
/// <summary> /// Inserts this circle into the supplied index. /// </summary> /// <param name="index">The spatial index to add to (should be an instance of /// <see cref="EditingIndex"/>)</param> internal void AddToIndex(IEditSpatialIndex index) { EditingIndex cx = (index as EditingIndex); Debug.Assert(cx != null); cx.AddCircle(this); }
/// <summary> /// Displays database attributes so that they can be edited by the user. /// </summary> /// <param name="r">The row of interest</param> /// <returns>True if any changes were saved to the database</returns> internal static bool Update(Row r) { // If the row is associated with any RowText, ensure it is removed from // the spatial index NOW (if we wait until the edit has been completed, // it's possible we won't be able to update the index properly) TextFeature[] text = r.Id.GetRowText(); EditingIndex index = CadastralMapModel.Current.EditingIndex; bool isChanged = false; try { // Remove the text from the spatial index (but see comment below) foreach (TextFeature tf in text) { index.RemoveFeature(tf); } // Display the attribute entry dialog AttributeDataForm dial = new AttributeDataForm(r.Table, r.Data); isChanged = (dial.ShowDialog() == DialogResult.OK); dial.Dispose(); if (isChanged) { IDataServer ds = EditingController.Current.DataServer; if (ds == null) { throw new InvalidOperationException("No database available"); } ds.SaveRow(r.Data); } } finally { // Ensure text has been re-indexed... actually, this is likely to be // redundant, because nothing here has actually altered the stored // width and height of the text (if the attributes have become more // verbose, they'll just be scrunched up a bit tighter). The text // metrics probably should be reworked (kind of like AutoSize for // Windows labels), but I'm not sure whether this demands a formal // editing operation. foreach (TextFeature tf in text) { index.AddFeature(tf); } // Re-display the text if any changes have been saved if (isChanged) { ISpatialDisplay display = EditingController.Current.ActiveDisplay; display.Redraw(); } } return(isChanged); }
Ring BuildSide(IDivider d, Window bwin, EditingIndex index, bool isLeft) { List<Face> edge = GetPolygonFaces(d, isLeft); Ring result = Ring.Create(edge); bwin.Union(result.Extent); result.AddToIndex(index); return result; }
/// <summary> /// Adds this feature to the spatial index, and sets the flag bit indicating /// that this feature is indexed. /// </summary> internal void AddToIndex() { EditingIndex index = MapModel.EditingIndex; if (index != null) { index.AddFeature(this); } }
/// <summary> /// Changes the text for this object /// </summary> /// <param name="s">The new value for this geometry</param> internal void SetText(TextFeature label, string s) { CadastralMapModel map = label.MapModel; EditingIndex index = map.EditingIndex; index.RemoveFeature(label); m_Text = s; index.AddFeature(label); }
/// <summary> /// Inserts this feature into the supplied index. This should be called shortly after a model /// is opened (after a prior call to <c>OnLoad</c>). /// </summary> /// <param name="index">The spatial index to add to</param> /// <returns>True if the feature was indexed. False if the feature is currently inactive (not /// added to the index)</returns> /// <remarks>The <see cref="LineFeature"/> class provides an override that also deals with /// indexing for topological elements.</remarks> internal virtual bool AddToIndex(EditingIndex index) { if (IsInactive) { return(false); } index.AddFeature(this); return(true); }
/// <summary> /// Records this circle as part of the spatial index in the current map model. /// </summary> internal void AddToIndex() { EditingIndex index = CadastralMapModel.Current.EditingIndex; if (index != null && !this.IsIndexed) { index.AddCircle(this); this.IsIndexed = true; } }
/// <summary> /// Performs any processing that needs to be done just before the position of /// a referenced feature is changed. /// </summary> /// <param name="f">The feature that is about to be moved - something that /// the <c>IFeatureDependent</c> is dependent on (not null).</param> /// <param name="ctx">The context in which the move is being made (not null).</param> public void OnFeatureMoving(Feature f, UpdateEditingContext ctx) { EditingIndex index = f.MapModel.EditingIndex; if (index != null && this.IsIndexed) { index.RemoveCircle(this); this.IsIndexed = false; } }
/// <summary> /// Creates a new <c>FindCirclesQuery</c> (and executes it). The result of the query /// can then be obtained through the <c>Result</c> property. /// </summary> /// <param name="index">The spatial index to search</param> /// <param name="p">The search position.</param> /// <param name="tol">The search tolerance (expected to be greater than zero).</param> internal FindCirclesQuery(EditingIndex index, IPosition p, ILength tol) { m_Position = p; m_Tolerance = tol.Meters; m_Result = new List<Circle>(); // The query will actually involve a square window, not a circle. IWindow x = new Window(p, m_Tolerance * 2.0); index.FindCircles(x, OnQueryHit); }
/// <summary> /// Inserts neighbouring polygons into the supplied index (if they are not already /// marked as indexed). This should be called shortly after a model is opened (after /// a prior call to <c>OnLoad</c>). /// </summary> /// <param name="d">The divider to process</param> /// <param name="index">The spatial index to add to</param> internal static void AddToIndex(IDivider d, EditingIndex index) { if (d.Left!=null) d.Left.AddToIndex(index); if (d.Right!=null) d.Right.AddToIndex(index); AddToIndex(d.From, index); AddToIndex(d.To, index); }
/// <summary> /// Creates a new <c>FindCirclesQuery</c> (and executes it). The result of the query /// can then be obtained through the <c>Result</c> property. /// </summary> /// <param name="index">The spatial index to search</param> /// <param name="p">The search position.</param> /// <param name="tol">The search tolerance (expected to be greater than zero).</param> internal FindCirclesQuery(EditingIndex index, IPosition p, ILength tol) { m_Position = p; m_Tolerance = tol.Meters; m_Result = new List <Circle>(); // The query will actually involve a square window, not a circle. IWindow x = new Window(p, m_Tolerance * 2.0); index.FindCircles(x, OnQueryHit); }
/// <summary> /// Inserts this polygon into the supplied index, so long as it's not already /// marked as indexed. Then marks it as indexed. /// </summary> /// <param name="index">The spatial index to add to</param> /// <returns>True if entry added to index. False if this ring is already marked /// as indexed.</returns> internal bool AddToIndex(EditingIndex index) { if (IsIndexed) { return(false); } index.Add(this); IsIndexed = true; return(true); }
/// <summary> /// Removes the features created by this edit from the model's spatial index. /// </summary> internal void RemoveFromIndex() { EditingIndex index = this.MapModel.EditingIndex; Feature[] fa = this.Features; foreach (Feature f in fa) { index.RemoveFeature(f); } }
/// <summary> /// Adds the features created by this edit to the model's spatial index. /// </summary> internal void AddToIndex() { EditingIndex index = this.MapModel.EditingIndex; Feature[] fa = this.Features; foreach (Feature f in fa) { index.AddFeature(f); } }
/// <summary> /// Removes spatial indexing for this feature, and clears the flag bit indicating /// that this feature is indexed. /// </summary> internal void RemoveIndex() { // The spatial index may be null while data is being deserialized from the // database during application startup EditingIndex index = MapModel.EditingIndex; if (index != null) { index.RemoveFeature(this); } }
/// <summary> /// Ensures that the polygon topology for this line has been completely defined. /// This implementation is suitable only for overlapping dividers, since it does nothing. /// </summary> /// <param name="bwin">The window of any new polygons that got created. This /// window is not initialized here. It just gets expanded.</param> /// <param name="index">The spatial index to include any newly built polygons.</param> internal void BuildPolygons(Window bwin, EditingIndex index) { foreach (IDivider d in this) { if (!d.IsOverlap) { if (d.Left==null) d.Left = BuildSide(d, bwin, index, true); if (d.Right==null) d.Right = BuildSide(d, bwin, index, false); } } }
/// <summary> /// Deactivates this feature. /// </summary> /// <remarks>This method is currently called when the model is getting loaded from /// the database, and it hits a DeletionOperation. I'm not sure whether it should /// be called during a "live" DeletionOperation</remarks> internal virtual void Deactivate() { IsInactive = true; IsMoved = false; SetBuilt(false); // Remove from spatial index EditingIndex index = m_Creator.MapModel.EditingIndex; if (index != null) { index.RemoveFeature(this); } // In the case of lines, this will first call the override that gets // rid of any topological attachments Clean(); }
/// <summary> /// Creates a new <c>CleanupQuery</c> and executes it. /// </summary> /// <param name="model">The model to clean</param> internal CleanupQuery(CadastralMapModel model) { if (model == null) { throw new ArgumentNullException(); } m_Model = model; m_UpdateWindow = new Window(); m_Deletions = new List <ISpatialObject>(100); m_Moves = new List <Feature>(100); // Cleanup features model.Index.QueryWindow(null, SpatialType.Feature, CleanupFeature); // Cleanup polygons model.Index.QueryWindow(null, SpatialType.Polygon, CleanupPolygon); // Remove stuff from spatial index if it's been deleted EditingIndex index = model.EditingIndex; foreach (ISpatialObject o in m_Deletions) { m_UpdateWindow.Union(o.Extent); if (o is Feature) { index.RemoveFeature((Feature)o); } else if (o is Ring) { index.Remove(o); } else { throw new ApplicationException("Unexpected data type: " + o.GetType().Name); } } }
/// <summary> /// Creates a new <c>PolygonBuilder</c> for the supplied model. Make a subsequent /// call to <c>Build</c> to create polygons. /// </summary> /// <param name="model">The model the polygons should be created within.</param> internal PolygonBuilder(CadastralMapModel model) { m_Model = model; m_NewPolygonExtent = new Window(); m_Index = model.EditingIndex; }
/// <summary> /// Ensures the terminal at one end of a divider has been indexed. /// </summary> /// <param name="t">The terminal at the start or end of a divider</param> /// <param name="cx">The spatial index to add to</param> static void AddToIndex(ITerminal t, EditingIndex cx) { Intersection x = (t as Intersection); if (x!=null && !x.IsIndexed) cx.AddIntersection(x); }
/// <summary> /// Ensures that the polygon topology for this line has been completely defined. /// </summary> /// <param name="bwin">The window of any new polygons that got created. This /// window is not initialized here. It just gets expanded.</param> /// <param name="index">The spatial index to include any newly built polygons.</param> internal void BuildPolygons(Window bwin, EditingIndex index) { if (m_Topology==null) { // Inactive topological lines will have null m_Topology // Debug.Assert(!IsTopological); return; } if (m_Topology!=null) m_Topology.BuildPolygons(bwin, index); }
/// <summary> /// Override inserts this line feature into the supplied index, together with any neighbouring /// polygons that have not already been added to the index. This should be called shortly after /// a model is opened (after a prior call to <c>OnLoad</c>). /// </summary> /// <param name="index">The spatial index to add to</param> /// <returns>True if the feature was indexed. False if the feature is currently inactive (not /// added to the index)</returns> internal override bool AddToIndex(EditingIndex index) { // Index this line feature if (!base.AddToIndex(index)) return false; // Index any neighbouring polygons if (m_Topology!=null) { foreach (IDivider d in m_Topology) Topology.AddToIndex(d, index); } return true; }