/// <summary> /// Check if this ID packet refers to a specific feature ID. /// </summary> /// <param name="fid">The feature ID to check for.</param> /// <returns>True if the feature ID was found.</returns> internal bool IsReferredTo(FeatureId fid) { if (fid==null) return false; else return (GetIndex(fid)>=0); }
/// <summary> /// Initializes a new instance of the <see cref="FeatureStub"/> class /// </summary> /// <param name="creator">The editing operation that created the feature.</param> /// <param name="id">The internal ID of the feature within /// the project that created it.</param> /// <param name="ent">The entity type for the feature (not null)</param> /// <param name="fid">The (optional) user-perceived ID for the feature.</param> /// <exception cref="ArgumentNullException">If either <paramref name="ent"/> or /// <paramref name="creator"/> is null.</exception> internal FeatureStub(Operation creator, InternalIdValue id, IEntity ent, FeatureId fid) { if (creator == null || ent == null) throw new ArgumentNullException(); m_Creator = creator; m_InternalId = id; m_What = ent; m_Id = fid; }
/// <summary> /// Restores an ID pointer that this range points to. This confirms that this /// packet really does point to the ID and, if so, the number of free IDs will /// be decremented. /// <para/> /// This function undoes a call to FreeId, and is called when a user-perceived /// deletion is being rolled back. /// </summary> /// <param name="fid">The feature ID to restore.</param> /// <returns>True if ID pointer was found.</returns> /// <remarks>TODO: This method now does nothing, since m_NumFree is no longer /// noted explicitly. Should look into calls. However, the other thing to also /// note is that FreeId is no longer called, so perhaps other things are amiss /// in the undo logic.</remarks> internal bool RestoreId(FeatureId fid) { // TODO: No need to do anything, since m_NumFree is no longer /* // Get the array index of the ID. int index = GetIndex(fid); // Return if not found. if (index < 0) throw new Exception("IdPacket.RestoreId - ID not found"); // Decrement the number of free slots (DON'T accidentally // decrement past zero, because that's a BIG number). if (m_NumFree>0) m_NumFree--; */ return true; }
/// <summary> /// Returns the array index for a specific feature ID. /// </summary> /// <param name="fid">The ID we want the index for.</param> /// <returns>The index value, or -1 if the ID was not found.</returns> int GetIndex(FeatureId fid) { return Array.IndexOf<FeatureId>(m_Ids, fid); }
/// <summary> /// Initializes a new instance of the <see cref="FeatureStub"/> class with the /// next available internal ID. /// </summary> /// <param name="creator">The editing operation that created the feature.</param> /// <param name="ent">The entity type for the feature (not null)</param> /// <param name="fid">The (optional) user-perceived ID for the feature.</param> /// <exception cref="ArgumentNullException">If either <paramref name="ent"/> or /// <paramref name="creator"/> is null.</exception> internal FeatureStub(Operation creator, IEntity ent, FeatureId fid) : this(creator, creator.Session.AllocateNextId(), ent, fid) { }
/// <summary> /// Performs checks for a text label. /// </summary> /// <param name="label">The label to check.</param> /// <returns>The problem(s) that were found.</returns> internal static CheckType CheckLabel(TextFeature label) { CheckType types = CheckType.Null; Polygon p = label.Container; if (p == null) { types |= CheckType.NoPolygonForLabel; } else { // Does the polygon point back? If not, we've got a multi-label. if (p.LabelCount > 1 && p.Label != label) { types |= CheckType.MultiLabel; } } // Does the label have at least one row of attribute data? FeatureId fid = label.FeatureId; if (fid == null || fid.RowCount == 0) { types |= CheckType.NoAttributes; } return(types); }
/// <summary> /// Initializes a new instance of the <see cref="Feature"/> class, and records it /// as part of the map model. /// </summary> /// <param name="creator">The editing operation that created the feature (never null).</param> /// <param name="id">The internal of this feature within the /// project that created it. Specify an internal ID value of 0 for a temporary feature that should not be added /// to the model.</param> /// <param name="entityType">The type of real-world object that the feature corresponds to.</param> /// <param name="featureId">The user-perceived ID (if any) for the feature. This is the ID that /// is used to associate the feature with any miscellaneous attributes /// that may be held in a database.</param> protected Feature(Operation creator, InternalIdValue id, IEntity entityType, FeatureId featureId) { if (creator == null) { throw new ArgumentNullException("Creating operation must be defined"); } if (entityType == null) { throw new ArgumentNullException("Entity type must be defined"); } //if (sessionSequence == 0) // throw new ArgumentException("Session sequence must be defined"); m_Creator = creator; m_InternalId = id; m_What = entityType; m_References = null; m_Flag = 0; // If a user-defined ID is present, ensure it knows about this feature, and vice versa m_Id = featureId; if (m_Id != null) { m_Id.AddReference(this); } // Remember this feature as part of the model if (!m_InternalId.IsEmpty) { m_Creator.MapModel.AddFeature(this); } }
/// <summary> /// Check if this ID packet refers to a specific feature ID. /// </summary> /// <param name="fid">The feature ID to check for.</param> /// <returns>True if the feature ID was found.</returns> internal bool IsReferredTo(FeatureId fid) { if (fid == null) { return(false); } else { return(GetIndex(fid) >= 0); } }
/// <summary> /// Initializes a new instance of the <see cref="FeatureStub"/> class /// that contains a copy of the properties of a feature. /// </summary> /// <param name="f">The feature containing the properties to copy (not null).</param> /// <exception cref="ArgumentNullException">If the supplied feature is null.</exception> internal FeatureStub(IFeature f) { if (f == null) { throw new ArgumentNullException(); } m_Creator = f.Creator; m_InternalId = f.InternalId; m_What = f.EntityType; m_Id = f.FeatureId; }
/// <summary> /// Initializes a new instance of the <see cref="FeatureStub"/> class /// </summary> /// <param name="creator">The editing operation that created the feature.</param> /// <param name="id">The internal ID of the feature within /// the project that created it.</param> /// <param name="ent">The entity type for the feature (not null)</param> /// <param name="fid">The (optional) user-perceived ID for the feature.</param> /// <exception cref="ArgumentNullException">If either <paramref name="ent"/> or /// <paramref name="creator"/> is null.</exception> internal FeatureStub(Operation creator, InternalIdValue id, IEntity ent, FeatureId fid) { if (creator == null || ent == null) { throw new ArgumentNullException(); } m_Creator = creator; m_InternalId = id; m_What = ent; m_Id = fid; }
/// <summary> /// Writes a user-perceived feature ID to a storage medium using the specified naming tags. /// convention. /// </summary> /// <param name="nativeField">The tag to use for a native ID.</param> /// <param name="foreignField">The tag to use for a foreign ID.</param> /// <param name="featureId">The ID to write (if null, nothing will be written)</param> void WriteFeatureId(DataField nativeField, DataField foreignField, FeatureId featureId) { if (featureId != null) { if (featureId is NativeId) { m_Writer.WriteUInt32(nativeField.ToString(), featureId.RawId); } else { m_Writer.WriteString(foreignField.ToString(), featureId.FormattedKey); } } }
/// <summary> /// Initializes a new instance of the <see cref="Row"/> class, /// forming a two-way association with the ID /// </summary> /// <param name="id">The ID for the row (not null). Modified to refer to /// the newly created <c>Row</c> object.</param> /// <param name="table">The definition of the table this row is part of (not null).</param> /// <param name="data">Data for the row (not null).</param> /// <exception cref="ArgumentNullException">If any parameter is null</exception> internal Row(FeatureId id, ITable table, DataRow data) { if (id == null || table == null || data == null) { throw new ArgumentNullException(); } m_Id = id; m_Table = table; m_Data = data; // Relate the ID to this row id.AddReference(this); }
/// <summary> /// Creates a feature ID from this ID handle. In order for this to work, a /// prior call to <c>IdHandle.ReserveId</c> is needed. /// </summary> /// <param name="feature">The feature that should get the created feature ID (currently /// without any defined ID)</param> /// <returns>The created feature ID (if any).</returns> internal FeatureId CreateId(Feature feature) { // Confirm that the feature does not already have an ID. if (feature.FeatureId != null) { throw new ApplicationException("IdHandle.CreateId - Feature already has an ID."); } // Claim the reserved ID and cross reference to the feature FeatureId fid = CreateId(); fid.Add(feature); return(fid); }
/// <summary> /// Restores an ID pointer that this range points to. This confirms that this /// packet really does point to the ID and, if so, the number of free IDs will /// be decremented. /// <para/> /// This function undoes a call to FreeId, and is called when a user-perceived /// deletion is being rolled back. /// </summary> /// <param name="fid">The feature ID to restore.</param> /// <returns>True if ID pointer was found.</returns> /// <remarks>TODO: This method now does nothing, since m_NumFree is no longer /// noted explicitly. Should look into calls. However, the other thing to also /// note is that FreeId is no longer called, so perhaps other things are amiss /// in the undo logic.</remarks> internal bool RestoreId(FeatureId fid) { // TODO: No need to do anything, since m_NumFree is no longer /* * // Get the array index of the ID. * int index = GetIndex(fid); * * // Return if not found. * if (index < 0) * throw new Exception("IdPacket.RestoreId - ID not found"); * * // Decrement the number of free slots (DON'T accidentally * // decrement past zero, because that's a BIG number). * if (m_NumFree>0) * m_NumFree--; */ return(true); }
/// <summary> /// Attaches miscellaneous attribute data to features /// </summary> /// <param name="features">The features to process (those that don't have a feature ID /// will be ignored)</param> /// <returns>The number of rows that were found (-1 if no database tables have /// been associated with Backsight)</returns> internal static int Load(Feature[] features) { List <FeatureId> fids = new List <FeatureId>(features.Length); foreach (Feature f in features) { FeatureId fid = f.FeatureId; if (fid != null) { fids.Add(fid); } } if (fids.Count == 0) { return(0); } else { return(Load(fids.ToArray())); } }
/// <summary> /// Records the feature ID for this feature. /// <para/> /// If a not-null ID is supplied, it will throw an exception if the feature /// already has an ID. To avoid that, the original ID must be successfully /// deleted via a prior call to <c>IdHandle.DeleteId</c>. /// </summary> /// <param name="fid">The ID to remember (may be null).</param> internal void SetId(FeatureId fid) { if (fid != null) { // Throw exception if the feature already has an ID (a // prior call to CeIdHandle::DeleteId should have been made). if (m_Id != null) { throw new InvalidOperationException("Feature.SetId - Attempt to re-define ID"); } // Record the new ID, and remember whether it is regarded as // a foreign ID or not. m_Id = fid; this.IsForeignId = (fid is ForeignId); } else { m_Id = null; this.IsForeignId = false; } }
/// <summary> /// Attaches miscellaneous attribute data to the features that have been loaded. /// </summary> /// <param name="fids">The feature IDs to look for</param> /// <returns>The number of rows that were found (-1 if no database tables have /// been associated with Backsight)</returns> /// <remarks> /// The current Backsight implementation deals primarily with the /// definition of the geometry for spatial features. While it is intended to /// provide basic attribute data entry, the overall design calls for a very /// loose binding. /// <para/> /// To cover this design goal, there are no references to miscellaneous attributes /// in any editing operation. This makes it possible to manipulate the attributes /// using external systems, with minimal concern for the impact it could have /// on Backsight (the only consequence of inadvertant attribute changes is /// that instances of <see cref="RowTextGeometry"/> could be orphaned by /// removing the associated attributes). /// <para/> /// While this simplifies the overall architecture, it is advisable to /// make any attribute data easily available to the user, since that may well /// guide the user regarding the relevance of spatial edits. /// <para/> /// This method will be called after the spatial features for a project have been /// loaded from the database. It takes a very simple-minded approach, by attempting /// to match features with every table associated with Backsight via the /// Environment Editor application (hopefully there aren't TOO many). /// This could potentially be overly time-consuming as part of the loading logic. /// While some of this could be addressed by lazy loading, or perhaps some more /// definitive layer->table associations, there is no proof that there is actually /// an issue that needs solving. Without that proof, it is considered inappropriate /// to code anything more complicated. /// </remarks> internal static int Load(FeatureId[] fids) { // Cross-reference the supplied IDs to their formatted key Dictionary<string, FeatureId> keyIds = new Dictionary<string, FeatureId>(fids.Length); foreach (FeatureId fid in fids) { string key = fid.FormattedKey; FeatureId existingId; if (keyIds.TryGetValue(key, out existingId)) { if (!object.ReferenceEquals(existingId, fid)) throw new Exception("More than one ID object for: "+key); } else { keyIds.Add(key, fid); } } return Load(keyIds); }
/// <summary> /// Returns the array index for a specific feature ID. /// </summary> /// <param name="fid">The ID we want the index for.</param> /// <returns>The index value, or -1 if the ID was not found.</returns> int GetIndex(FeatureId fid) { return(Array.IndexOf <FeatureId>(m_Ids, fid)); }
/// <summary> /// Reads data that was previously written using <see cref="WriteData"/> /// </summary> /// <param name="editDeserializer">The mechanism for reading back content.</param> /// <param name="id">The internal of the feature within the project that created it.</param> /// <param name="entity">The type of real-world object that the feature corresponds to.</param> /// <param name="fid">The ID of the feature (may be null).</param> static void ReadData(EditDeserializer editDeserializer, out InternalIdValue id, out IEntity entity, out FeatureId fid) { id = editDeserializer.ReadInternalId(DataField.Id); entity = editDeserializer.ReadEntity(DataField.Entity); fid = editDeserializer.ReadFeatureId(); }
/// <summary> /// Writes a user-perceived feature ID to a storage medium using a standard naming /// convention. /// </summary> /// <param name="featureId">The ID to write (if null, nothing will be written)</param> internal void WriteFeatureId(FeatureId featureId) { WriteFeatureId(DataField.Key, DataField.ForeignKey, featureId); }
/// <summary> /// Initializes a new instance of the <see cref="FeatureStub"/> class /// that contains a copy of the properties of a feature. /// </summary> /// <param name="f">The feature containing the properties to copy (not null).</param> /// <exception cref="ArgumentNullException">If the supplied feature is null.</exception> internal FeatureStub(IFeature f) { if (f == null) throw new ArgumentNullException(); m_Creator = f.Creator; m_InternalId = f.InternalId; m_What = f.EntityType; m_Id = f.FeatureId; }