int main( int nArgc, char ** papszArgv ) { DDFModule oModule; const char *pszFilename; int i; if( nArgc > 1 ) pszFilename = papszArgv[1]; else { printf( "Usage: 8211view filename\n" ); exit( 1 ); } for( i = 0; i < 40; i++ ) { /* -------------------------------------------------------------------- */ /* Open the file. Note that by default errors are reported to */ /* stderr, so we don't bother doing it ourselves. */ /* -------------------------------------------------------------------- */ if( !oModule.Open( pszFilename ) ) { exit( 1 ); } /* -------------------------------------------------------------------- */ /* Loop reading records till there are none left. */ /* -------------------------------------------------------------------- */ DDFRecord *poRecord; int nRecordCount = 0; int nFieldCount = 0; while( (poRecord = oModule.ReadRecord()) != NULL ) { /* ------------------------------------------------------------ */ /* Loop over each field in this particular record. */ /* ------------------------------------------------------------ */ for( int iField = 0; iField < poRecord->GetFieldCount(); iField++ ) { DDFField *poField = poRecord->GetField( iField ); ViewRecordField( poField ); nFieldCount++; } nRecordCount++; } oModule.Close(); printf( "Read %d records, %d fields.\n", nRecordCount, nFieldCount ); } }
DDFModule *SDTSTransfer::GetLayerModuleReader( int iEntry ) { if( iEntry < 0 || iEntry >= nLayers ) { return nullptr; } DDFModule *poModuleReader = new DDFModule; if( !poModuleReader->Open( oCATD.GetEntryFilePath( panLayerCATDEntry[iEntry] ) ) ) { panLayerCATDEntry[iEntry] = SLTUnknown; // to prevent further attempt delete poModuleReader; return nullptr; } return poModuleReader; }
int SDTS_XREF::Read( const char * pszFilename ) { DDFModule oXREFFile; DDFRecord *poRecord; /* -------------------------------------------------------------------- */ /* Open the file, and read the header. */ /* -------------------------------------------------------------------- */ if( !oXREFFile.Open( pszFilename ) ) return FALSE; /* -------------------------------------------------------------------- */ /* Read the first record, and verify that this is an XREF record. */ /* -------------------------------------------------------------------- */ poRecord = oXREFFile.ReadRecord(); if( poRecord == NULL ) return FALSE; if( poRecord->GetStringSubfield( "XREF", 0, "MODN", 0 ) == NULL ) return FALSE; /* -------------------------------------------------------------------- */ /* Read fields of interest. */ /* -------------------------------------------------------------------- */ CPLFree( pszSystemName ); pszSystemName = CPLStrdup( poRecord->GetStringSubfield( "XREF", 0, "RSNM", 0 ) ); CPLFree( pszDatum ); pszDatum = CPLStrdup( poRecord->GetStringSubfield( "XREF", 0, "HDAT", 0 ) ); nZone = poRecord->GetIntSubfield( "XREF", 0, "ZONE", 0 ); return TRUE; }
DDFModule *SDTSTransfer::GetLayerModuleReader( int iEntry ) { DDFModule *poModuleReader; if( iEntry < 0 || iEntry >= nLayers ) { return NULL; } poModuleReader = new DDFModule; if( !poModuleReader->Open( oCATD.GetEntryFilePath( panLayerCATDEntry[iEntry] ) ) ) { delete poModuleReader; return NULL; } else { return poModuleReader; } }
GDALDataset *SDTSDataset::Open( GDALOpenInfo * poOpenInfo ) { int i; /* -------------------------------------------------------------------- */ /* Before trying SDTSOpen() we first verify that the first */ /* record is in fact a SDTS file descriptor record. */ /* -------------------------------------------------------------------- */ char *pachLeader = (char *) poOpenInfo->pabyHeader; if( poOpenInfo->nHeaderBytes < 24 ) return NULL; if( pachLeader[5] != '1' && pachLeader[5] != '2' && pachLeader[5] != '3' ) return NULL; if( pachLeader[6] != 'L' ) return NULL; if( pachLeader[8] != '1' && pachLeader[8] != ' ' ) return NULL; /* -------------------------------------------------------------------- */ /* Try opening the dataset. */ /* -------------------------------------------------------------------- */ SDTSTransfer *poTransfer = new SDTSTransfer; if( !poTransfer->Open( poOpenInfo->pszFilename ) ) { delete poTransfer; return NULL; } /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { delete poTransfer; CPLError( CE_Failure, CPLE_NotSupported, "The SDTS driver does not support update access to existing" " datasets.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Find the first raster layer. If there are none, abort */ /* returning an error. */ /* -------------------------------------------------------------------- */ SDTSRasterReader *poRL = NULL; for( i = 0; i < poTransfer->GetLayerCount(); i++ ) { if( poTransfer->GetLayerType( i ) == SLTRaster ) { poRL = poTransfer->GetLayerRasterReader( i ); break; } } if( poRL == NULL ) { delete poTransfer; CPLError( CE_Warning, CPLE_AppDefined, "%s is an SDTS transfer, but has no raster cell layers.\n" "Perhaps it is a vector transfer?\n", poOpenInfo->pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Initialize a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ SDTSDataset *poDS = new SDTSDataset(); poDS->poTransfer = poTransfer; poDS->poRL = poRL; /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ poDS->nRasterXSize = poRL->GetXSize(); poDS->nRasterYSize = poRL->GetYSize(); /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ poDS->nBands = 1; poDS->papoBands = (GDALRasterBand **) VSICalloc(sizeof(GDALRasterBand *),poDS->nBands); for( i = 0; i < poDS->nBands; i++ ) poDS->SetBand( i+1, new SDTSRasterBand( poDS, i+1, poRL ) ); /* -------------------------------------------------------------------- */ /* Try to establish the projection string. For now we only */ /* support UTM and GEO. */ /* -------------------------------------------------------------------- */ OGRSpatialReference oSRS; SDTS_XREF *poXREF = poTransfer->GetXREF(); if( EQUAL(poXREF->pszSystemName,"UTM") ) { oSRS.SetUTM( poXREF->nZone ); } else if( EQUAL(poXREF->pszSystemName,"GEO") ) { /* we set datum later */ } else oSRS.SetLocalCS( poXREF->pszSystemName ); if( oSRS.IsLocal() ) /* don't try to set datum. */; else if( EQUAL(poXREF->pszDatum,"NAS") ) oSRS.SetWellKnownGeogCS( "NAD27" ); else if( EQUAL(poXREF->pszDatum, "NAX") ) oSRS.SetWellKnownGeogCS( "NAD83" ); else if( EQUAL(poXREF->pszDatum, "WGC") ) oSRS.SetWellKnownGeogCS( "WGS72" ); else if( EQUAL(poXREF->pszDatum, "WGE") ) oSRS.SetWellKnownGeogCS( "WGS84" ); else oSRS.SetWellKnownGeogCS( "WGS84" ); oSRS.Fixup(); poDS->pszProjection = NULL; if( oSRS.exportToWkt( &poDS->pszProjection ) != OGRERR_NONE ) poDS->pszProjection = CPLStrdup(""); /* -------------------------------------------------------------------- */ /* Get metadata from the IDEN file. */ /* -------------------------------------------------------------------- */ const char* pszIDENFilePath = poTransfer->GetCATD()->GetModuleFilePath("IDEN"); if (pszIDENFilePath) { DDFModule oIDENFile; if( oIDENFile.Open( pszIDENFilePath ) ) { DDFRecord* poRecord; while( (poRecord = oIDENFile.ReadRecord()) != NULL ) { if( poRecord->GetStringSubfield( "IDEN", 0, "MODN", 0 ) == NULL ) continue; static const char* fields[][2] = { { "TITL", "TITLE" }, { "DAID", "DATASET_ID" }, { "DAST", "DATA_STRUCTURE" }, { "MPDT", "MAP_DATE" }, { "DCDT", "DATASET_CREATION_DATE" } }; for (i = 0; i < (int)sizeof(fields) / (int)sizeof(fields[0]) ; i++) { const char* pszFieldValue = poRecord->GetStringSubfield( "IDEN", 0, fields[i][0], 0 ); if ( pszFieldValue ) poDS->SetMetadataItem(fields[i][1], pszFieldValue); } break; } } } /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); return( poDS ); }
int main( int nArgc, char ** papszArgv ) { DDFModule oModule; const char *pszFilename = NULL; int bFSPTHack = FALSE; int bXML = FALSE; /* -------------------------------------------------------------------- */ /* Check arguments. */ /* -------------------------------------------------------------------- */ for( int iArg = 1; iArg < nArgc; iArg++ ) { if( EQUAL(papszArgv[iArg],"-fspt_repeating") ) bFSPTHack = TRUE; else if( EQUAL(papszArgv[iArg],"-xml") ) bXML = TRUE; else pszFilename = papszArgv[iArg]; } if( pszFilename == NULL ) { printf( "Usage: 8211dump [-xml] [-fspt_repeating] filename\n" ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Open file. */ /* -------------------------------------------------------------------- */ if( !oModule.Open( pszFilename ) ) exit( 1 ); /* -------------------------------------------------------------------- */ /* Apply FSPT hack if required. */ /* -------------------------------------------------------------------- */ if( bFSPTHack ) { DDFFieldDefn *poFSPT = oModule.FindFieldDefn( "FSPT" ); if( poFSPT == NULL ) fprintf( stderr, "unable to find FSPT field to set repeating flag.\n" ); else poFSPT->SetRepeatingFlag( TRUE ); } /* -------------------------------------------------------------------- */ /* Dump header, and all records. */ /* -------------------------------------------------------------------- */ DDFRecord *poRecord; if( bXML ) { printf("<DDFModule>\n"); int nFieldDefnCount = oModule.GetFieldCount(); for( int i = 0; i < nFieldDefnCount; i++ ) { DDFFieldDefn* poFieldDefn = oModule.GetField(i); const char* pszDataStructCode; switch( poFieldDefn->GetDataStructCode() ) { case dsc_elementary: pszDataStructCode = "elementary"; break; case dsc_vector: pszDataStructCode = "vector"; break; case dsc_array: pszDataStructCode = "array"; break; case dsc_concatenated: pszDataStructCode = "concatenated"; break; default: pszDataStructCode = "(unknown)"; break; } const char* pszDataTypeCode; switch( poFieldDefn->GetDataTypeCode() ) { case dtc_char_string: pszDataTypeCode = "char_string"; break; case dtc_implicit_point: pszDataTypeCode = "implicit_point"; break; case dtc_explicit_point: pszDataTypeCode = "explicit_point"; break; case dtc_explicit_point_scaled: pszDataTypeCode = "explicit_point_scaled"; break; case dtc_char_bit_string: pszDataTypeCode = "char_bit_string"; break; case dtc_bit_string: pszDataTypeCode = "bit_string"; break; case dtc_mixed_data_type: pszDataTypeCode = "mixed_data_type"; break; default: pszDataTypeCode = "(unknown)"; break; } printf("<DDFFieldDefn tag=\"%s\" fieldName=\"%s\" arrayDescr=\"%s\" " "formatControls=\"%s\" dataStructCode=\"%s\" dataTypeCode=\"%s\">\n", poFieldDefn->GetName(), poFieldDefn->GetDescription(), poFieldDefn->GetArrayDescr(), poFieldDefn->GetFormatControls(), pszDataStructCode, pszDataTypeCode); int nSubfieldCount = poFieldDefn->GetSubfieldCount(); for( int iSubField = 0; iSubField < nSubfieldCount; iSubField++ ) { DDFSubfieldDefn* poSubFieldDefn = poFieldDefn->GetSubfield(iSubField); printf(" <DDFSubfieldDefn name=\"%s\" format=\"%s\"/>\n", poSubFieldDefn->GetName(), poSubFieldDefn->GetFormat()); } printf("</DDFFieldDefn>\n"); } for( poRecord = oModule.ReadRecord(); poRecord != NULL; poRecord = oModule.ReadRecord() ) { printf("<DDFRecord>\n"); int nFieldCount = poRecord->GetFieldCount(); for( int iField = 0; iField < nFieldCount; iField++ ) { DDFField* poField = poRecord->GetField(iField); DDFFieldDefn* poDefn = poField->GetFieldDefn(); const char* pszFieldName = poDefn->GetName(); printf(" <DDFField name=\"%s\"", pszFieldName); if( poField->GetRepeatCount() > 1 ) printf(" repeatCount=\"%d\"", poField->GetRepeatCount()); int iOffset = 0, nLoopCount; int nRepeatCount = poField->GetRepeatCount(); const char* pachData = poField->GetData(); int nDataSize = poField->GetDataSize(); if( nRepeatCount == 1 && poDefn->GetSubfieldCount() == 0 ) { printf(" value=\"0x"); for( int i = 0; i < nDataSize - 1; i++ ) printf( "%02X", pachData[i] ); printf("\">\n"); } else printf(">\n"); for( nLoopCount = 0; nLoopCount < nRepeatCount; nLoopCount++ ) { for( int iSubField = 0; iSubField < poDefn->GetSubfieldCount(); iSubField++ ) { int nBytesConsumed; DDFSubfieldDefn* poSubFieldDefn = poDefn->GetSubfield(iSubField); const char* pszSubFieldName = poSubFieldDefn->GetName(); printf(" <DDFSubfield name=\"%s\" ", pszSubFieldName); DDFDataType eType = poSubFieldDefn->GetType(); const char* pachSubdata = pachData + iOffset; int nMaxBytes = nDataSize - iOffset; if( eType == DDFFloat ) printf("type=\"float\">%f", poSubFieldDefn->ExtractFloatData( pachSubdata, nMaxBytes, NULL ) ); else if( eType == DDFInt ) printf("type=\"integer\">%d", poSubFieldDefn->ExtractIntData( pachSubdata, nMaxBytes, NULL ) ); else if( eType == DDFBinaryString ) { int nBytes, i; GByte *pabyBString = (GByte *) poSubFieldDefn->ExtractStringData( pachSubdata, nMaxBytes, &nBytes ); printf( "type=\"binary\">0x" ); for( i = 0; i < nBytes; i++ ) printf( "%02X", pabyBString[i] ); } else { GByte* pabyString = (GByte *)poSubFieldDefn->ExtractStringData( pachSubdata, nMaxBytes, NULL ); int bBinary = FALSE; int i; for( i = 0; pabyString[i] != '\0'; i ++ ) { if( pabyString[i] < 32 || pabyString[i] > 127 ) { bBinary = TRUE; break; } } if( bBinary ) { printf( "type=\"binary\">0x" ); for( i = 0; pabyString[i] != '\0'; i ++ ) printf( "%02X", pabyString[i] ); } else { char* pszEscaped = CPLEscapeString((const char*)pabyString, -1, CPLES_XML); printf("type=\"string\">%s", pszEscaped); CPLFree(pszEscaped); } } printf("</DDFSubfield>\n"); poSubFieldDefn->GetDataLength( pachSubdata, nMaxBytes, &nBytesConsumed ); iOffset += nBytesConsumed; } } printf(" </DDFField>\n"); } printf("</DDFRecord>\n"); } printf("</DDFModule>\n"); } else { oModule.Dump( stdout ); long nStartLoc; nStartLoc = VSIFTellL( oModule.GetFP() ); for( poRecord = oModule.ReadRecord(); poRecord != NULL; poRecord = oModule.ReadRecord() ) { printf( "File Offset: %ld\n", nStartLoc ); poRecord->Dump( stdout ); nStartLoc = VSIFTellL( oModule.GetFP() ); } } oModule.Close(); #ifdef DBMALLOC malloc_dump(1); #endif }
void mk_s57() { DDFModule oModule; DDFFieldDefn *poFDefn; oModule.Initialize(); /* -------------------------------------------------------------------- */ /* Create the '0000' definition. */ /* -------------------------------------------------------------------- */ poFDefn = new DDFFieldDefn(); poFDefn->Create( "0000", "", "0001DSIDDSIDDSSI0001DSPM0001VRIDVRIDATTVVRIDVRPCVRIDVRPTVRIDSGCCVRIDSG2DVRIDSG3D0001FRIDFRIDFOIDFRIDATTFFRIDNATFFRIDFFPCFRIDFFPTFRIDFSPCFRIDFSPT", dsc_elementary, dtc_char_string ); oModule.AddField( poFDefn ); /* -------------------------------------------------------------------- */ /* Create the '0001' definition. */ /* -------------------------------------------------------------------- */ poFDefn = new DDFFieldDefn(); poFDefn->Create( "0001", "ISO 8211 Record Identifier", "", dsc_elementary, dtc_bit_string, "(b12)" ); oModule.AddField( poFDefn ); /* -------------------------------------------------------------------- */ /* Create the DSID field. */ /* -------------------------------------------------------------------- */ poFDefn = new DDFFieldDefn(); poFDefn->Create( "DSID", "Data set identification field", "", dsc_vector, dtc_mixed_data_type ); poFDefn->AddSubfield( "RCNM", "b11" ); poFDefn->AddSubfield( "RCID", "b14" ); poFDefn->AddSubfield( "EXPP", "b11" ); poFDefn->AddSubfield( "INTU", "b11" ); poFDefn->AddSubfield( "DSNM", "A" ); poFDefn->AddSubfield( "EDTN", "A" ); poFDefn->AddSubfield( "UPDN", "A" ); poFDefn->AddSubfield( "UADT", "A(8)" ); poFDefn->AddSubfield( "ISDT", "A(8)" ); poFDefn->AddSubfield( "STED", "R(4)" ); poFDefn->AddSubfield( "PRSP", "b11" ); poFDefn->AddSubfield( "PSDN", "A" ); poFDefn->AddSubfield( "PRED", "A" ); poFDefn->AddSubfield( "PROF", "b11" ); poFDefn->AddSubfield( "AGEN", "b12" ); poFDefn->AddSubfield( "COMT", "A" ); oModule.AddField( poFDefn ); /* -------------------------------------------------------------------- */ /* Create the DSSI field. */ /* -------------------------------------------------------------------- */ poFDefn = new DDFFieldDefn(); poFDefn->Create( "DSSI", "Data set structure information field", "", dsc_vector, dtc_mixed_data_type ); poFDefn->AddSubfield( "DSTR", "b11" ); poFDefn->AddSubfield( "AALL", "b11" ); poFDefn->AddSubfield( "NALL", "b11" ); poFDefn->AddSubfield( "NOMR", "b14" ); poFDefn->AddSubfield( "NOCR", "b14" ); poFDefn->AddSubfield( "NOGR", "b14" ); poFDefn->AddSubfield( "NOLR", "b14" ); poFDefn->AddSubfield( "NOIN", "b14" ); poFDefn->AddSubfield( "NOCN", "b14" ); poFDefn->AddSubfield( "NOED", "b14" ); poFDefn->AddSubfield( "NOFA", "b14" ); oModule.AddField( poFDefn ); /* -------------------------------------------------------------------- */ /* Create the DSPM field. */ /* -------------------------------------------------------------------- */ poFDefn = new DDFFieldDefn(); poFDefn->Create( "DSPM", "Data set parameter field", "", dsc_vector, dtc_mixed_data_type ); poFDefn->AddSubfield( "RCNM", "b11" ); poFDefn->AddSubfield( "RCID", "b14" ); poFDefn->AddSubfield( "HDAT", "b11" ); poFDefn->AddSubfield( "VDAT", "b11" ); poFDefn->AddSubfield( "SDAT", "b11" ); poFDefn->AddSubfield( "CSCL", "b14" ); poFDefn->AddSubfield( "DUNI", "b11" ); poFDefn->AddSubfield( "HUNI", "b11" ); poFDefn->AddSubfield( "PUNI", "b11" ); poFDefn->AddSubfield( "COUN", "b11" ); poFDefn->AddSubfield( "COMF", "b14" ); poFDefn->AddSubfield( "SOMF", "b14" ); poFDefn->AddSubfield( "COMT", "A" ); oModule.AddField( poFDefn ); /* -------------------------------------------------------------------- */ /* Create the VRID field. */ /* -------------------------------------------------------------------- */ poFDefn = new DDFFieldDefn(); poFDefn->Create( "VRID", "Vector record identifier field", "", dsc_vector, dtc_mixed_data_type ); poFDefn->AddSubfield( "RCNM", "b11" ); poFDefn->AddSubfield( "RCID", "b14" ); poFDefn->AddSubfield( "RVER", "b12" ); poFDefn->AddSubfield( "RUIN", "b11" ); oModule.AddField( poFDefn ); /* -------------------------------------------------------------------- */ /* Create the ATTV field. */ /* -------------------------------------------------------------------- */ poFDefn = new DDFFieldDefn(); poFDefn->Create( "ATTV", "Vector record attribute field", "", dsc_vector, dtc_mixed_data_type ); /* how do I mark this as repeating? */ poFDefn->AddSubfield( "ATTL", "b12" ); poFDefn->AddSubfield( "ATVL", "A" ); oModule.AddField( poFDefn ); /* -------------------------------------------------------------------- */ /* Create the SG2D field. */ /* -------------------------------------------------------------------- */ poFDefn = new DDFFieldDefn(); poFDefn->Create( "SG2D", "2-D coordinate field", "*", dsc_vector, dtc_mixed_data_type ); /* how do I mark this as repeating? */ poFDefn->AddSubfield( "YCOO", "b24" ); poFDefn->AddSubfield( "XCOO", "b24" ); oModule.AddField( poFDefn ); /* -------------------------------------------------------------------- */ /* Create the SG3D field. */ /* -------------------------------------------------------------------- */ poFDefn = new DDFFieldDefn(); poFDefn->Create( "SG3D", "3-D coordinate (sounding array) field", "*", dsc_vector, dtc_mixed_data_type ); /* how do I mark this as repeating? */ poFDefn->AddSubfield( "YCOO", "b24" ); poFDefn->AddSubfield( "XCOO", "b24" ); poFDefn->AddSubfield( "VE3D", "b24" ); oModule.AddField( poFDefn ); /* -------------------------------------------------------------------- */ // need to add: VRPC, VRPT, SGCC, FRID, FOID, ATTF, NATF, FFPC, // FFPT, FSPC, and FSPT /* -------------------------------------------------------------------- */ /* Create file. */ /* -------------------------------------------------------------------- */ oModule.Dump( stdout ); oModule.Create( "out.000" ); /* -------------------------------------------------------------------- */ /* Create a record. */ /* -------------------------------------------------------------------- */ DDFRecord *poRec = new DDFRecord( &oModule ); DDFField *poField; poField = poRec->AddField( oModule.FindFieldDefn( "0001" ) ); poRec->SetFieldRaw( poField, 0, "\1\0\036", 3 ); poField = poRec->AddField( oModule.FindFieldDefn( "DSID" ) ); poRec->SetIntSubfield ( "DSID", 0, "RCNM", 0, 10 ); poRec->SetIntSubfield ( "DSID", 0, "RCID", 0, 1 ); poRec->SetIntSubfield ( "DSID", 0, "EXPP", 0, 1 ); poRec->SetIntSubfield ( "DSID", 0, "INTU", 0, 4 ); poRec->SetStringSubfield( "DSID", 0, "DSNM", 0, "GB4X0000.000" ); poRec->SetStringSubfield( "DSID", 0, "EDTN", 0, "2" ); poRec->SetStringSubfield( "DSID", 0, "UPDN", 0, "0" ); poRec->SetStringSubfield( "DSID", 0, "UADT", 0, "20010409" ); poRec->SetStringSubfield( "DSID", 0, "ISDT", 0, "20010409" ); poRec->SetFloatSubfield ( "DSID", 0, "STED", 0, 3.1 ); poRec->SetIntSubfield ( "DSID", 0, "PRSP", 0, 1 ); poRec->SetStringSubfield( "DSID", 0, "PSDN", 0, "" ); poRec->SetStringSubfield( "DSID", 0, "PRED", 0, "2.0" ); poRec->SetIntSubfield ( "DSID", 0, "PROF", 0, 1 ); poRec->SetIntSubfield ( "DSID", 0, "AGEN", 0, 540 ); poRec->SetStringSubfield( "DSID", 0, "COMT", 0, "" ); poField = poRec->AddField( oModule.FindFieldDefn( "DSSI" ) ); poRec->SetIntSubfield ( "DSSI", 0, "DSTR", 0, 2 ); poRec->SetIntSubfield ( "DSSI", 0, "AALL", 0, 1 ); poRec->SetIntSubfield ( "DSSI", 0, "NALL", 0, 1 ); poRec->SetIntSubfield ( "DSSI", 0, "NOMR", 0, 22 ); poRec->SetIntSubfield ( "DSSI", 0, "NOCR", 0, 0 ); poRec->SetIntSubfield ( "DSSI", 0, "NOGR", 0, 2141 ); poRec->SetIntSubfield ( "DSSI", 0, "NOLR", 0, 15 ); poRec->SetIntSubfield ( "DSSI", 0, "NOIN", 0, 512 ); poRec->SetIntSubfield ( "DSSI", 0, "NOCN", 0, 2181 ); poRec->SetIntSubfield ( "DSSI", 0, "NOED", 0, 3192 ); poRec->SetIntSubfield ( "DSSI", 0, "NOFA", 0, 0 ); poRec->Write(); delete poRec; /* -------------------------------------------------------------------- */ /* Create a record. */ /* -------------------------------------------------------------------- */ poRec = new DDFRecord( &oModule ); poField = poRec->AddField( oModule.FindFieldDefn( "0001" ) ); poRec->SetFieldRaw( poField, 0, "\2\0\036", 3 ); poField = poRec->AddField( oModule.FindFieldDefn( "DSPM" ) ); poRec->SetIntSubfield ( "DSPM", 0, "RCNM", 0, 20 ); poRec->SetIntSubfield ( "DSPM", 0, "RCID", 0, 1 ); poRec->SetIntSubfield ( "DSPM", 0, "HDAT", 0, 2 ); poRec->SetIntSubfield ( "DSPM", 0, "VDAT", 0, 17 ); poRec->SetIntSubfield ( "DSPM", 0, "SDAT", 0, 23 ); poRec->SetIntSubfield ( "DSPM", 0, "CSCL", 0, 52000 ); poRec->SetIntSubfield ( "DSPM", 0, "DUNI", 0, 1 ); poRec->SetIntSubfield ( "DSPM", 0, "HUNI", 0, 1 ); poRec->SetIntSubfield ( "DSPM", 0, "PUNI", 0, 1 ); poRec->SetIntSubfield ( "DSPM", 0, "COUN", 0, 1 ); poRec->SetIntSubfield ( "DSPM", 0, "COMF", 0, 1000000 ); poRec->SetIntSubfield ( "DSPM", 0, "SOMF", 0, 10 ); poRec->Write(); delete poRec; /* -------------------------------------------------------------------- */ /* Create a record. */ /* -------------------------------------------------------------------- */ poRec = new DDFRecord( &oModule ); poField = poRec->AddField( oModule.FindFieldDefn( "0001" ) ); poRec->SetFieldRaw( poField, 0, "\3\0\036", 3 ); poField = poRec->AddField( oModule.FindFieldDefn( "VRID" ) ); poRec->SetIntSubfield ( "VRID", 0, "RCNM", 0, 110 ); poRec->SetIntSubfield ( "VRID", 0, "RCID", 0, 518 ); poRec->SetIntSubfield ( "VRID", 0, "RVER", 0, 1 ); poRec->SetIntSubfield ( "VRID", 0, "RUIN", 0, 1 ); poField = poRec->AddField( oModule.FindFieldDefn( "SG3D" ) ); poRec->SetIntSubfield ( "SG3D", 0, "YCOO", 0, -325998702 ); poRec->SetIntSubfield ( "SG3D", 0, "XCOO", 0, 612175350 ); poRec->SetIntSubfield ( "SG3D", 0, "VE3D", 0, 174 ); poRec->SetIntSubfield ( "SG3D", 0, "YCOO", 1, -325995189 ); poRec->SetIntSubfield ( "SG3D", 0, "XCOO", 1, 612228812 ); poRec->SetIntSubfield ( "SG3D", 0, "VE3D", 1, 400 ); poRec->Write(); delete poRec; }
void mk_catalog() { DDFModule oModule; DDFFieldDefn *poFDefn; oModule.Initialize(); /* -------------------------------------------------------------------- */ /* Create the '0000' definition. */ /* -------------------------------------------------------------------- */ poFDefn = new DDFFieldDefn(); poFDefn->Create( "0000", "", "0001CATD", dsc_elementary, dtc_char_string ); oModule.AddField( poFDefn ); /* -------------------------------------------------------------------- */ /* Create the '0000' definition. */ /* -------------------------------------------------------------------- */ poFDefn = new DDFFieldDefn(); poFDefn->Create( "0001", "ISO 8211 Record Identifier", "", dsc_elementary, dtc_bit_string, "(b12)" ); oModule.AddField( poFDefn ); /* -------------------------------------------------------------------- */ /* Create the CATD field. */ /* -------------------------------------------------------------------- */ poFDefn = new DDFFieldDefn(); poFDefn->Create( "CATD", "Catalog Directory field", "", dsc_vector, dtc_mixed_data_type ); poFDefn->AddSubfield( "RCNM", "A(2)" ); poFDefn->AddSubfield( "RCID", "I(10)" ); poFDefn->AddSubfield( "FILE", "A" ); poFDefn->AddSubfield( "LFIL", "A" ); poFDefn->AddSubfield( "VOLM", "A" ); poFDefn->AddSubfield( "IMPL", "A(3)" ); poFDefn->AddSubfield( "SLAT", "R" ); poFDefn->AddSubfield( "WLON", "R" ); poFDefn->AddSubfield( "NLAT", "R" ); poFDefn->AddSubfield( "ELON", "R" ); poFDefn->AddSubfield( "CRCS", "A" ); poFDefn->AddSubfield( "COMT", "A" ); oModule.AddField( poFDefn ); oModule.Dump( stdout ); oModule.Create( "out.ddf" ); /* -------------------------------------------------------------------- */ /* Create a record. */ /* -------------------------------------------------------------------- */ DDFRecord *poRec = new DDFRecord( &oModule ); DDFField *poField; poField = poRec->AddField( oModule.FindFieldDefn( "0001" ) ); poRec->SetFieldRaw( poField, 0, "\0\0\036", 3 ); poField = poRec->AddField( oModule.FindFieldDefn( "CATD" ) ); poRec->SetStringSubfield( "CATD", 0, "RCNM", 0, "CD" ); poRec->SetIntSubfield ( "CATD", 0, "RCID", 0, 1 ); poRec->SetStringSubfield( "CATD", 0, "FILE", 0, "CATALOG.030" ); poRec->SetStringSubfield( "CATD", 0, "VOLM", 0, "V01X01" ); poRec->SetStringSubfield( "CATD", 0, "IMPL", 0, "ASC" ); poRec->SetStringSubfield( "CATD", 0, "COMT", 0, "Exchange Set Catalog file" ); poRec->Write(); delete poRec; /* -------------------------------------------------------------------- */ /* Create a record. */ /* -------------------------------------------------------------------- */ poRec = new DDFRecord( &oModule ); poField = poRec->AddField( oModule.FindFieldDefn( "0001" ) ); poRec->SetFieldRaw( poField, 0, "\1\0\036", 3 ); poField = poRec->AddField( oModule.FindFieldDefn( "CATD" ) ); poRec->SetStringSubfield( "CATD", 0, "RCNM", 0, "CD" ); poRec->SetIntSubfield ( "CATD", 0, "RCID", 0, 2 ); poRec->SetStringSubfield( "CATD", 0, "FILE", 0, "No410810.000" ); poRec->SetStringSubfield( "CATD", 0, "VOLM", 0, "V01X01" ); poRec->SetStringSubfield( "CATD", 0, "IMPL", 0, "BIN" ); poRec->SetFloatSubfield ( "CATD", 0, "SLAT", 0, 59.000005 ); poRec->SetFloatSubfield ( "CATD", 0, "WLON", 0, 4.999996 ); poRec->SetFloatSubfield ( "CATD", 0, "NLAT", 0, 59.500003 ); poRec->SetFloatSubfield ( "CATD", 0, "ELON", 0, 5.499997 ); poRec->SetStringSubfield( "CATD", 0, "CRCS", 0, "555C3AD4" ); poRec->Write(); delete poRec; }
int SDTSRasterReader::Open( SDTS_CATD * poCATD, SDTS_IREF * poIREF, const char * pszModule ) { strncpy( szModule, pszModule, sizeof(szModule) ); szModule[sizeof(szModule) - 1] = '\0'; /* ==================================================================== */ /* Search the LDEF module for the requested cell module. */ /* ==================================================================== */ DDFModule oLDEF; DDFRecord *poRecord; /* -------------------------------------------------------------------- */ /* Open the LDEF module, and report failure if it is missing. */ /* -------------------------------------------------------------------- */ if( poCATD->GetModuleFilePath("LDEF") == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Can't find LDEF entry in CATD module ... " "can't treat as raster.\n" ); return FALSE; } if( !oLDEF.Open( poCATD->GetModuleFilePath("LDEF") ) ) return FALSE; /* -------------------------------------------------------------------- */ /* Read each record, till we find what we want. */ /* -------------------------------------------------------------------- */ while( (poRecord = oLDEF.ReadRecord() ) != NULL ) { const char* pszCandidateModule = poRecord->GetStringSubfield("LDEF",0,"CMNM",0); if( pszCandidateModule == NULL ) { poRecord = NULL; break; } if( EQUAL(pszCandidateModule, pszModule) ) break; } if( poRecord == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Can't find module `%s' in LDEF file.\n", pszModule ); return FALSE; } /* -------------------------------------------------------------------- */ /* Extract raster dimensions, and origin offset (0/1). */ /* -------------------------------------------------------------------- */ nXSize = poRecord->GetIntSubfield( "LDEF", 0, "NCOL", 0 ); nYSize = poRecord->GetIntSubfield( "LDEF", 0, "NROW", 0 ); nXStart = poRecord->GetIntSubfield( "LDEF", 0, "SOCI", 0 ); nYStart = poRecord->GetIntSubfield( "LDEF", 0, "SORI", 0 ); /* -------------------------------------------------------------------- */ /* Get the point in the pixel that the origin defines. We only */ /* support top left and center. */ /* -------------------------------------------------------------------- */ const char* pszINTR = poRecord->GetStringSubfield( "LDEF", 0, "INTR", 0 ); if( pszINTR == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Can't find INTR subfield of LDEF field" ); return FALSE; } strcpy( szINTR, pszINTR ); if( EQUAL(szINTR,"") ) strcpy( szINTR, "CE" ); if( !EQUAL(szINTR,"CE") && !EQUAL(szINTR,"TL") ) { CPLError( CE_Warning, CPLE_AppDefined, "Unsupported INTR value of `%s', assume CE.\n" "Positions may be off by one pixel.\n", szINTR ); strcpy( szINTR, "CE" ); } /* -------------------------------------------------------------------- */ /* Record the LDEF record number we used so we can find the */ /* corresponding RSDF record. */ /* -------------------------------------------------------------------- */ int nLDEF_RCID; nLDEF_RCID = poRecord->GetIntSubfield( "LDEF", 0, "RCID", 0 ); oLDEF.Close(); /* ==================================================================== */ /* Search the RSDF module for the requested cell module. */ /* ==================================================================== */ DDFModule oRSDF; /* -------------------------------------------------------------------- */ /* Open the RSDF module, and report failure if it is missing. */ /* -------------------------------------------------------------------- */ if( poCATD->GetModuleFilePath("RSDF") == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Can't find RSDF entry in CATD module ... " "can't treat as raster.\n" ); return FALSE; } if( !oRSDF.Open( poCATD->GetModuleFilePath("RSDF") ) ) return FALSE; /* -------------------------------------------------------------------- */ /* Read each record, till we find what we want. */ /* -------------------------------------------------------------------- */ while( (poRecord = oRSDF.ReadRecord() ) != NULL ) { if( poRecord->GetIntSubfield("LYID",0,"RCID",0) == nLDEF_RCID ) break; } if( poRecord == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Can't find LDEF:%d record in RSDF file.\n", nLDEF_RCID ); return FALSE; } /* -------------------------------------------------------------------- */ /* Establish the raster pixel/line to georef transformation. */ /* -------------------------------------------------------------------- */ double dfZ; if( poRecord->FindField( "SADR" ) == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Can't find SADR field in RSDF record.\n" ); return FALSE; } poIREF->GetSADR( poRecord->FindField( "SADR" ), 1, adfTransform + 0, adfTransform + 3, &dfZ ); adfTransform[1] = poIREF->dfXRes; adfTransform[2] = 0.0; adfTransform[4] = 0.0; adfTransform[5] = -1 * poIREF->dfYRes; /* -------------------------------------------------------------------- */ /* If the origin is the center of the pixel, then shift it back */ /* half a pixel to the top left of the top left. */ /* -------------------------------------------------------------------- */ if( EQUAL(szINTR,"CE") ) { adfTransform[0] -= adfTransform[1] * 0.5; adfTransform[3] -= adfTransform[5] * 0.5; } /* -------------------------------------------------------------------- */ /* Verify some other assumptions. */ /* -------------------------------------------------------------------- */ const char *pszString; pszString = poRecord->GetStringSubfield( "RSDF", 0, "OBRP", 0); if( pszString == NULL ) pszString = ""; if( !EQUAL(pszString,"G2") ) { CPLError( CE_Failure, CPLE_AppDefined, "OBRP value of `%s' not expected 2D raster code (G2).\n", pszString ); return FALSE; } pszString = poRecord->GetStringSubfield( "RSDF", 0, "SCOR", 0); if( pszString == NULL ) pszString = ""; if( !EQUAL(pszString,"TL") ) { CPLError( CE_Warning, CPLE_AppDefined, "SCOR (origin) is `%s' instead of expected top left.\n" "Georef coordinates will likely be incorrect.\n", pszString ); } oRSDF.Close(); /* -------------------------------------------------------------------- */ /* For now we will assume that the block size is one scanline. */ /* We will blow a gasket later while reading the cell file if */ /* this isn't the case. */ /* */ /* This isn't a very flexible raster implementation! */ /* -------------------------------------------------------------------- */ nXBlockSize = nXSize; nYBlockSize = 1; /* ==================================================================== */ /* Fetch the data type used for the raster, and the units from */ /* the data dictionary/schema record (DDSH). */ /* ==================================================================== */ DDFModule oDDSH; /* -------------------------------------------------------------------- */ /* Open the DDSH module, and report failure if it is missing. */ /* -------------------------------------------------------------------- */ if( poCATD->GetModuleFilePath("DDSH") == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Can't find DDSH entry in CATD module ... " "can't treat as raster.\n" ); return FALSE; } if( !oDDSH.Open( poCATD->GetModuleFilePath("DDSH") ) ) return FALSE; /* -------------------------------------------------------------------- */ /* Read each record, till we find what we want. */ /* -------------------------------------------------------------------- */ while( (poRecord = oDDSH.ReadRecord() ) != NULL ) { const char* pszName = poRecord->GetStringSubfield("DDSH",0,"NAME",0); if( pszName == NULL ) { poRecord = NULL; break; } if( EQUAL(pszName,pszModule) ) break; } if( poRecord == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Can't find DDSH record for %s.\n", pszModule ); return FALSE; } /* -------------------------------------------------------------------- */ /* Get some values we are interested in. */ /* -------------------------------------------------------------------- */ if( poRecord->GetStringSubfield("DDSH",0,"FMT",0) != NULL ) strcpy( szFMT, poRecord->GetStringSubfield("DDSH",0,"FMT",0) ); else strcpy( szFMT, "BUI16" ); if( poRecord->GetStringSubfield("DDSH",0,"UNIT",0) != NULL ) strcpy( szUNITS, poRecord->GetStringSubfield("DDSH",0,"UNIT",0) ); else strcpy( szUNITS, "METERS" ); if( poRecord->GetStringSubfield("DDSH",0,"ATLB",0) != NULL ) strcpy( szLabel, poRecord->GetStringSubfield("DDSH",0,"ATLB",0) ); else strcpy( szLabel, "" ); /* -------------------------------------------------------------------- */ /* Open the cell file. */ /* -------------------------------------------------------------------- */ return( oDDFModule.Open( poCATD->GetModuleFilePath(pszModule) ) ); }
int main( int nArgc, char ** papszArgv ) { DDFModule oModule; const char *pszFilename = nullptr; int bFSPTHack = FALSE; for( int iArg = 1; iArg < nArgc; iArg++ ) { if( EQUAL(papszArgv[iArg],"-fspt_repeating") ) bFSPTHack = TRUE; else pszFilename = papszArgv[iArg]; } if( pszFilename == nullptr ) { printf( "Usage: 8211view filename\n" ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Open the file. Note that by default errors are reported to */ /* stderr, so we don't bother doing it ourselves. */ /* -------------------------------------------------------------------- */ if( !oModule.Open( pszFilename ) ) { exit( 1 ); } if( bFSPTHack ) { DDFFieldDefn *poFSPT = oModule.FindFieldDefn( "FSPT" ); if( poFSPT == nullptr ) fprintf( stderr, "unable to find FSPT field to set repeating flag.\n" ); else poFSPT->SetRepeatingFlag( TRUE ); } /* -------------------------------------------------------------------- */ /* Loop reading records till there are none left. */ /* -------------------------------------------------------------------- */ DDFRecord *poRecord = nullptr; int iRecord = 0; while( (poRecord = oModule.ReadRecord()) != nullptr ) { printf( "Record %d (%d bytes)\n", ++iRecord, poRecord->GetDataSize() ); /* ------------------------------------------------------------ */ /* Loop over each field in this particular record. */ /* ------------------------------------------------------------ */ for( int iField = 0; iField < poRecord->GetFieldCount(); iField++ ) { DDFField *poField = poRecord->GetField( iField ); ViewRecordField( poField ); } } }
int main(int nArgc, char* papszArgv[]) { const char *pszFilename = NULL, *pszOutFilename = NULL; DDFModule oModule; /* -------------------------------------------------------------------- */ /* Check arguments. */ /* -------------------------------------------------------------------- */ for( int iArg = 1; iArg < nArgc; iArg++ ) { if( pszFilename == NULL ) pszFilename = papszArgv[iArg]; else if( pszOutFilename == NULL ) pszOutFilename = papszArgv[iArg]; else { pszFilename = NULL; break; } } if( pszFilename == NULL ) { printf( "Usage: 8211createfromxml filename.xml outfilename\n" ); exit( 1 ); } CPLXMLNode* poRoot = CPLParseXMLFile( pszFilename ); if( poRoot == NULL ) { fprintf(stderr, "Cannot parse XML file '%s'\n", pszFilename); exit( 1 ); } CPLXMLNode* poXMLDDFModule = CPLSearchXMLNode(poRoot, "=DDFModule"); if( poXMLDDFModule == NULL ) { fprintf(stderr, "Cannot find DDFModule node in XML file '%s'\n", pszFilename); exit( 1 ); } /* Compute the size of the DDFField tag */ CPLXMLNode* psIter = poXMLDDFModule->psChild; int nSizeFieldTag = 0; while( psIter != NULL ) { if( psIter->eType == CXT_Element && strcmp(psIter->pszValue, "DDFFieldDefn") == 0 ) { const char* pszTag = CPLGetXMLValue(psIter, "tag", ""); if( nSizeFieldTag == 0 ) nSizeFieldTag = (int)strlen(pszTag); else if( nSizeFieldTag != (int)strlen(pszTag) ) { fprintf(stderr, "All fields have not the same tag size\n"); exit( 1 ); } } psIter = psIter->psNext; } char chInterchangeLevel = '3'; char chLeaderIden = 'L'; char chCodeExtensionIndicator = 'E'; char chVersionNumber = '1'; char chAppIndicator = ' '; const char *pszExtendedCharSet = " ! "; int nSizeFieldLength = 3; int nSizeFieldPos = 4; chInterchangeLevel = CPLGetXMLValue(poXMLDDFModule, "_interchangeLevel", CPLSPrintf("%c", chInterchangeLevel))[0]; chLeaderIden = CPLGetXMLValue(poXMLDDFModule, "_leaderIden", CPLSPrintf("%c", chLeaderIden))[0]; chCodeExtensionIndicator = CPLGetXMLValue(poXMLDDFModule, "_inlineCodeExtensionIndicator", CPLSPrintf("%c", chCodeExtensionIndicator))[0]; chVersionNumber = CPLGetXMLValue(poXMLDDFModule, "_versionNumber", CPLSPrintf("%c", chVersionNumber))[0]; chAppIndicator = CPLGetXMLValue(poXMLDDFModule, "_appIndicator", CPLSPrintf("%c", chAppIndicator))[0]; char szExtendedCharSet[4]; snprintf(szExtendedCharSet, sizeof(szExtendedCharSet), "%s", CPLGetXMLValue(poXMLDDFModule, "_extendedCharSet", pszExtendedCharSet)); pszExtendedCharSet = szExtendedCharSet; nSizeFieldLength = atoi(CPLGetXMLValue(poXMLDDFModule, "_sizeFieldLength", CPLSPrintf("%d", nSizeFieldLength))); nSizeFieldPos = atoi(CPLGetXMLValue(poXMLDDFModule, "_sizeFieldPos", CPLSPrintf("%d", nSizeFieldPos))); nSizeFieldTag = atoi(CPLGetXMLValue(poXMLDDFModule, "_sizeFieldTag", CPLSPrintf("%d", nSizeFieldTag))); oModule.Initialize(chInterchangeLevel, chLeaderIden, chCodeExtensionIndicator, chVersionNumber, chAppIndicator, pszExtendedCharSet, nSizeFieldLength, nSizeFieldPos, nSizeFieldTag); oModule.SetFieldControlLength(atoi(CPLGetXMLValue(poXMLDDFModule, "_fieldControlLength", CPLSPrintf("%d", oModule.GetFieldControlLength())))); int bCreated = FALSE; /* Create DDFFieldDefn and DDFRecord elements */ psIter = poXMLDDFModule->psChild; while( psIter != NULL ) { if( psIter->eType == CXT_Element && strcmp(psIter->pszValue, "DDFFieldDefn") == 0 ) { DDFFieldDefn* poFDefn = new DDFFieldDefn(); DDF_data_struct_code eStructCode = dsc_elementary; const char* pszStructCode = CPLGetXMLValue(psIter, "dataStructCode", ""); if( strcmp(pszStructCode, "elementary") == 0 ) eStructCode = dsc_elementary; else if( strcmp(pszStructCode, "vector") == 0 ) eStructCode = dsc_vector; else if( strcmp(pszStructCode, "array") == 0 ) eStructCode = dsc_array; else if( strcmp(pszStructCode, "concatenated") == 0 ) eStructCode = dsc_concatenated; DDF_data_type_code eTypeCode = dtc_char_string; const char* pszTypeCode = CPLGetXMLValue(psIter, "dataTypeCode", ""); if( strcmp(pszTypeCode, "char_string") == 0 ) eTypeCode = dtc_char_string; else if( strcmp(pszTypeCode, "implicit_point") == 0 ) eTypeCode = dtc_implicit_point; else if( strcmp(pszTypeCode, "explicit_point") == 0 ) eTypeCode = dtc_explicit_point; else if( strcmp(pszTypeCode, "explicit_point_scaled") == 0 ) eTypeCode = dtc_explicit_point_scaled; else if( strcmp(pszTypeCode, "char_bit_string") == 0 ) eTypeCode = dtc_char_bit_string; else if( strcmp(pszTypeCode, "bit_string") == 0 ) eTypeCode = dtc_bit_string; else if( strcmp(pszTypeCode, "mixed_data_type") == 0 ) eTypeCode = dtc_mixed_data_type; const char* pszFormatControls = CPLGetXMLValue(psIter, "formatControls", NULL); if( eStructCode != dsc_elementary ) pszFormatControls = NULL; const char* pszArrayDescr = CPLGetXMLValue(psIter, "arrayDescr", ""); if( eStructCode == dsc_vector ) pszArrayDescr = ""; else if( eStructCode == dsc_array ) pszArrayDescr = "*"; poFDefn->Create( CPLGetXMLValue(psIter, "tag", ""), CPLGetXMLValue(psIter, "fieldName", ""), pszArrayDescr, eStructCode, eTypeCode, pszFormatControls ); CPLXMLNode* psSubIter = psIter->psChild; while( psSubIter != NULL ) { if( psSubIter->eType == CXT_Element && strcmp(psSubIter->pszValue, "DDFSubfieldDefn") == 0 ) { poFDefn->AddSubfield( CPLGetXMLValue(psSubIter, "name", ""), CPLGetXMLValue(psSubIter, "format", "") ); } psSubIter = psSubIter->psNext; } pszFormatControls = CPLGetXMLValue(psIter, "formatControls", NULL); if( pszFormatControls ) poFDefn->SetFormatControls(pszFormatControls); oModule.AddField( poFDefn ); } else if( psIter->eType == CXT_Element && strcmp(psIter->pszValue, "DDFRecord") == 0 ) { //const bool bFirstRecord = !bCreated; if( !bCreated ) { oModule.Create( pszOutFilename ); bCreated = TRUE; } DDFRecord *poRec = new DDFRecord( &oModule ); std::map<std::string, int> oMapField; //if( !bFirstRecord ) // poRec->SetReuseHeader(atoi(CPLGetXMLValue(psIter, "reuseHeader", CPLSPrintf("%d", poRec->GetReuseHeader())))); poRec->SetSizeFieldLength(atoi(CPLGetXMLValue(psIter, "_sizeFieldLength", CPLSPrintf("%d", poRec->GetSizeFieldLength())))); poRec->SetSizeFieldPos(atoi(CPLGetXMLValue(psIter, "_sizeFieldPos", CPLSPrintf("%d", poRec->GetSizeFieldPos())))); poRec->SetSizeFieldTag(atoi(CPLGetXMLValue(psIter, "_sizeFieldTag", CPLSPrintf("%d", poRec->GetSizeFieldTag())))); CPLXMLNode* psSubIter = psIter->psChild; while( psSubIter != NULL ) { if( psSubIter->eType == CXT_Element && strcmp(psSubIter->pszValue, "DDFField") == 0 ) { const char* pszFieldName = CPLGetXMLValue(psSubIter, "name", ""); DDFFieldDefn* poFieldDefn = oModule.FindFieldDefn( pszFieldName ); if( poFieldDefn == NULL ) { fprintf(stderr, "Can't find field '%s'\n", pszFieldName ); exit(1); } int nFieldOcc = oMapField[pszFieldName]; oMapField[pszFieldName] ++ ; DDFField *poField = poRec->AddField( poFieldDefn ); const char* pszValue = CPLGetXMLValue(psSubIter, "value", NULL); if( pszValue != NULL && STARTS_WITH(pszValue, "0x") ) { pszValue += 2; int nDataLen = (int)strlen(pszValue) / 2; char* pabyData = (char*) malloc(nDataLen); for(int i=0;i<nDataLen;i++) { char c; int nHigh, nLow; c = pszValue[2*i]; if( c >= 'A' && c <= 'F' ) nHigh = 10 + c - 'A'; else nHigh = c - '0'; c = pszValue[2*i + 1]; if( c >= 'A' && c <= 'F' ) nLow = 10 + c - 'A'; else nLow = c - '0'; pabyData[i] = (nHigh << 4) + nLow; } poRec->SetFieldRaw( poField, nFieldOcc, (const char *) pabyData, nDataLen ); free(pabyData); } else { CPLXMLNode* psSubfieldIter = psSubIter->psChild; std::map<std::string, int> oMapSubfield; while( psSubfieldIter != NULL ) { if( psSubfieldIter->eType == CXT_Element && strcmp(psSubfieldIter->pszValue, "DDFSubfield") == 0 ) { const char* pszSubfieldName = CPLGetXMLValue(psSubfieldIter, "name", ""); const char* pszSubfieldType = CPLGetXMLValue(psSubfieldIter, "type", ""); const char* pszSubfieldValue = CPLGetXMLValue(psSubfieldIter, NULL, ""); int nOcc = oMapSubfield[pszSubfieldName]; oMapSubfield[pszSubfieldName] ++ ; if( strcmp(pszSubfieldType, "float") == 0 ) { poRec->SetFloatSubfield( pszFieldName, nFieldOcc, pszSubfieldName, nOcc, CPLAtof(pszSubfieldValue) ); } else if( strcmp(pszSubfieldType, "integer") == 0 ) { poRec->SetIntSubfield( pszFieldName, nFieldOcc, pszSubfieldName, nOcc, atoi(pszSubfieldValue) ); } else if( strcmp(pszSubfieldType, "string") == 0 ) { poRec->SetStringSubfield( pszFieldName, nFieldOcc, pszSubfieldName, nOcc, pszSubfieldValue ); } else if( strcmp(pszSubfieldType, "binary") == 0 && STARTS_WITH(pszSubfieldValue, "0x") ) { pszSubfieldValue += 2; int nDataLen = (int)strlen(pszSubfieldValue) / 2; char* pabyData = (char*) malloc(nDataLen); for(int i=0;i<nDataLen;i++) { char c; int nHigh, nLow; c = pszSubfieldValue[2*i]; if( c >= 'A' && c <= 'F' ) nHigh = 10 + c - 'A'; else nHigh = c - '0'; c = pszSubfieldValue[2*i + 1]; if( c >= 'A' && c <= 'F' ) nLow = 10 + c - 'A'; else nLow = c - '0'; pabyData[i] = (nHigh << 4) + nLow; } poRec->SetStringSubfield( pszFieldName, nFieldOcc, pszSubfieldName, nOcc, pabyData, nDataLen ); free(pabyData); } } psSubfieldIter = psSubfieldIter->psNext; } } } psSubIter = psSubIter->psNext; } poRec->Write(); delete poRec; } psIter = psIter->psNext; } CPLDestroyXMLNode(poRoot); oModule.Close(); return 0; }