public BaseFile(Iso8211Reader reader) { //Current this works because we know the two records are special DataSetGeneralInformationRecord = reader.ReadDataRecord(); var dssi = DataSetGeneralInformationRecord.Fields.GetFieldByTag("DSSI"); if (dssi != null) { subFieldRow = dssi.subFields.Values[0]; tagLookup = dssi.subFields.TagIndex; vectorDataStructure = (VectorDataStructure)subFieldRow.GetUInt32(tagLookup.IndexOf("DSTR")); ATTFLexicalLevel = (S57LexicalLevel)subFieldRow.GetUInt32(tagLookup.IndexOf("AALL")); NATFLexicalLevel = (S57LexicalLevel)subFieldRow.GetUInt32(tagLookup.IndexOf("NALL")); numberOfMetaRecords = subFieldRow.GetUInt32(tagLookup.IndexOf("NOMR")); numberOfCartographicRecords = subFieldRow.GetUInt32(tagLookup.IndexOf("NOCR")); numberOfGeoRecords = subFieldRow.GetUInt32(tagLookup.IndexOf("NOGR")); numberOfCollectionRecords = subFieldRow.GetUInt32(tagLookup.IndexOf("NOLR")); numberOfIsolatedNodeRecords = subFieldRow.GetUInt32(tagLookup.IndexOf("NOIN")); numberOfConnectedNodeRecords = subFieldRow.GetUInt32(tagLookup.IndexOf("NOCN")); numberOfEdgeRecords = subFieldRow.GetUInt32(tagLookup.IndexOf("NOED")); numberOfFaceRecords = subFieldRow.GetUInt32(tagLookup.IndexOf("NOFA")); } DataSetGeographicReferenceRecord = reader.ReadDataRecord(); var dspm = DataSetGeographicReferenceRecord.Fields.GetFieldByTag("DSPM"); if (dspm != null) { subFieldRow = dspm.subFields.Values[0]; tagLookup = dspm.subFields.TagIndex; horizontalGeodeticDatum = subFieldRow.GetUInt32(tagLookup.IndexOf("HDAT")); verticalDatum = subFieldRow.GetUInt32(tagLookup.IndexOf("VDAT")); soundingDatum = subFieldRow.GetUInt32(tagLookup.IndexOf("SDAT")); compilationScaleOfData = subFieldRow.GetUInt32(tagLookup.IndexOf("CSCL")); unitsOfDepthMeasurement = subFieldRow.GetUInt32(tagLookup.IndexOf("DUNI")); unitsOfHeightMeasurement = subFieldRow.GetUInt32(tagLookup.IndexOf("HUNI")); unitsOfPositionalAccuracy = subFieldRow.GetUInt32(tagLookup.IndexOf("PUNI")); coordinateUnits = (CoordinateUnits)subFieldRow.GetUInt32(tagLookup.IndexOf("COUN")); coordinateMultiplicationFactor = subFieldRow.GetUInt32(tagLookup.IndexOf("COMF")); soundingMultiplicationFactor = subFieldRow.GetUInt32(tagLookup.IndexOf("SOMF")); // COMT } // DSPR Dataset projection // DSRC Dataset registration control // DSHT Dataset history // DSAC Dataset accuracy // CATD catalogue directory // CATX Catalogue cross reference eFeatureRecords = new Dictionary <NAMEkey, Feature>(); eFeatureObjects = new Dictionary <LongName, Feature>(); eVectorRecords = new Dictionary <NAMEkey, Vector>(); var nextRec = reader.ReadDataRecord(); while (nextRec != null) { if (nextRec.Fields.FindFieldByTag("VRID")) { vrid = nextRec.Fields.GetFieldByTag("VRID"); rcnm = vrid.subFields.GetUInt32(0, "RCNM"); rcid = vrid.subFields.GetUInt32(0, "RCID"); var key = new NAMEkey(rcnm, rcid); Vector newVec = new Vector(key, nextRec); eVectorRecords.Add(key, newVec); } else { if (nextRec.Fields.FindFieldByTag("FRID")) { frid = nextRec.Fields.GetFieldByTag("FRID"); rcnm = frid.subFields.GetUInt32(0, "RCNM"); rcid = frid.subFields.GetUInt32(0, "RCID"); //consider using lnam as key (from FOID field), challenge: update files deleting a feature record do not encode lnam of that feature record var key = new NAMEkey(rcnm, rcid); Feature newFeat = new Feature(key, nextRec); eFeatureRecords.Add(key, newFeat); } } nextRec = reader.ReadDataRecord(); } }
public void ApplyUpdateFile(UpdateFile updateFile) { DataField target_vrid, target_frid; RecordUpdate ruin; uint rver, target_rver; DataField attv, target_attv; DataField attf, target_attf; DataField natf, target_natf; bool attribute_found = false; DataField vrpt, target_vrpt, vrpc; RecordUpdate vpui; int vpix, nvpt; DataField coordinatefield, target_coordinatefield, sgcc; RecordUpdate ccui; int ccix, ccnc; DataField ffpt, target_ffpt, ffpc; RecordUpdate ffui; int ffix, nfpt; DataField fspt, target_fspt, fspc; RecordUpdate fsui; int fsix, nspt; SFcontainer[] target_row; //throw new NotImplementedException("ApplyUpdateFile not implemented"); foreach (DataRecord vr in updateFile.UpdateVectorRecords) { // Record Identifier Field vrid = vr.Fields.GetFieldByTag("VRID"); subFieldRow = vrid.subFields.Values[0]; tagLookup = vrid.subFields.TagIndex; rcnm = subFieldRow.GetUInt32(tagLookup.IndexOf("RCNM")); rcid = subFieldRow.GetUInt32(tagLookup.IndexOf("RCID")); rver = subFieldRow.GetUInt32(tagLookup.IndexOf("RVER")); ruin = (RecordUpdate)subFieldRow.GetUInt32(tagLookup.IndexOf("RUIN")); NAMEkey updateNAMEkey = new NAMEkey(rcnm, rcid); if (ruin == RecordUpdate.Insert) { Vector newVec = new Vector(updateNAMEkey, vr); eVectorRecords.Add(updateNAMEkey, newVec); } else { target_vrid = eVectorRecords[updateNAMEkey].VectorRecord.Fields.GetFieldByTag("VRID"); target_rver = target_vrid.subFields.GetUInt32(0, "RVER"); if (ruin == RecordUpdate.Delete) { if (target_rver == rver - 1) { eVectorRecords.Remove(updateNAMEkey); } } else if (ruin == RecordUpdate.Modify) { attv = vr.Fields.GetFieldByTag("ATTV"); //attribute update not tested if (attv != null && target_rver == rver - 1) { int atvl, target_atvl; int attl, target_attl; target_attv = eVectorRecords[updateNAMEkey].VectorRecord.Fields.GetFieldByTag("ATTV"); if (target_attv == null) { eVectorRecords[updateNAMEkey].VectorRecord.Fields.Add(attv); } else { attl = attv.subFields.TagIndex.IndexOf("ATTL"); target_attl = target_attv.subFields.TagIndex.IndexOf("ATTL"); atvl = attv.subFields.TagIndex.IndexOf("ATVL"); target_atvl = target_attv.subFields.TagIndex.IndexOf("ATVL"); foreach (var row in attv.subFields.Values) { attribute_found = false; for (int i = 0; i < target_attv.subFields.Values.Count; i++) { target_row = target_attv.subFields.Values[i]; if (target_row[target_attl].Equals(row[attl])) //if attribute found, overwrite value { target_attv.subFields.Values[i][target_atvl] = row[atvl]; attribute_found = true; break; } } if (!attribute_found) { target_attv.subFields.Values.Add(row); //risky, assumes same indices of ATTL and ATVl in source and target } } } } // VRPC update instruction Pointer Control Field vrpc = vr.Fields.GetFieldByTag("VRPC"); if (vrpc != null && target_rver == rver - 1) { vpui = (RecordUpdate)vrpc.subFields.GetUInt32(0, "VPUI"); vpix = (int)vrpc.subFields.GetUInt32(0, "VPIX") - 1; //c sharp indices start at 0 while S57 indices start at 1 nvpt = (int)vrpc.subFields.GetUInt32(0, "NVPT"); //number of vector record pointers to patch vrpt = vr.Fields.GetFieldByTag("VRPT"); target_vrpt = eVectorRecords[updateNAMEkey].VectorRecord.Fields.GetFieldByTag("VRPT"); if (vpui == RecordUpdate.Insert) { if (target_vrpt == null) //insert can also mean add to non-existing VRPT. { eFeatureRecords[updateNAMEkey].FeatureRecord.Fields.Add(vrpt); } else { for (int i = 0; i < nvpt; i++) { target_vrpt.subFields.Values.Insert(vpix + i, vrpt.subFields.Values[i]); //maybe risky, assumes same subfield order in source and target } } } else if (vpui == RecordUpdate.Delete) { for (int i = 0; i < nvpt; i++) { target_vrpt.subFields.Values.RemoveAt(vpix); } } else if (vpui == RecordUpdate.Modify) { for (int i = 0; i < nvpt; i++) { target_vrpt.subFields.Values[vpix + i] = vrpt.subFields.Values[i]; //maybe risky, assumes same subfield order in source and target } } } // SGCC update instruction Coordinate Control Field sgcc = vr.Fields.GetFieldByTag("SGCC"); if (sgcc != null && target_rver == rver - 1) { ccui = (RecordUpdate)sgcc.subFields.GetUInt32(0, "CCUI"); ccix = (int)sgcc.subFields.GetUInt32(0, "CCIX") - 1; //c sharp indices start at 0 while S57 indices start at 1 ccnc = (int)sgcc.subFields.GetUInt32(0, "CCNC"); //number of vector record pointers to patch coordinatefield = vr.Fields.GetFieldByTag("SG2D"); target_coordinatefield = eVectorRecords[updateNAMEkey].VectorRecord.Fields.GetFieldByTag("SG2D"); if (target_coordinatefield == null) { coordinatefield = vr.Fields.GetFieldByTag("SG3D"); target_coordinatefield = eVectorRecords[updateNAMEkey].VectorRecord.Fields.GetFieldByTag("SG3D"); } if (ccui == RecordUpdate.Insert) { if (target_coordinatefield == null) //insert can also mean add to non-existing coordinatefield. { eFeatureRecords[updateNAMEkey].FeatureRecord.Fields.Add(coordinatefield); } else { for (int i = 0; i < ccnc; i++) { target_coordinatefield.subFields.Values.Insert(ccix + i, coordinatefield.subFields.Values[i]); //maybe risky, assumes same subfield order in source and target } } } else if (ccui == RecordUpdate.Delete) { for (int i = 0; i < ccnc; i++) { target_coordinatefield.subFields.Values.RemoveAt(ccix); } } else if (ccui == RecordUpdate.Modify) { for (int i = 0; i < ccnc; i++) { target_coordinatefield.subFields.Values[ccix + i] = coordinatefield.subFields.Values[i]; //risky, assumes same subfield order in source and target } } } target_vrid.subFields.Values[0][target_vrid.subFields.TagIndex.IndexOf("RVER")].uintValue = rver; } } } foreach (DataRecord fr in updateFile.UpdateFeatureRecords) { // Record Identifier Field frid = fr.Fields.GetFieldByTag("FRID"); subFieldRow = frid.subFields.Values[0]; tagLookup = frid.subFields.TagIndex; rcnm = subFieldRow.GetUInt32(tagLookup.IndexOf("RCNM")); rcid = subFieldRow.GetUInt32(tagLookup.IndexOf("RCID")); rver = subFieldRow.GetUInt32(tagLookup.IndexOf("RVER")); ruin = (RecordUpdate)subFieldRow.GetUInt32(tagLookup.IndexOf("RUIN")); NAMEkey updateNAMEkey = new NAMEkey(rcnm, rcid); if (ruin == RecordUpdate.Insert) { Feature newFeat = new Feature(updateNAMEkey, fr); eFeatureRecords.Add(updateNAMEkey, newFeat); } else { target_frid = eFeatureRecords[updateNAMEkey].FeatureRecord.Fields.GetFieldByTag("FRID"); target_rver = target_frid.subFields.GetUInt32(0, "RVER"); if (ruin == RecordUpdate.Delete) { if (target_rver == rver - 1) { eFeatureRecords.Remove(updateNAMEkey); } } else if (ruin == RecordUpdate.Modify) { attf = fr.Fields.GetFieldByTag("ATTF"); //attribute update not tested if (attf != null && target_rver == rver - 1) { int atvl, target_atvl; int attl, target_attl; target_attf = eFeatureRecords[updateNAMEkey].FeatureRecord.Fields.GetFieldByTag("ATTF"); if (target_attf == null) { eFeatureRecords[updateNAMEkey].FeatureRecord.Fields.Add(attf); } else { attl = attf.subFields.TagIndex.IndexOf("ATTL"); target_attl = target_attf.subFields.TagIndex.IndexOf("ATTL"); atvl = attf.subFields.TagIndex.IndexOf("ATVL"); target_atvl = target_attf.subFields.TagIndex.IndexOf("ATVL"); foreach (var row in attf.subFields.Values) { attribute_found = false; for (int i = 0; i < target_attf.subFields.Values.Count; i++) { target_row = target_attf.subFields.Values[i]; if (target_row[target_attl].Equals(row[attl])) //if attribute found, overwrite value { target_attf.subFields.Values[i][target_atvl] = row[atvl]; attribute_found = true; break; } } if (!attribute_found) { target_attf.subFields.Values.Add(row); //risky, assumes same indices of ATTL and ATVl in source and target } } } } natf = fr.Fields.GetFieldByTag("NATF"); //attribute update not tested if (natf != null && target_rver == rver - 1) { int atvl, target_atvl; int attl, target_attl; target_natf = eFeatureRecords[updateNAMEkey].FeatureRecord.Fields.GetFieldByTag("NATF"); if (target_natf == null) { eFeatureRecords[updateNAMEkey].FeatureRecord.Fields.Add(natf); } else { attl = natf.subFields.TagIndex.IndexOf("ATTL"); target_attl = target_natf.subFields.TagIndex.IndexOf("ATTL"); atvl = natf.subFields.TagIndex.IndexOf("ATVL"); target_atvl = target_natf.subFields.TagIndex.IndexOf("ATVL"); foreach (var row in natf.subFields.Values) { attribute_found = false; for (int i = 0; i < target_natf.subFields.Values.Count; i++) { target_row = target_natf.subFields.Values[i]; if (target_row[target_attl].Equals(row[attl])) //if attribute found, overwrite value { target_natf.subFields.Values[i][target_atvl] = row[atvl]; attribute_found = true; break; } } if (!attribute_found) { target_natf.subFields.Values.Add(row); //risky, assumes same indices of ATTL and ATVl in source and target } } } } // FFPC update instruction Pointer Control Field ffpc = fr.Fields.GetFieldByTag("FFPC"); if (ffpc != null && target_rver == rver - 1) { ffui = (RecordUpdate)ffpc.subFields.GetUInt32(0, "FFUI"); ffix = (int)ffpc.subFields.GetUInt32(0, "FFIX") - 1; //c sharp indices start at 0 while S57 indices start at 1 nfpt = (int)ffpc.subFields.GetUInt32(0, "NFPT"); //number of vector record pointers to patch ffpt = fr.Fields.GetFieldByTag("FFPT"); target_ffpt = eFeatureRecords[updateNAMEkey].FeatureRecord.Fields.GetFieldByTag("FFPT"); var target = eFeatureRecords[updateNAMEkey]; if (ffui == RecordUpdate.Insert) { if (target_ffpt == null) //insert can also mean add to non-existing FFPT. { eFeatureRecords[updateNAMEkey].FeatureRecord.Fields.Add(ffpt); } else { for (int i = 0; i < nfpt; i++) { target_ffpt.subFields.Values.Insert(ffix + i, ffpt.subFields.Values[i]); //maybe risky, assumes same subfield order in source and target } } } else if (ffui == RecordUpdate.Delete) { for (int i = 0; i < nfpt; i++) { target_ffpt.subFields.Values.RemoveAt(ffix); } } else if (ffui == RecordUpdate.Modify) { for (int i = 0; i < nfpt; i++) { target_ffpt.subFields.Values[ffix + i] = ffpt.subFields.Values[i]; //maybe risky, assumes same subfield order in source and target } } } // FSPC update instruction Pointer Control Field fspc = fr.Fields.GetFieldByTag("FSPC"); if (fspc != null && target_rver == rver - 1) { fsui = (RecordUpdate)fspc.subFields.GetUInt32(0, "FSUI"); fsix = (int)fspc.subFields.GetUInt32(0, "FSIX") - 1; //c sharp indices start at 0 while S57 indices start at 1 nspt = (int)fspc.subFields.GetUInt32(0, "NSPT"); //number of vector record pointers to patch fspt = fr.Fields.GetFieldByTag("FSPT"); target_fspt = eFeatureRecords[updateNAMEkey].FeatureRecord.Fields.GetFieldByTag("FSPT"); if (fsui == RecordUpdate.Insert) { if (target_fspt == null) //insert can also mean add to non-existing FSPT. { eFeatureRecords[updateNAMEkey].FeatureRecord.Fields.Add(fspt); } else { for (int i = 0; i < nspt; i++) { target_fspt.subFields.Values.Insert(fsix + i, fspt.subFields.Values[i]); //maybe risky, assumes same subfield order in source and target } } } else if (fsui == RecordUpdate.Delete) { for (int i = 0; i < nspt; i++) { target_fspt.subFields.Values.RemoveAt(fsix); } } else if (fsui == RecordUpdate.Modify) { for (int i = 0; i < nspt; i++) { target_fspt.subFields.Values[fsix + i] = fspt.subFields.Values[i]; //maybe risky, assumes same subfield order in source and target } } } target_frid.subFields.Values[0][target_frid.subFields.TagIndex.IndexOf("RVER")].uintValue = rver; } } } }