Search code examples
c++gdal

Reading NITF file using GDAL C++


I need to write a NITF file using GDAL C++ libraries. I am able to open the file but unable to read NITF header fields (e.g FTITLE, CLEVEL etc). If anybody is having a sample code, kindly post. Also, my code is:

GDALDataset*    poDataset;
GDALAllRegister();
poDataset = (GDALDataset *)GDALOpen("i_3001a.ntf", GA_ReadOnly);
if (poDataset == NULL)
{
  std::cout << "Unable to open the file" << std::endl;
  return 0;
}


printf("Driver: %s/%s\n",
    poDataset->GetDriver()->GetDescription(),
    poDataset->GetDriver()->GetMetadataItem(GDAL_DMD_LONGNAME));
printf("Size is %dx%dx%d\n",
    poDataset->GetRasterXSize(), poDataset->GetRasterYSize(),
    poDataset->GetRasterCount());



GDALDriver* poDriver = poDataset->GetDriver();

char** papszMetadata = NULL;
papszMetadata = poDataset->GetMetadata("NITF_METADATA");
if (papszMetadata == NULL)
{
    std::cout << "Unable to get metadata" << std::endl;
    return 0;
}

Now, how to extract the individual fields from the metadata. Also, help in reading image blocks. Any good site shall also help

Thanks


Solution

  • If you want just the standard NITF header fields, you can get the list of fields by calling...

    gdalinfo -mdd all 'i_3001a.ntf'
    

    That will give a big list of Key/Value pairs. The image you provided is from the DOD's reference page, so here is the output on that file...

    
    Driver: NITF/National Imagery Transmission Format
    Files: i_3001a.ntf
    Size is 1024, 1024
    Coordinate System is:
    GEOGCRS["WGS 84",
        DATUM["World Geodetic System 1984",
            ELLIPSOID["WGS 84",6378137,298.257223563,
                LENGTHUNIT["metre",1]]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["degree",0.0174532925199433]],
        CS[ellipsoidal,2],
            AXIS["geodetic latitude (Lat)",north,
                ORDER[1],
                ANGLEUNIT["degree",0.0174532925199433]],
            AXIS["geodetic longitude (Lon)",east,
                ORDER[2],
                ANGLEUNIT["degree",0.0174532925199433]],
        ID["EPSG",4326]]
    Data axis to CRS axis mapping: 2,1
    Origin = (84.999999864233729,32.983333469099598)
    Pixel Size = (0.000000271532530,-0.000000271532530)
    Metadata:
      NITF_ABPP=08
      NITF_CCS_COLUMN=0
      NITF_CCS_ROW=0
      NITF_CLEVEL=03
      NITF_ENCRYP=0
      NITF_FBKGC=255,255,255
      NITF_FDT=19971217102630
      NITF_FHDR=NITF02.10
      NITF_FSCATP=
      NITF_FSCAUT=
      NITF_FSCLAS=U
      NITF_FSCLSY=
      NITF_FSCLTX=
      NITF_FSCODE=
      NITF_FSCOP=00000
      NITF_FSCPYS=00000
      NITF_FSCRSN=
      NITF_FSCTLH=
      NITF_FSCTLN=
      NITF_FSDCDT=
      NITF_FSDCTP=
      NITF_FSDCXM=
      NITF_FSDG=
      NITF_FSDGDT=
      NITF_FSREL=
      NITF_FSSRDT=
      NITF_FTITLE=Checks an uncompressed 1024x1024 8 bit mono image with GEOcentric data. Airfield
      NITF_IALVL=0
      NITF_IC=NC
      NITF_ICAT=VIS
      NITF_ICORDS=G
      NITF_IDATIM=19961217102630
      NITF_IDLVL=1
      NITF_IGEOLO=325900N0850000E325900N0850001E325859N0850001E325859N0850000E
      NITF_IID1=Missing ID
      NITF_IID2=- BASE IMAGE -
      NITF_ILOC_COLUMN=0
      NITF_ILOC_ROW=0
      NITF_IMAG=1.0 
      NITF_IMODE=B
      NITF_IREP=MONO
      NITF_ISCATP=
      NITF_ISCAUT=
      NITF_ISCLAS=U
      NITF_ISCLSY=
      NITF_ISCLTX=
      NITF_ISCODE=
      NITF_ISCRSN=
      NITF_ISCTLH=
      NITF_ISCTLN=
      NITF_ISDCDT=
      NITF_ISDCTP=
      NITF_ISDCXM=
      NITF_ISDG=
      NITF_ISDGDT=
      NITF_ISORCE=Unknown
      NITF_ISREL=
      NITF_ISSRDT=
      NITF_ONAME=JITC Fort Huachuca, AZ
      NITF_OPHONE=(520) 538-5458
      NITF_OSTAID=i_3001a
      NITF_PJUST=R
      NITF_PVTYPE=INT
      NITF_STYPE=BF01
      NITF_TGTID=
    Metadata (DERIVED_SUBDATASETS):
      DERIVED_SUBDATASET_1_NAME=DERIVED_SUBDATASET:LOGAMPLITUDE:i_3001a.ntf
      DERIVED_SUBDATASET_1_DESC=log10 of amplitude of input bands from i_3001a.ntf
    Metadata (NITF_METADATA):
      NITFFileHeader=000404 TklURjAyLjEwMDNCRjAxaV8zMDAxYSAgIDE5OTcxMjE3MTAyNjMwQ2hlY2tzIGFuIHVuY29tcHJlc3NlZCAxMDI0eDEwMjQgOCBiaXQgbW9ubyBpbWFnZSB3aXRoIEdFT2NlbnRyaWMgZGF0YS4gQWlyZmllbGRVICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAwMDAwMDAwMDAw////SklUQyBGb3J0IEh1YWNodWNhLCBBWiAgKDUyMCkgNTM4LTU0NTggICAgMDAwMDAxMDQ5NDc5MDAwNDA0MDAxMDAwNDk5MDAwMTA0ODU3NjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA=
      NITFImageSubheader=499 SU1NaXNzaW5nIElEMTk5NjEyMTcxMDI2MzAgICAgICAgICAgICAgICAgIC0gQkFTRSBJTUFHRSAtICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwVW5rbm93biAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMDAwMDEwMjQwMDAwMTAyNElOVE1PTk8gICAgVklTICAgICAwOFJHMzI1OTAwTjA4NTAwMDBFMzI1OTAwTjA4NTAwMDFFMzI1ODU5TjA4NTAwMDFFMzI1ODU5TjA4NTAwMDBFME5DMU0gICAgICAgTiAgIDAwQjAwMDEwMDAxMTAyNDEwMjQwODAwMTAwMDAwMDAwMDAwMDAxLjAgMDAwMDAwMDAwMA==
    Metadata (CGM):
      SEGMENT_COUNT=0
    Corner Coordinates:
    Upper Left  (  84.9999999,  32.9833335) ( 85d 0' 0.00"E, 32d59' 0.00"N)
    Lower Left  (  84.9999999,  32.9830554) ( 85d 0' 0.00"E, 32d58'59.00"N)
    Upper Right (  85.0002779,  32.9833335) ( 85d 0' 1.00"E, 32d59' 0.00"N)
    Lower Right (  85.0002779,  32.9830554) ( 85d 0' 1.00"E, 32d58'59.00"N)
    Center      (  85.0001389,  32.9831944) ( 85d 0' 0.50"E, 32d58'59.50"N)
    Band 1 Block=1024x1 Type=Byte, ColorInterp=Gray
    

    Then you can call them directly or in bulk...

    #include <iostream>
    #include <gdal/gdal.h>
    #include <gdal/gdal_priv.h>
    
    int main( int argc, char* argv[] )
    {
        GDALDataset*  poDataset;
        GDALAllRegister();
        poDataset = (GDALDataset *)GDALOpen("i_3001a.ntf", GA_ReadOnly);
        if (poDataset == NULL)
        {
            std::cout << "Unable to open the file" << std::endl;
            return 0;
        }
    
        printf( "Driver: %s/%s\n",
                poDataset->GetDriver()->GetDescription(),
                poDataset->GetDriver()->GetMetadataItem(GDAL_DMD_LONGNAME));
        printf( "Size is %dx%dx%d\n",
                poDataset->GetRasterXSize(), 
                poDataset->GetRasterYSize(),
                poDataset->GetRasterCount() );
    
    
        GDALDriver* poDriver = poDataset->GetDriver();
    
        char** papszMetadata = NULL;
    
        // Bulk Call
        papszMetadata = poDataset->GetMetadata( nullptr );
        if (papszMetadata == NULL)
        {
            std::cout << "Unable to get metadata" << std::endl;
            return 0;
        }
        else
        {
            int counter = 0;
            while( papszMetadata[counter] != nullptr )
            {
                std::cout << "Item: " << papszMetadata[counter] << std::endl;
                counter++;
            }
        }
    
        // Specific item
        std::cout << std::endl;
        std::cout << "NITF_ONAME: " << poDataset->GetMetadataItem( "NITF_ONAME" ) << 
        std::endl;
    
    
        return 0;
    }
    

    Here is the output of this slight mod to your code...

    Driver: NITF/National Imagery Transmission Format
    Size is 1024x1024x1
    Item: NITF_ABPP=08
    Item: NITF_CCS_COLUMN=0
    Item: NITF_CCS_ROW=0
    Item: NITF_CLEVEL=03
    Item: NITF_ENCRYP=0
    Item: NITF_FBKGC=255,255,255
    Item: NITF_FDT=19971217102630
    Item: NITF_FHDR=NITF02.10
    Item: NITF_FSCATP=
    Item: NITF_FSCAUT=
    Item: NITF_FSCLAS=U
    Item: NITF_FSCLSY=
    Item: NITF_FSCLTX=
    Item: NITF_FSCODE=
    Item: NITF_FSCOP=00000
    Item: NITF_FSCPYS=00000
    Item: NITF_FSCRSN=
    Item: NITF_FSCTLH=
    Item: NITF_FSCTLN=
    Item: NITF_FSDCDT=
    Item: NITF_FSDCTP=
    Item: NITF_FSDCXM=
    Item: NITF_FSDG=
    Item: NITF_FSDGDT=
    Item: NITF_FSREL=
    Item: NITF_FSSRDT=
    Item: NITF_FTITLE=Checks an uncompressed 1024x1024 8 bit mono image with GEOcentric data. Airfield
    Item: NITF_IALVL=0
    Item: NITF_IC=NC
    Item: NITF_ICAT=VIS
    Item: NITF_ICORDS=G
    Item: NITF_IDATIM=19961217102630
    Item: NITF_IDLVL=1
    Item: NITF_IGEOLO=325900N0850000E325900N0850001E325859N0850001E325859N0850000E
    Item: NITF_IID1=Missing ID
    Item: NITF_IID2=- BASE IMAGE -
    Item: NITF_ILOC_COLUMN=0
    Item: NITF_ILOC_ROW=0
    Item: NITF_IMAG=1.0 
    Item: NITF_IMODE=B
    Item: NITF_IREP=MONO
    Item: NITF_ISCATP=
    Item: NITF_ISCAUT=
    Item: NITF_ISCLAS=U
    Item: NITF_ISCLSY=
    Item: NITF_ISCLTX=
    Item: NITF_ISCODE=
    Item: NITF_ISCRSN=
    Item: NITF_ISCTLH=
    Item: NITF_ISCTLN=
    Item: NITF_ISDCDT=
    Item: NITF_ISDCTP=
    Item: NITF_ISDCXM=
    Item: NITF_ISDG=
    Item: NITF_ISDGDT=
    Item: NITF_ISORCE=Unknown
    Item: NITF_ISREL=
    Item: NITF_ISSRDT=
    Item: NITF_ONAME=JITC Fort Huachuca, AZ
    Item: NITF_OPHONE=(520) 538-5458
    Item: NITF_OSTAID=i_3001a
    Item: NITF_PJUST=R
    Item: NITF_PVTYPE=INT
    Item: NITF_STYPE=BF01
    Item: NITF_TGTID=
    
    NITF_ONAME: JITC Fort Huachuca, AZ
    

    WARNING: This doesn't work for Tagged-Record-Extensions (TREs), that requires a little more digging.