/// <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> /// Reads an array of spatial features (using their unique IDs the read them from the map model). /// </summary> /// <typeparam name="T">The type of spatial feature expected by the caller</typeparam> /// <param name="referenceFrom">The object that is making the reference</param> /// <param name="field">A tag associated with the array</param> /// <returns>The features that were read (should all be not null).</returns> internal T[] ReadFeatureRefArray <T>(IFeatureRefArray referenceFrom, DataField field) where T : Feature { string[] ids = ReadSimpleArray <string>(field); T[] result = new T[ids.Length]; List <ForwardRefArrayItem> fwRefs = null; for (int i = 0; i < result.Length; i++) { InternalIdValue id = new InternalIdValue(ids[i]); result[i] = MapModel.Find <T>(id); if (result[i] == null) { if (fwRefs == null) { fwRefs = new List <ForwardRefArrayItem>(); } fwRefs.Add(new ForwardRefArrayItem(id, i)); } } if (fwRefs != null) { m_ForwardRefs.Add(new ForwardFeatureRefArray(referenceFrom, field, fwRefs.ToArray())); } return(result); }
/// <summary> /// Initializes a new instance of the <see cref="ForwardFeatureRef"/> class. /// </summary> /// <param name="referenceFrom">The object that makes the forward-reference (not null).</param> /// <param name="field">The ID of the persistent field.</param> /// <param name="iid">The internal ID that has been persisted for the field (relating to a feature /// that has not been created yet).</param> /// <exception cref="ArgumentNullException">If <paramref name="referenceFrom"/> is not defined.</exception> internal ForwardFeatureRef(IFeatureRef referenceFrom, DataField field, InternalIdValue iid) : base(field) { if (referenceFrom == null) { throw new ArgumentNullException(); } ReferenceFrom = referenceFrom; InternalId = iid; }
/// <summary> /// Records information for a line split /// </summary> /// <param name="parentLine">The line that may be getting split</param> /// <param name="field">The tag of the item that should be attached to the line split info</param> /// <param name="dataId">The ID for the section (null if there is no split)</param> /// <returns>True if a line split was recorded, false if the <paramref name="splitSection"/> is null.</returns> internal bool AddLineSplit(LineFeature parentLine, DataField field, string dataId) { if (dataId == null) { return(false); } InternalIdValue id = new InternalIdValue(dataId); AddFeatureDescription(field, new FeatureStub(Creator, id, parentLine.EntityType, null)); return(true); }
/// <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> /// Creates a new <c>PointFeature</c> with geometry that isn't shared /// with any other point. /// </summary> /// <param name="creator">The operation that created the feature (not null)</param> /// <param name="id">The internal ID of this feature within the project that created it.</param> /// <param name="e">The entity type for the feature (not null)</param> /// <param name="g">The geometry for the point (may be null)</param> internal PointFeature(Operation creator, InternalIdValue id, IEntity e, PointGeometry g) : base(creator, id, e, null) { if (g == null) { m_Geom = null; } else { m_Geom = new Node(this, g); } }
/// <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 virtual LineFeature CreateSection(string itemName, LineFeature baseLine, PointFeature from, PointFeature to) { IFeature f = FindFeatureDescription(itemName); if (f == null) { InternalIdValue id = MapModel.WorkingSession.AllocateNextId(); f = new FeatureStub(m_Operation, id, baseLine.EntityType, baseLine.FeatureId); } return(new LineFeature(f, baseLine, from, to, baseLine.IsTopological)); }
private PointFeature EnsurePointExists(PointGeometry p, ILength tol, Operation creator) { PointFeature result = (PointFeature)m_Index.QueryClosest(p, tol, SpatialType.Point); if (result == null) { IEntity e = creator.MapModel.DefaultPointType; InternalIdValue id = CadastralMapModel.Current.WorkingSession.AllocateNextId(); result = new PointFeature(creator, id, e, p); m_Index.Add(result); m_Result.Add(result); } return(result); }
/// <summary> /// Initializes a new instance of the <see cref="LegFace"/> class /// using the data read from persistent storage. /// </summary> /// <param name="editDeserializer">The mechanism for reading back content.</param> internal LegFace(EditDeserializer editDeserializer) { // Only connection paths should generate LegFace instances PathOperation op = (editDeserializer.CurrentEdit as PathOperation); if (op == null) { throw new ApplicationException("Unexpected creating edit for a leg face"); } this.Sequence = editDeserializer.ReadInternalId(DataField.Id); if (editDeserializer.IsNextField(DataField.PrimaryFaceId)) { InternalIdValue primaryFaceId = editDeserializer.ReadInternalId(DataField.PrimaryFaceId); LegFace face = op.FindFace(primaryFaceId); if (face == null) { throw new ApplicationException("Cannot locate primary face " + primaryFaceId); } Leg = face.Leg; Leg.AlternateFace = this; } else { // This should never happen. Primary faces are not serialized using the LegFace // class (we only use LegFace as part of a PathOperation to simplify import of // extra legs from old CEdit files). throw new ApplicationException(); } // Convert the data entry string into observed spans string entryString = editDeserializer.ReadString(DataField.EntryString); DistanceUnit defaultEntryUnit = EditingController.Current.EntryUnit; Distance[] dists = LineSubdivisionFace.GetDistances(entryString, defaultEntryUnit, false); m_Spans = new SpanInfo[dists.Length]; for (int i = 0; i < m_Spans.Length; i++) { m_Spans[i] = new SpanInfo() { ObservedDistance = dists[i] }; } }
/// <summary> /// Creates a new <see cref="LineFeature"/> (with <see cref="SegmentGeometry"/>) using information previously /// recorded via a call to <see cref="AddFeatureDescription"/>. /// </summary> /// <param name="itemName">The name for the item involved</param> /// <param name="from">The point at the start of the line (not null).</param> /// <param name="to">The point at the end of the line (not null).</param> /// <returns>The created feature (never null)</returns> internal virtual LineFeature CreateSegmentLineFeature(string itemName, PointFeature from, PointFeature to) { LineFeature result = null; IFeature f = FindFeatureDescription(itemName); if (f == null) { InternalIdValue id = MapModel.WorkingSession.AllocateNextId(); result = new LineFeature(m_Operation, id, LineType, from, to); result.SetNextId(); } else { result = new LineFeature(f, from, to); } return(result); }
/// <summary> /// Creates a new instance of <see cref="PointFeature"/>, with the currently /// active entity type (and a user-perceived ID if it applies), and adds to the model. /// </summary> /// <returns>The new feature (never null)</returns> internal virtual PointFeature CreatePointFeature(string itemName) { PointFeature result = null; IFeature f = FindFeatureDescription(itemName); if (f == null) { InternalIdValue id = MapModel.WorkingSession.AllocateNextId(); result = new PointFeature(m_Operation, id, PointType, null); result.SetNextId(); } else { result = new PointFeature(f, null); } return(result); }
/// <summary> /// Reads a reference to a spatial feature, using that reference to obtain the /// corresponding feature. /// </summary> /// <typeparam name="T">The type of spatial feature expected by the caller</typeparam> /// <param name="field">A tag associated with the value</param> /// <returns> /// The feature that was read (null if the feature reference is an internal ID of 0). May /// actually have a type that is derived from the supplied type. /// </returns> /// <remarks>This does not create a brand new feature. Rather, it uses a reference /// to try to obtain a feature that should have already been created. /// <para/> /// This version assumes that the referenced feature must have been already deserialized, which /// should always be the case when dealing with edits that were created using Backsight. This /// may NOT be the case when dealing with data files that originated in the old CEdit system. /// The problem is that CEdit handled updates by modifying the objects holding the original /// edits and, since it is valid to make use of features created after the initial edit (so /// long as there is no dependency), it is possible that the features may be initially unknown /// during deserialization. /// <para/> /// So if there is any possibility that the referenced feature may come later in the editing /// sequence, use the version that also accepts an instance of <see cref="IFeatureRef"/>. /// Note that for updates to be possible, the edit needs to implement <see cref="IRevisable"/> /// (if updates are not possible, forward references should not be possible either). /// </remarks> /// <exception cref="ApplicationException">If the internal ID is defined, but the referenced feature /// could not be found.</exception> internal T ReadFeatureRef <T>(DataField field) where T : Feature { InternalIdValue id = m_Reader.ReadInternalId(field.ToString()); if (id.IsEmpty) { return(default(T)); } T result = MapModel.Find <T>(id); if (result == null) { throw new ApplicationException(String.Format("Cannot locate forward reference {0} (type={1})", id, typeof(T).Name)); } return(result); }
/// <summary> /// Creates a new <see cref="ArcFeature"/> using information previously /// recorded via a call to <see cref="AddFeatureDescription"/>. /// </summary> /// <param name="itemName">The name for the item involved</param> /// <param name="from">The point at the start of the line (not null).</param> /// <param name="to">The point at the end of the line (not null).</param> /// <returns>The created feature (never null)</returns> internal virtual ArcFeature CreateArcFeature(string itemName, PointFeature from, PointFeature to) { ArcFeature result = null; IFeature f = FindFeatureDescription(itemName); if (f == null) { InternalIdValue id = MapModel.WorkingSession.AllocateNextId(); result = new ArcFeature(m_Operation, id, LineType, null, from, to, true); result.SetNextId(); } else { result = new ArcFeature(f, from, to, null, f.EntityType.IsPolygonBoundaryValid); } return(result); }
/// <summary> /// Reads a reference to a spatial feature, using that reference to obtain the /// corresponding feature. If the feature cannot be found, the reference will be cached as /// a forward reference (on completion of deserialization, you then call <see cref="ApplyForwardRefs"/> /// to process the cache). /// </summary> /// <typeparam name="T">The type of spatial feature expected by the caller</typeparam> /// <param name="referenceFrom">The object that is making the reference</param> /// <param name="field">A tag associated with the value</param> /// <returns> /// The feature that was read (null if not found, or the reference was undefined). May /// actually have a type that is derived from the supplied type. /// </returns> /// <remarks>This does not create a brand new feature. Rather, it uses a reference /// to try to obtain a feature that should have already been created. /// </remarks> internal T ReadFeatureRef <T>(IFeatureRef referenceFrom, DataField field) where T : Feature { InternalIdValue id = m_Reader.ReadInternalId(field.ToString()); if (id.IsEmpty) { return(default(T)); } T result = MapModel.Find <T>(id); if (result == null) { var fwRef = new ForwardFeatureRef(referenceFrom, field, id); m_ForwardRefs.Add(fwRef); } return(result); }
/// <summary> /// Initializes a new instance of the <see cref="IdMapping"/> class. /// </summary> /// <param name="internalId">The internal id.</param> /// <param name="rawId">The raw value for an associated instance of <see cref="NativeId"/>.</param> internal IdMapping(InternalIdValue internalId, uint rawId) { m_InternalId = internalId; m_RawId = rawId; }
private Feature ImportLine(ILength tol, Ntx.Line line, Operation creator) { // Circular arcs are handled elsewhere if (line.IsCurve) { return(null); } IEntity what = GetEntityType(line, SpatialType.Line); PointGeometry[] pts = GetPositions(line); // Ignore zero-length lines if (HasZeroLength(pts)) { return(null); } // Ensure point features exist at both ends of the line. PointFeature ps = EnsurePointExists(pts[0], tol, creator); PointFeature pe = EnsurePointExists(pts[pts.Length - 1], tol, creator); // Force end positions to match pts[0] = ps.PointGeometry; pts[pts.Length - 1] = pe.PointGeometry; // It's possible we've now produced a zero-length line if (Object.ReferenceEquals(ps, pe) && HasZeroLength(pts)) { return(null); } // If we're dealing with a multi-segment, I have occasionally seen tiny glitches // at the end of the incoming lines (whether this is a real data problem, or an // imperfection in the import software is unknown). So double check now. // In the longer term, the import software should also check for more complex // issues, like missing intersections. In the meantime, I assume that incoming // topological data is generally clean. if (pts.Length > 2 && line.IsTopologicalArc) { pts = CheckMultiSegmentEnds(pts); } LineFeature result; InternalIdValue id = CadastralMapModel.Current.WorkingSession.AllocateNextId(); if (pts.Length == 2) { result = new LineFeature(creator, id, what, ps, pe); } else { result = new LineFeature(creator, id, what, ps, pe, pts); } // The toological status of the incoming arc may override the status that the // constructor derived from the entity type result.SetTopology(line.IsTopologicalArc); return(result); }
private ArcFeature ImportArc(Ntx.Line line, Operation creator, ILength tol) { Debug.Assert(line.IsCurve); IEntity what = GetEntityType(line, SpatialType.Line); // Get positions defining the arc PointGeometry[] pts = GetPositions(line); // Ignore zero-length lines if (HasZeroLength(pts)) { return(null); } // Add a point at the center of the circle Ntx.Position pos = line.Center; PointGeometry pc = new PointGeometry(pos.Easting, pos.Northing); PointFeature center = EnsurePointExists(pc, tol, creator); // Calculate exact positions for the arc endpoints double radius = line.Radius; ICircleGeometry cg = new CircleGeometry(pc, radius); IPosition bc = CircleGeometry.GetClosestPosition(cg, pts[0]); IPosition ec = CircleGeometry.GetClosestPosition(cg, pts[pts.Length - 1]); // Round off to nearest micron PointGeometry bcg = PointGeometry.Create(bc); PointGeometry ecg = PointGeometry.Create(ec); // Ensure point features exist at both ends of the line. PointFeature ps = GetArcEndPoint(bcg, tol, creator); PointFeature pe = GetArcEndPoint(ecg, tol, creator); // Try to find a circle that's already been added by this import. Circle c = EnsureCircleExists(center, radius, tol, creator); // Determine which way the arc is directed bool iscw = LineStringGeometry.IsClockwise(pts, center); InternalIdValue id = CadastralMapModel.Current.WorkingSession.AllocateNextId(); ArcFeature arc = new ArcFeature(creator, id, what, c, ps, pe, iscw); // The toological status of the incoming arc may override the status that the // constructor derived from the entity type arc.SetTopology(line.IsTopologicalArc); #if DEBUG // Confirm the NTX data was valid (ensure it's consistent with what we've imported)... double readRad = c.Radius; double calcRad = BasicGeom.Distance(c.Center, ps); Debug.Assert(Math.Abs(readRad - calcRad) < tol.Meters); foreach (IPointGeometry pg in pts) { ILength check = arc.Geometry.Distance(pg); Debug.Assert(check.Meters < tol.Meters); } #endif return(arc); }
/// <summary> /// Writes an internal ID to a storage medium. /// </summary> /// <param name="field">The tag that identifies the item.</param> /// <param name="id">The internal ID to write</param> internal void WriteInternalId(DataField field, InternalIdValue id) { m_Writer.WriteInternalId(field.ToString(), id); }
/// <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 an internal ID to a storage medium. /// </summary> /// <param name="name">A name tag for the item</param> /// <param name="id">The internal ID to write</param> public void WriteInternalId(string name, InternalIdValue id) { WriteValue(name, id.ToString()); }
// none #endregion #region Constructors /// <summary> /// Creates a new <c>ArcFeature</c> /// </summary> /// <param name="creator">The operation that created the feature (not null)</param> /// <param name="id">The internal ID of this feature within the project that created it.</param> /// <param name="e">The entity type for the feature.</param> /// <param name="c">The circle the arc coincides with</param> /// <param name="bc">The point at the start of the arc</param> /// <param name="ec">The point at the end of the arc</param> /// <param name="isClockwise">True if the arc is directed clockwise from start to end</param> internal ArcFeature(Operation creator, InternalIdValue id, IEntity e, Circle c, PointFeature bc, PointFeature ec, bool isClockwise) : base(creator, id, e, bc, ec, new ArcGeometry(c, bc, ec, isClockwise)) { }
/// <summary> /// Creates a stub for an item on this face. /// </summary> /// <param name="itemSequence">The sequence number to assign to the stub</param> /// <param name="ent">The entity type for the stub</param> /// <returns>The created stub</returns> FeatureStub CreateStub(Operation creator, uint itemSequence, IEntity ent) { InternalIdValue iid = new InternalIdValue(itemSequence); return(new FeatureStub(creator, iid, ent, null)); }
private Feature ImportName(Ntx.Name name, Operation creator) { /* * // Get pointer to the applicable map theme * CeTheme theme(Name.GetTheme()); * CeTheme* pTheme = theme.AddTheme(); * * // Get pointer to the entity type. * GRAPHICSTYPE geom = ANNOTATION; * if ( Name.IsLabel() ) geom = POLYGON; * CeEntity* pEntity = AddEntity(Name.GetpFeatureCode(),pTheme,geom); */ IEntity entity = GetEntityType(name, SpatialType.Text); // Get the text string string text = name.Text; // Get the position of the centre of the 1st character Ntx.Position pos = name.Position(0); IPosition vcentre = new Position(pos.Easting, pos.Northing); // Get text metrics float height = name.Height; float spacing = name.Spacing; float rotation = name.Rotation; // Calculate the top left corner of the first character using // the text metrics we just got ... // Get the width of the first character. For names that contain // only one character, the spacing we have will be zero, so in // that case, deduce the width of the character via the covering // rectangle. float charwidth = spacing; if (charwidth < Constants.TINY) { // Get the covering rectangle. Ntx.Position nw = name.NorthWest; Ntx.Position se = name.SouthEast; // And get the dimensions. double dx = se.Easting - nw.Easting; double dy = nw.Northing - se.Northing; // If the cover is screwed up, assume the width is 80% of the text height. if (dy < Constants.TINY) { charwidth = (float)(height * 0.8); } else { charwidth = (float)(height * (dx / dy)); } } // Define the bearing from bottom to top of the text. double vbear = (double)rotation; // Get position directly above the centre of the 1st char. IPosition above = Geom.Polar(vcentre, vbear, 0.5 * (double)height); // Define the bearing from the point we just got to the // start of the text string. double hbear = vbear - Constants.PIDIV2; // Back up half a character to get the initial corner. PointGeometry topleft = new PointGeometry(Geom.Polar(above, hbear, 0.5 * (double)charwidth)); IFont font = null; double width = (double)text.Length * charwidth; TextFeature result = null; if (name.IsLabel) { // Create key text string keystr = name.Text; KeyTextGeometry kt = new KeyTextGeometry(topleft, font, height, width, rotation); InternalIdValue id = CadastralMapModel.Current.WorkingSession.AllocateNextId(); result = new TextFeature(creator, id, entity, kt); kt.Label = result; result.SetTopology(true); // Define the label's foreign ID and form a two-way association ForeignId fid = GetFeatureId(keystr); Debug.Assert(fid != null); fid.Add(result); // Remember the reference position of the label. Ntx.Position xp = name.RefPosition; IPointGeometry pp = new PointGeometry(xp.Easting, xp.Northing); result.SetPolPosition(pp); } else { // Create a miscellaneous text label. MiscTextGeometry mt = new MiscTextGeometry(text, topleft, font, height, width, rotation); InternalIdValue id = CadastralMapModel.Current.WorkingSession.AllocateNextId(); result = new TextFeature(creator, id, entity, mt); result.SetTopology(false); } return(result); }
/// <summary> /// Creates a new text feature /// </summary> /// <param name="creator">The operation creating the text</param> /// <param name="id">The internal ID of this feature within the /// project that created it.</param> /// <param name="ent">The entity type for the string.</param> /// <param name="text">The text geometry (including the text string itself)</param> /// </param> internal TextFeature(Operation creator, InternalIdValue id, IEntity ent, TextGeometry text) : base(creator, id, ent, null) { m_Geom = text; m_Container = null; }
private Feature ImportSymbol(Ntx.Symbol symbol, Operation creator) { IEntity what = GetEntityType(symbol, SpatialType.Point); // Get the position Ntx.Position pos = symbol.Position; PointGeometry g = new PointGeometry(pos.Easting, pos.Northing); // Ignore positions at 0,0! if (g.Easting.Microns == 0 && g.Northing.Microns == 0) { return(null); } InternalIdValue id = CadastralMapModel.Current.WorkingSession.AllocateNextId(); PointFeature p = new PointFeature(creator, id, what, g); /* * * static LOGICAL warned=FALSE; // debug * * // Get pointer to the map theme * CeTheme theme(Symbol.GetTheme()); * const CeTheme* const pTheme = theme.AddTheme(); * * // Get pointer to the entity * CeEntity* pEntity = AddEntity(Symbol.GetpFeatureCode(),pTheme,VERTEX); * * // Get the position * const CxPosition& pos = Symbol.GetPosition(); * * // For the time being ... * if ( !warned && pos.Is3D() ) { * AfxMessageBox("Elevation data is being stripped."); * warned = TRUE; * } * * // Add the position of the symbol. * CeVertex vtx(pos.GetEasting(),pos.GetNorthing()) ; * const CeLocation* pLoc = pMap->AddLocation(vtx); * * // If the location does not already have an associated point * // feature, add one now (the location may have been previously * // added via the import of a line). * * // Note that this version of AddPoint will always add a duplicate * // point at the specified location. * * CePoint* pPoint = pMap->AddPoint((CeLocation* const)pLoc,pEntity); */ // Define foreign ID (if any) ... string keystr = symbol.Key; ForeignId fid = GetFeatureId(keystr); if (fid != null) { fid.Add(p); } return(p); }
/// <summary> /// Initializes a new instance of the <see cref="IdMapping"/> class /// using the data read from persistent storage. /// </summary> /// <param name="editDeserializer">The mechanism for reading back content.</param> internal IdMapping(EditDeserializer editDeserializer) { m_InternalId = editDeserializer.ReadInternalId(DataField.Id); m_RawId = editDeserializer.ReadUInt32(DataField.Key); }