Exemplo n.º 1
0
        /// <summary>
        /// Reads a user-perceived feature ID using the specified naming tags.
        /// </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>
        /// <returns>The user-perceived ID that was read (may be null)</returns>
        internal FeatureId ReadFeatureId(DataField nativeField, DataField foreignField)
        {
            if (IsNextField(nativeField))
            {
                uint     nativeKey = m_Reader.ReadUInt32(nativeField.ToString());
                NativeId nid       = MapModel.FindNativeId(nativeKey);

                if (nid == null)
                {
                    return(MapModel.AddNativeId(nativeKey));
                }
                else
                {
                    return(nid);
                }
            }

            if (IsNextField(foreignField))
            {
                string    key = m_Reader.ReadString(foreignField.ToString());
                ForeignId fid = MapModel.FindForeignId(key);

                if (fid == null)
                {
                    return(MapModel.AddForeignId(key));
                }
                else
                {
                    return(fid);
                }
            }

            return(null);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Tries to produce a numeric key.
        /// </summary>
        /// <param name="id">The raw ID to use (without any check digit).</param>
        /// <returns>The numeric key value (0 if a numeric key cannot be generated).</returns>
        internal uint GetNumericKey(uint id)
        {
            // If a check digit is required, and the raw ID exceeds 200
            // million, it means that the numeric key wouldn't fit in
            // a 32-bit value.
            if (HasCheckDigit && id > 200000000)
            {
                return(0);
            }

            // If the key format is not completely numeric, we can't do it.
            if (!IsNumericKey())
            {
                return(0);
            }

            // If a check digit is not required, the supplied raw ID is
            // the numeric key we want to store.
            if (!HasCheckDigit)
            {
                return(id);
            }

            // Work out the check digit and append it to the raw ID.
            uint checkdig = NativeId.GetCheckDigit(id);

            return(id * 10 + checkdig);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Reads back an array of ID mappings, associating the user-perceived IDs with the
        /// corresponding spatial features.
        /// </summary>
        /// <param name="field">A tag associated with the array</param>
        internal void ReadIdMappings(DataField field)
        {
            if (!IsNextField(field))
            {
                return;
            }

            IdMapping[] mapping = ReadPersistentArray <IdMapping>(field);

            for (int i = 0; i < mapping.Length; i++)
            {
                IdMapping m   = mapping[i];
                NativeId  nid = MapModel.FindNativeId(m.RawId);
                if (nid == null)
                {
                    nid = MapModel.AddNativeId(m.RawId);
                }

                Feature f = MapModel.Find <Feature>(m.InternalId);

                // Ignore null ref if we are dealing with the very last mapping of a connection path
                // (covers CEdit bug that produced spurious point at the end of the path).
                if (f == null)
                {
                    //if (m_CurrentEdit is PathOperation && i == (mapping.Length - 1))
                    //    break;

                    throw new ApplicationException("Cannot locate feature for ID mapping: " + m);
                }

                f.SetId(nid);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Ensures this feature is clean after some sort of edit. If this feature has been marked
        /// for deletion (either deletion through a <see cref="DeletionOperation"/>, or because
        /// the creating edit is being rolled back), this ensures that any associated ID object
        /// no longer refers to this feature.
        /// <para/>
        /// Any override should first do it's stuff, then call this implementation.
        /// </summary>
        internal virtual void Clean()
        {
            // Return if this feature hasn't been marked for deletion
            if (!IsUndoing)
            {
                return;
            }

            // If this feature is active, but it doesn't appear to be indexed,
            // do it now. This is a bit of a kludge, meant to cover the fact
            // that lines are erroneously dropping out of the index after making
            // updates.
            //if (this.IsInactive == false && this.IsIndexed == false)
            //    this.MapModel.EditingIndex.AddFeature(this);

            // Return if there is no feature ID.
            if (m_Id == null)
            {
                return;
            }

            // Cut the reference that the ID makes to this feature (the ID
            // may continue to point to other features).
            m_Id.CutReference(this);

            // Remove the the ID from its enclosing ID packet
            NativeId nid = (m_Id as NativeId);

            if (nid != null)
            {
                nid.IdGroup.ReleaseId(nid);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Restores (un-deletes) this feature.
        /// </summary>
        /// <returns>True if feature restored. False if the feature wasn't marked as inactive.</returns>
        internal virtual bool Restore()
        {
            // Return if this feature doesn't currently have the "inactive" state
            if (!IsInactive)
            {
                return(false);
            }

            // If this feature referred to an ID, restore it.
            if (m_Id != null)
            {
                // Ensure that the ID is cross-referenced to this feature.
                m_Id.AddReference(this);

                // That's pretty well it. When a feature is de-activated, only the back
                // pointer from the ID is nulled out. The feature retained it's pointer to the ID,
                // and the ID itself was left in place as part of the IdPacket to which it belongs.
                // For native IDs, the packet needs to be told to decrement the number of free
                // IDs.

                // TODO: This may be irrelevant (need to also review the logic when something is
                // de-activated).

                if (m_Id is NativeId)
                {
                    IdManager idMan = MapModel.IdManager;
                    if (idMan != null)
                    {
                        // Find the ID group that applies to the feature's
                        // entity type (this will be null if the entity type was
                        // not originally listed in the IdEntity table, or the
                        // group is considered to be obsolete).
                        IdGroup g = idMan.GetGroup(this.EntityType);

                        // If we got a group (and the ID if not foreign) try to find
                        // the ID packet that refers to the feature's ID.
                        if (g != null)
                        {
                            NativeId nid = (m_Id as NativeId);
                            IdPacket p   = g.FindPacket(nid);
                            p.RestoreId(m_Id);
                        }
                    }
                }
            }

            // Add back into the map index.
            MapModel.EditingIndex.AddFeature(this);

            // Remember that the feature is now active
            IsInactive = false;

            return(true);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Release an allocated ID for a feature that is being removed due to an undo.
        /// This nulls out the reference to the ID from its enclosing ID packet.
        /// </summary>
        /// <param name="id">The ID that should be returned to the pool of available IDs.</param>
        internal void ReleaseId(NativeId id)
        {
            IdPacket p = FindPacket(id);

            if (p == null)
            {
                throw new ApplicationException("Cannot locate packet for ID: " + id.FormattedKey);
            }

            p.DeleteId(id);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Records an ID if it belongs to this ID packet
        /// </summary>
        /// <param name="nid">The ID that may belong to this packet</param>
        /// <returns>True if the supplied ID has been recorded as part of
        /// this packet</returns>
        internal bool SetId(NativeId nid)
        {
            int index = GetIndex(nid.RawId);

            if (index < 0)
            {
                return(false);
            }

            m_Ids[index] = nid;
            return(true);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Exhaustive search for the ID packet that refers to a specific ID. This method
        /// should only be called in situations where something has gone astray.
        /// </summary>
        /// <param name="fid">The ID to search for</param>
        /// <returns>The packet that contains the specified object (null if not found)</returns>
        internal IdPacket FindPacket(NativeId nid)
        {
            foreach (IdGroup g in m_IdGroups)
            {
                IdPacket p = g.FindPacket(nid);
                if (p != null)
                {
                    return(p);
                }
            }

            return(null);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Formats an ID number the way this ID group likes to see it.
        /// </summary>
        /// <param name="id">The raw ID to format (may not actually lie within the
        /// limits of this packet).</param>
        /// <returns>The formatted result.</returns>
        internal string FormatId(uint id)
        {
            // Apply the format assuming no check digit.
            string key = String.Format(KeyFormat, id);

            // If there really is a check digit, work it out and append it.
            if (HasCheckDigit)
            {
                uint cd = NativeId.GetCheckDigit(id);
                key += cd.ToString();
            }

            return(key);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Obtains any ID mappings for the features that are associated with an instance of <see cref="NativeId"/>
        /// </summary>
        /// <param name="features">The features of interest</param>
        /// <returns>The ID mappings for those features that have a native ID (never null, but could be an empty array).</returns>
        IdMapping[] GetIdMappings(Feature[] features)
        {
            List <IdMapping> result = new List <IdMapping>(features.Length);

            foreach (Feature f in features)
            {
                NativeId id = (f.FeatureId as NativeId);
                if (id != null)
                {
                    result.Add(new IdMapping(f.InternalId, id.RawId));
                }
            }

            return(result.ToArray());
        }
Exemplo n.º 11
0
        /// <summary>
        /// Deletes an ID that this packet points to. This nulls out the reference to the ID,
        /// and should be called ONLY if the feature ID is being eliminated as a result of undo.
        /// </summary>
        /// <param name="fid">The feature ID to remove. At call, it should be inactive (not
        /// referring to anything).</param>
        /// <returns>True if ID reference has been nulled out.</returns>
        internal bool DeleteId(NativeId fid)
        {
            // Confirm the ID is inactive.
            if (!fid.IsInactive)
            {
                throw new Exception("IdPacket.DeleteId - ID is still in use");
            }

            // Get the array index of the ID.
            int index = GetIndex(fid);

            if (index < 0)
            {
                return(false);
            }

            m_Ids[index] = null;
            return(true);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Exhaustive search for the ID packet that refers to a specific ID. This method
        /// should only be called in situations where something has gone astray.
        /// </summary>
        /// <param name="fid">The ID to search for</param>
        /// <returns>The packet that contains the specified object (null if not found)</returns>
        internal IdPacket FindPacket(NativeId nid)
        {
            foreach (IdGroup g in m_IdGroups)
            {
                IdPacket p = g.FindPacket(nid);
                if (p!=null)
                    return p;
            }

            return null;
        }
Exemplo n.º 13
0
        /// <summary>
        /// Exhaustive search for the ID packet that refers to a specific ID.
        /// </summary>
        /// <param name="fid">The ID to search for</param>
        /// <returns>The packet that contains the specified object (null if not found)</returns>
        internal IdPacket FindPacket(NativeId fid)
        {
            uint rawId = fid.RawId;

            return(m_Packets.Find(p => p.Contains(rawId)));
        }
Exemplo n.º 14
0
        /// <summary>
        /// Records an ID if it belongs to this ID packet
        /// </summary>
        /// <param name="nid">The ID that may belong to this packet</param>
        /// <returns>True if the supplied ID has been recorded as part of
        /// this packet</returns>
        internal bool SetId(NativeId nid)
        {
            int index = GetIndex(nid.RawId);
            if (index < 0)
                return false;

            m_Ids[index] = nid;
            return true;
        }
Exemplo n.º 15
0
        /// <summary>
        /// Deletes an ID that this packet points to. This nulls out the reference to the ID,
        /// and should be called ONLY if the feature ID is being eliminated as a result of undo.
        /// </summary>
        /// <param name="fid">The feature ID to remove. At call, it should be inactive (not
        /// referring to anything).</param>
        /// <returns>True if ID reference has been nulled out.</returns>
        internal bool DeleteId(NativeId fid)
        {
            // Confirm the ID is inactive.
            if (!fid.IsInactive)
                throw new Exception("IdPacket.DeleteId - ID is still in use");

            // Get the array index of the ID.
            int index = GetIndex(fid);
            if (index < 0)
                return false;

            m_Ids[index] = null;
            return true;
        }
Exemplo n.º 16
0
        /// <summary>
        /// Release an allocated ID for a feature that is being removed due to an undo.
        /// This nulls out the reference to the ID from its enclosing ID packet.
        /// </summary>
        /// <param name="id">The ID that should be returned to the pool of available IDs.</param>
        internal void ReleaseId(NativeId id)
        {
            IdPacket p = FindPacket(id);
            if (p == null)
                throw new ApplicationException("Cannot locate packet for ID: " + id.FormattedKey);

            p.DeleteId(id);
        }
Exemplo n.º 17
0
        /// <summary>
        /// Creates a new feature ID that doesn't reference anything (and does not add it to the map model).
        /// </summary>
        /// <param name="id">The ID to create.</param>
        /// <returns>The created feature ID.</returns>
        internal FeatureId CreateId(uint id)
        {
            // Confirm that the specified ID falls within this range.
            if (id < (uint)Min || id > (uint)Max)
            {
                throw new Exception("IdPacket.CreateId - New ID is not in range!");
            }

            // Confirm that the specified ID was previously reserved (if not,
            // see if it has already been created).
            int reserveIndex = FindReservedId(id);

            if (reserveIndex < 0)
            {
                string msg = String.Format("ID {0} d was not properly reserved.", id);
                throw new ApplicationException(msg);
            }

            // Confirm that the packet does not already refer to an active ID.
            int      index = (int)id - Min;
            bool     reuse = false;
            NativeId fid   = m_Ids[index];

            if (fid != null)
            {
                if (fid.IsInactive)
                {
                    reuse = true;
                }
                else
                {
                    throw new Exception("IdPacket.CreateId - ID slot has already been used.");
                }
            }

            // If we're not re-using an old ID, create one.
            if (!reuse)
            {
                string keystr;      // The key string

                // Try to get a numeric key.
                uint keyval = m_Group.GetNumericKey(id);

                if (keyval != 0)
                {
                    // If we got one, we still need to represent it as a string (for
                    // the FeatureId constructor). However, we need to let the
                    // constructor know that it's ok to convert it back to numeric!

                    keystr = keyval.ToString();
                }
                else
                {
                    // Format the ID using the key format (+ possible check digit)
                    keystr = m_Group.FormatId(id);
                }

                // Create the new ID
                fid          = new NativeId(m_Group, id);
                m_Ids[index] = fid;
            }

            // Clear the reserve status
            m_ReservedIds.RemoveAt(reserveIndex);

            return(fid);
        }
Exemplo n.º 18
0
        /// <summary>
        /// Creates a new feature ID that doesn't reference anything (and does not add it to the map model).
        /// </summary>
        /// <param name="id">The ID to create.</param>
        /// <returns>The created feature ID.</returns>
        internal FeatureId CreateId(uint id)
        {
            // Confirm that the specified ID falls within this range.
            if (id<(uint)Min || id>(uint)Max)
                throw new Exception("IdPacket.CreateId - New ID is not in range!");

            // Confirm that the specified ID was previously reserved (if not,
            // see if it has already been created).
            int reserveIndex = FindReservedId(id);
            if (reserveIndex < 0)
            {
                string msg = String.Format("ID {0} d was not properly reserved.", id);
                throw new ApplicationException(msg);
            }

            // Confirm that the packet does not already refer to an active ID.
            int index = (int)id - Min;
            bool reuse = false;
            NativeId fid = m_Ids[index];

            if (fid!=null)
            {
                if (fid.IsInactive)
                    reuse = true;
                else
                    throw new Exception("IdPacket.CreateId - ID slot has already been used.");
            }

            // If we're not re-using an old ID, create one.
            if (!reuse)
            {
                string keystr;      // The key string

                // Try to get a numeric key.
                uint keyval = m_Group.GetNumericKey(id);

                if (keyval!=0)
                {
                    // If we got one, we still need to represent it as a string (for
                    // the FeatureId constructor). However, we need to let the
                    // constructor know that it's ok to convert it back to numeric!

                    keystr = keyval.ToString();
                }
                else
                {
                    // Format the ID using the key format (+ possible check digit)
                    keystr = m_Group.FormatId(id);
                }

                // Create the new ID
                fid = new NativeId(m_Group, id);
                m_Ids[index] = fid;
            }

            // Clear the reserve status
            m_ReservedIds.RemoveAt(reserveIndex);

            return fid;
        }
Exemplo n.º 19
0
 /// <summary>
 /// Exhaustive search for the ID packet that refers to a specific ID.
 /// </summary>
 /// <param name="fid">The ID to search for</param>
 /// <returns>The packet that contains the specified object (null if not found)</returns>
 internal IdPacket FindPacket(NativeId fid)
 {
     uint rawId = fid.RawId;
     return m_Packets.Find(p => p.Contains(rawId));
 }