GDAL库扩展Landsat系列MTL文件格式支持

时间:2023-01-04 16:04:32

Landsat系列卫星提供的数据,一般都是每个波段一个tif文件,然后外加一个MTL.txt的元数据文件,使用gdal可以直接打开每个波段的tif文件,但是有时候想在打开tif数据的同时能够自动读取MTL文件里面的元数据信息,这个时候就只能自己再解析这个文件了。比较麻烦,下面就是针对这种情况,直接在gdal库里面扩展一种支持landsat的mtl的格式,直接打开mtl文件的同时自动打开tif数据以及元数据。

关于扩展GDAL库可以参考我之前写的CNSDTF格式扩展,以及gdal的官网说明,网址为http://www.gdal.org/gdal_drivertut.html。

首先我们看一下Landsat的数据目录格式,以Landsat8数据为例,如下图所示:

GDAL库扩展Landsat系列MTL文件格式支持

Landsat8一共有11个波段,里面包含12个tif文件和一个txt文件,Landsat8包括两个传感器,分别是OLI和TIRS,其中OLI传感器有9个光谱波段,空间分辨率为15m(全色波段1个)和30m(多光谱波段8个),成像幅宽为185km。 TIRS有2个热红外波段,空间分辨率为30m,所以一共11个波段,此外还有一个BQA的tif不太清楚干啥的。

知道了数据的类别,那么我们可以参考HDF数据的样子,将Landsat8的数据归类为4个子数据集,第一个OLI全色数据,第二个OLI多光谱数据,第三个TIRS数据,第四个就是BQA数据。

下面是Landsat的实现源码,将其放到frmts\landsat目录,然后参考官网的说明编写make文件等,重新编译gdal库即可。

/******************************************************************************
* $Id: landsatdataset.cpp 27044 2014-03-16 23:41:27Z rouault $
*
* Project: Landsat 7/8 _MTL.TXT Driver
* Purpose: Implementation of the LandsatDataset class.
* Author: Minlu Li, liminlu0314@163.com
*
******************************************************************************
* Copyright (c) 2015, Minlu Li
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
****************************************************************************/ #include "gdal_pam.h"
#include "gdal_proxy.h"
#include "ogr_spatialref.h"
#include "cpl_string.h"
#include "vrtdataset.h"
#include "cpl_multiproc.h"
#include "cplkeywordparser.h" enum Satellite // Satellites:
{
LANDSAT7, // Landsat 7
LANDSAT8 // Landsat 8
}; /************************************************************************/
/* ==================================================================== */
/* LandsatDataset */
/* ==================================================================== */
/************************************************************************/ class CPL_DLL LandsatDataset : public GDALPamDataset
{
VRTDataset *poVRTDS;
std::vector<GDALDataset *> apoTifDS; protected:
virtual int CloseDependentDatasets(); public:
LandsatDataset();
~LandsatDataset(); virtual char **GetFileList(void); static GDALDataset *Open( GDALOpenInfo * );
static int Identify( GDALOpenInfo *poOpenInfo );
static int ParserLandsat7( const char* pszMtlFile, char **papszMetaInfo, int nSubdataset, LandsatDataset **ppoDS );
static int ParserLandsat8( const char* pszMtlFile, char **papszMetaInfo, int nSubdataset, LandsatDataset **ppoDS );
}; /************************************************************************/
/* ==================================================================== */
/* LandSatRasterBand */
/* ==================================================================== */
/************************************************************************/ class LandSatRasterBand : public GDALPamRasterBand
{
friend class LandsatDataset; GDALRasterBand *poVRTBand; public:
LandSatRasterBand( LandsatDataset *, int, GDALRasterBand * );
virtual ~LandSatRasterBand() {}; virtual CPLErr IReadBlock( int, int, void * );
virtual CPLErr IRasterIO( GDALRWFlag, int, int, int, int,
void *, int, int, GDALDataType,
int, int );
}; /************************************************************************/
/* LandSatRasterBand() */
/************************************************************************/ LandSatRasterBand::LandSatRasterBand( LandsatDataset *poTILDS, int nBand,
GDALRasterBand *poVRTBand ) {
this->poDS = poTILDS;
this->poVRTBand = poVRTBand;
this->nBand = nBand;
this->eDataType = poVRTBand->GetRasterDataType(); poVRTBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
} /************************************************************************/
/* IReadBlock() */
/************************************************************************/ CPLErr LandSatRasterBand::IReadBlock( int iBlockX, int iBlockY, void *pBuffer ) {
return poVRTBand->ReadBlock( iBlockX, iBlockY, pBuffer );
} /************************************************************************/
/* IRasterIO() */
/************************************************************************/ CPLErr LandSatRasterBand::IRasterIO( GDALRWFlag eRWFlag,
int nXOff, int nYOff, int nXSize, int nYSize,
void * pData, int nBufXSize, int nBufYSize,
GDALDataType eBufType,
int nPixelSpace, int nLineSpace ) {
if(GetOverviewCount() > 0)
{
return GDALPamRasterBand::IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
pData, nBufXSize, nBufYSize, eBufType,
nPixelSpace, nLineSpace );
}
else //if not exist TIL overviews, try to use band source overviews
{
return poVRTBand->RasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
pData, nBufXSize, nBufYSize, eBufType,
nPixelSpace, nLineSpace );
}
} /************************************************************************/
/* LandsatDataset() */
/************************************************************************/ LandsatDataset::LandsatDataset() {
poVRTDS = NULL;
} /************************************************************************/
/* ~LandsatDataset() */
/************************************************************************/ LandsatDataset::~LandsatDataset() {
CloseDependentDatasets();
} /************************************************************************/
/* CloseDependentDatasets() */
/************************************************************************/ int LandsatDataset::CloseDependentDatasets()
{
int bHasDroppedRef = GDALPamDataset::CloseDependentDatasets(); if( poVRTDS )
{
bHasDroppedRef = TRUE;
delete poVRTDS;
poVRTDS = NULL;
} while( !apoTifDS.empty() )
{
GDALClose( (GDALDatasetH) apoTifDS.back() );
apoTifDS.pop_back();
} return bHasDroppedRef;
} /************************************************************************/
/* Identify() */
/************************************************************************/ int LandsatDataset::Identify( GDALOpenInfo *poOpenInfo ) {
if( EQUALN(poOpenInfo->pszFilename,"LANDSAT:",8) ) //subdataset
return TRUE; const char* pszExt = CPLGetExtension(poOpenInfo->pszFilename);
if( !EQUAL(pszExt,"TXT") && !EQUAL(pszExt,"MET"))
return FALSE; if( strstr((const char *) poOpenInfo->pabyHeader,"GROUP = L1_METADATA_FILE") == NULL )
return FALSE;
else
return TRUE;
} int LandsatDataset::ParserLandsat7( const char* pszMtlFile, char **papszMetaInfo, int nSubdataset, LandsatDataset **ppoDS )
{
LandsatDataset *poDS = (LandsatDataset*)(*ppoDS); double dfCellSize = 0.0;
char **papszRasterName = NULL;
if(nSubdataset == 0)
{
dfCellSize = CPLAtof(CSLFetchNameValueDef(papszMetaInfo, "PROJECTION_PARAMETERS.GRID_CELL_SIZE_PAN", "0"));
poDS->nRasterXSize = atoi(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_SAMPLES_PAN","0"));
poDS->nRasterYSize = atoi(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_LINES_PAN","0"));
papszRasterName = CSLAddString(papszRasterName, "BAND8");
}
else if(nSubdataset ==1)
{
dfCellSize = CPLAtof(CSLFetchNameValueDef(papszMetaInfo, "PROJECTION_PARAMETERS.GRID_CELL_SIZE_REF", "0"));
poDS->nRasterXSize = atoi(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_SAMPLES_REF","0"));
poDS->nRasterYSize = atoi(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_LINES_REF","0"));
papszRasterName = CSLAddString(papszRasterName, "BAND1");
papszRasterName = CSLAddString(papszRasterName, "BAND2");
papszRasterName = CSLAddString(papszRasterName, "BAND3");
papszRasterName = CSLAddString(papszRasterName, "BAND4");
papszRasterName = CSLAddString(papszRasterName, "BAND5");
papszRasterName = CSLAddString(papszRasterName, "BAND7");
}
else
{
dfCellSize = CPLAtof(CSLFetchNameValueDef(papszMetaInfo, "PROJECTION_PARAMETERS.GRID_CELL_SIZE_THM", "0"));
poDS->nRasterXSize = atoi(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_SAMPLES_THM","0"));
poDS->nRasterYSize = atoi(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_LINES_THM","0"));
papszRasterName = CSLAddString(papszRasterName, "BAND61");
papszRasterName = CSLAddString(papszRasterName, "BAND62");
} if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize))
{
CSLDestroy(papszRasterName);
return FALSE;
} OGRSpatialReference oSRS;
const char* pszMapProjection = CSLFetchNameValue(papszMetaInfo, "PROJECTION_PARAMETERS.MAP_PROJECTION");
const char* pszDatum = NULL;
const char* pszEllipsoid = NULL;
const char* pszZone = NULL; if(strstr(pszMapProjection, "UTM") != NULL)
{
pszDatum = CSLFetchNameValue(papszMetaInfo, "PROJECTION_PARAMETERS.REFERENCE_DATUM");
pszEllipsoid = CSLFetchNameValue(papszMetaInfo, "PROJECTION_PARAMETERS.REFERENCE_ELLIPSOID");
pszZone = CSLFetchNameValue(papszMetaInfo, "UTM_PARAMETERS.ZONE_NUMBER"); // trim double quotes.
if( pszDatum[0] == '"' )
pszDatum++;
if( pszDatum[strlen(pszDatum)-1] == '"' )
((char *) pszDatum)[strlen(pszDatum)-1] = '\0'; oSRS.SetWellKnownGeogCS(pszDatum);
oSRS.SetUTM(atoi(pszZone));
} char *pszWkt = NULL;
if(oSRS.exportToWkt(&pszWkt) == OGRERR_NONE)
poDS->SetProjection(pszWkt); double dfUL_X = CPLAtof(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_UL_CORNER_MAPX","0"));
double dfUL_Y = CPLAtof(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_UL_CORNER_MAPY","0"));
double dfUR_X = CPLAtof(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_UR_CORNER_MAPX","0"));
double dfUR_Y = CPLAtof(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_UR_CORNER_MAPY","0"));
double dfLL_X = CPLAtof(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_LL_CORNER_MAPX","0"));
double dfLL_Y = CPLAtof(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_LL_CORNER_MAPY","0"));
double dfLR_X = CPLAtof(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_LR_CORNER_MAPX","0"));
double dfLR_Y = CPLAtof(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_LR_CORNER_MAPY","0")); double adfGeoTransform[6] = {dfUL_X, dfCellSize, 0, dfUL_Y, 0, -1*dfCellSize};
poDS->SetGeoTransform(adfGeoTransform); /* -------------------------------------------------------------------- */
/* We need to open one of the images in order to establish */
/* details like the band count and types. */
/* -------------------------------------------------------------------- */
GDALDataset *poTemplateDS = NULL; CPLString ostrFileName;
ostrFileName.Printf( "L1_METADATA_FILE.%s_FILE_NAME", papszRasterName[0] );
const char *pszFilename = CSLFetchNameValue( papszMetaInfo, ostrFileName.c_str() );
if( pszFilename == NULL )
{
CPLError( CE_Failure, CPLE_AppDefined, "Missing %s in .TXT file.", ostrFileName.c_str() );
CSLDestroy(papszRasterName);
return FALSE;
} CPLString osDirname = CPLGetDirname(pszMtlFile); // trim double quotes.
if( pszFilename[0] == '"' )
pszFilename++;
if( pszFilename[strlen(pszFilename)-1] == '"' )
((char *) pszFilename)[strlen(pszFilename)-1] = '\0'; const char* pszSubFile = CPLFormFilename(osDirname, pszFilename, NULL);
poTemplateDS = (GDALDataset *) GDALOpen( pszSubFile, GA_ReadOnly );
if( poTemplateDS == NULL || poTemplateDS->GetRasterCount() == 0)
{
if (poTemplateDS != NULL)
GDALClose( poTemplateDS ); CSLDestroy(papszRasterName);
return FALSE;
} poDS->SetProjection(poTemplateDS->GetProjectionRef());
poTemplateDS->GetGeoTransform(adfGeoTransform);
poDS->SetGeoTransform(adfGeoTransform); GDALRasterBand *poTemplateBand = poTemplateDS->GetRasterBand(1);
GDALDataType eDT = poTemplateBand->GetRasterDataType();
int nBandCount = CSLCount(papszRasterName); poTemplateBand = NULL;
GDALClose( poTemplateDS ); /* -------------------------------------------------------------------- */
/* Create and initialize the corresponding VRT dataset used to */
/* manage the tiled data access. */
/* -------------------------------------------------------------------- */
poDS->poVRTDS = new VRTDataset(poDS->nRasterXSize, poDS->nRasterYSize);
int iBand = 0;
for( iBand = 0; iBand < nBandCount; iBand++ )
poDS->poVRTDS->AddBand( eDT, NULL ); /* Don't try to write a VRT file */
poDS->poVRTDS->SetWritable(FALSE); /* -------------------------------------------------------------------- */
/* Create band information objects. */
/* -------------------------------------------------------------------- */
for( iBand = 0; iBand < nBandCount; iBand++ )
{
ostrFileName.Printf( "L1_METADATA_FILE.%s_FILE_NAME", papszRasterName[iBand] );
pszFilename = CSLFetchNameValue( papszMetaInfo, ostrFileName.c_str() );
if( pszFilename == NULL )
{
CPLError( CE_Failure, CPLE_AppDefined, "Missing %s in .TXT file.", ostrFileName.c_str() );
CSLDestroy(papszRasterName);
return FALSE;
} // trim double quotes.
if( pszFilename[0] == '"' )
pszFilename++;
if( pszFilename[strlen(pszFilename)-1] == '"' )
((char *) pszFilename)[strlen(pszFilename)-1] = '\0'; pszSubFile = CPLFormFilename(osDirname, pszFilename, NULL);
GDALDataset *poBandDS = (GDALDataset *) GDALOpen( pszSubFile, GA_ReadOnly );
if( poBandDS == NULL || poBandDS->GetRasterCount() == 0)
{
if (poBandDS != NULL)
GDALClose( poBandDS ); CSLDestroy(papszRasterName);
return FALSE;
} poDS->apoTifDS.push_back( poBandDS ); GDALRasterBand *pBand = poBandDS->GetRasterBand(1);
LandSatRasterBand *pLandsatBand = new LandSatRasterBand( poDS, iBand+1, pBand);
char** papszBandMeta = NULL;
papszBandMeta = CSLAddString(papszBandMeta, pszFilename);
pLandsatBand->SetMetadata(papszBandMeta);
poDS->SetBand( iBand+1, pLandsatBand);
} CSLDestroy(papszRasterName);
return TRUE;
} int LandsatDataset::ParserLandsat8( const char* pszMtlFile, char **papszMetaInfo, int nSubdataset, LandsatDataset **ppoDS )
{
LandsatDataset *poDS = (LandsatDataset*)(*ppoDS); double dfCellSize = 0.0;
char **papszRasterName = NULL;
if(nSubdataset == 0)
{
dfCellSize = CPLAtof(CSLFetchNameValueDef(papszMetaInfo, "L1_METADATA_FILE.PROJECTION_PARAMETERS.GRID_CELL_SIZE_PANCHROMATIC", "0"));
poDS->nRasterXSize = atoi(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_METADATA.PANCHROMATIC_SAMPLES","0"));
poDS->nRasterYSize = atoi(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_METADATA.PANCHROMATIC_LINES","0"));
papszRasterName = CSLAddString(papszRasterName, "BAND_8");
}
else if(nSubdataset ==1)
{
dfCellSize = CPLAtof(CSLFetchNameValueDef(papszMetaInfo, "L1_METADATA_FILE.PROJECTION_PARAMETERS.GRID_CELL_SIZE_REFLECTIVE", "0"));
poDS->nRasterXSize = atoi(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_METADATA.REFLECTIVE_SAMPLES","0"));
poDS->nRasterYSize = atoi(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_METADATA.REFLECTIVE_LINES","0"));
papszRasterName = CSLAddString(papszRasterName, "BAND_1");
papszRasterName = CSLAddString(papszRasterName, "BAND_2");
papszRasterName = CSLAddString(papszRasterName, "BAND_3");
papszRasterName = CSLAddString(papszRasterName, "BAND_4");
papszRasterName = CSLAddString(papszRasterName, "BAND_5");
papszRasterName = CSLAddString(papszRasterName, "BAND_6");
papszRasterName = CSLAddString(papszRasterName, "BAND_7");
papszRasterName = CSLAddString(papszRasterName, "BAND_9");
}
else if(nSubdataset ==2)
{
dfCellSize = CPLAtof(CSLFetchNameValueDef(papszMetaInfo, "L1_METADATA_FILE.PROJECTION_PARAMETERS.GRID_CELL_SIZE_THERMAL", "0"));
poDS->nRasterXSize = atoi(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_METADATA.THERMAL_SAMPLES","0"));
poDS->nRasterYSize = atoi(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_METADATA.THERMAL_LINES","0"));
papszRasterName = CSLAddString(papszRasterName, "BAND_10");
papszRasterName = CSLAddString(papszRasterName, "BAND_11");
}
else
{
dfCellSize = CPLAtof(CSLFetchNameValueDef(papszMetaInfo, "L1_METADATA_FILE.PROJECTION_PARAMETERS.GRID_CELL_SIZE_THERMAL", "0"));
poDS->nRasterXSize = atoi(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_METADATA.THERMAL_SAMPLES","0"));
poDS->nRasterYSize = atoi(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_METADATA.THERMAL_LINES","0"));
papszRasterName = CSLAddString(papszRasterName, "BAND_QUALITY");
} if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize))
{
CSLDestroy(papszRasterName);
return FALSE;
} OGRSpatialReference oSRS;
const char* pszMapProjection = CSLFetchNameValue(papszMetaInfo, "L1_METADATA_FILE.PROJECTION_PARAMETERS.MAP_PROJECTION");
const char* pszDatum = NULL;
const char* pszEllipsoid = NULL;
const char* pszZone = NULL; if(strstr(pszMapProjection, "UTM") != NULL)
{
pszDatum = CSLFetchNameValue(papszMetaInfo, "L1_METADATA_FILE.PROJECTION_PARAMETERS.DATUM");
pszEllipsoid = CSLFetchNameValue(papszMetaInfo, "L1_METADATA_FILE.PROJECTION_PARAMETERS.ELLIPSOID");
pszZone = CSLFetchNameValue(papszMetaInfo, "L1_METADATA_FILE.PROJECTION_PARAMETERS.UTM_ZONE"); // trim double quotes.
if( pszDatum[0] == '"' )
pszDatum++;
if( pszDatum[strlen(pszDatum)-1] == '"' )
((char *) pszDatum)[strlen(pszDatum)-1] = '\0'; oSRS.SetWellKnownGeogCS(pszDatum);
oSRS.SetUTM(atoi(pszZone));
} char *pszWkt = NULL;
if(oSRS.exportToWkt(&pszWkt) == OGRERR_NONE)
poDS->SetProjection(pszWkt); double dfUL_X = CPLAtof(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_METADATA.CORNER_UL_PROJECTION_X_PRODUCT","0"));
double dfUL_Y = CPLAtof(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_METADATA.CORNER_UL_PROJECTION_Y_PRODUCT","0"));
double dfUR_X = CPLAtof(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_METADATA.CORNER_UR_PROJECTION_X_PRODUCT","0"));
double dfUR_Y = CPLAtof(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_METADATA.CORNER_UR_PROJECTION_Y_PRODUCT","0"));
double dfLL_X = CPLAtof(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_METADATA.CORNER_LL_PROJECTION_X_PRODUCT","0"));
double dfLL_Y = CPLAtof(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_METADATA.CORNER_LL_PROJECTION_Y_PRODUCT","0"));
double dfLR_X = CPLAtof(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_METADATA.CORNER_LR_PROJECTION_X_PRODUCT","0"));
double dfLR_Y = CPLAtof(CSLFetchNameValueDef(papszMetaInfo,"L1_METADATA_FILE.PRODUCT_METADATA.CORNER_LR_PROJECTION_Y_PRODUCT","0")); double adfGeoTransform[6] = {dfUL_X, dfCellSize, 0, dfUL_Y, 0, -1*dfCellSize};
poDS->SetGeoTransform(adfGeoTransform); /* -------------------------------------------------------------------- */
/* We need to open one of the images in order to establish */
/* details like the band count and types. */
/* -------------------------------------------------------------------- */
GDALDataset *poTemplateDS = NULL; CPLString ostrFileName;
ostrFileName.Printf( "L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_%s", papszRasterName[0] );
const char *pszFilename = CSLFetchNameValue( papszMetaInfo, ostrFileName.c_str() );
if( pszFilename == NULL )
{
CPLError( CE_Failure, CPLE_AppDefined, "Missing %s in .TXT file.", ostrFileName.c_str() );
CSLDestroy(papszRasterName);
return FALSE;
} CPLString osDirname = CPLGetDirname(pszMtlFile); // trim double quotes.
if( pszFilename[0] == '"' )
pszFilename++;
if( pszFilename[strlen(pszFilename)-1] == '"' )
((char *) pszFilename)[strlen(pszFilename)-1] = '\0'; const char* pszSubFile = CPLFormFilename(osDirname, pszFilename, NULL);
poTemplateDS = (GDALDataset *) GDALOpen( pszSubFile, GA_ReadOnly );
if( poTemplateDS == NULL || poTemplateDS->GetRasterCount() == 0)
{
if (poTemplateDS != NULL)
GDALClose( poTemplateDS ); CSLDestroy(papszRasterName);
return FALSE;
} poDS->SetProjection(poTemplateDS->GetProjectionRef());
poTemplateDS->GetGeoTransform(adfGeoTransform);
poDS->SetGeoTransform(adfGeoTransform); GDALRasterBand *poTemplateBand = poTemplateDS->GetRasterBand(1);
GDALDataType eDT = poTemplateBand->GetRasterDataType();
int nBandCount = CSLCount(papszRasterName); poTemplateBand = NULL;
GDALClose( poTemplateDS ); /* -------------------------------------------------------------------- */
/* Create and initialize the corresponding VRT dataset used to */
/* manage the tiled data access. */
/* -------------------------------------------------------------------- */
poDS->poVRTDS = new VRTDataset(poDS->nRasterXSize, poDS->nRasterYSize);
int iBand = 0;
for( iBand = 0; iBand < nBandCount; iBand++ )
poDS->poVRTDS->AddBand( eDT, NULL ); /* Don't try to write a VRT file */
poDS->poVRTDS->SetWritable(FALSE); /* -------------------------------------------------------------------- */
/* Create band information objects. */
/* -------------------------------------------------------------------- */
for( iBand = 0; iBand < nBandCount; iBand++ )
{
ostrFileName.Printf( "L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_%s", papszRasterName[iBand] );
pszFilename = CSLFetchNameValue( papszMetaInfo, ostrFileName.c_str() );
if( pszFilename == NULL )
{
CPLError( CE_Failure, CPLE_AppDefined, "Missing %s in .TXT file.", ostrFileName.c_str() );
CSLDestroy(papszRasterName);
return FALSE;
} // trim double quotes.
if( pszFilename[0] == '"' )
pszFilename++;
if( pszFilename[strlen(pszFilename)-1] == '"' )
((char *) pszFilename)[strlen(pszFilename)-1] = '\0'; pszSubFile = CPLFormFilename(osDirname, pszFilename, NULL);
GDALDataset *poBandDS = (GDALDataset *) GDALOpen( pszSubFile, GA_ReadOnly );
if( poBandDS == NULL || poBandDS->GetRasterCount() == 0)
{
if (poBandDS != NULL)
GDALClose( poBandDS ); CSLDestroy(papszRasterName);
return FALSE;
} poDS->apoTifDS.push_back( poBandDS ); GDALRasterBand *pBand = poBandDS->GetRasterBand(1);
LandSatRasterBand *pLandsatBand = new LandSatRasterBand( poDS, iBand+1, pBand);
char** papszBandMeta = NULL;
papszBandMeta = CSLAddString(papszBandMeta, pszFilename);
pLandsatBand->SetMetadata(papszBandMeta);
poDS->SetBand( iBand+1, pLandsatBand);
} CSLDestroy(papszRasterName);
return TRUE;
} /************************************************************************/
/* Open() */
/************************************************************************/ GDALDataset *LandsatDataset::Open( GDALOpenInfo * poOpenInfo ) {
if( !Identify( poOpenInfo ) )
return NULL; /* -------------------------------------------------------------------- */
/* Confirm the requested access is supported. */
/* -------------------------------------------------------------------- */
if( poOpenInfo->eAccess == GA_Update )
{
CPLError( CE_Failure, CPLE_NotSupported,
"The LANDSAT driver does not support update access to existing"
" datasets.\n" );
return NULL;
} CPLString osFilename;
int iSubdatasetIndex = -1;//0:PAN 1:REF 2:THM if( EQUALN(poOpenInfo->pszFilename, "LANDSAT:",8) )
{
const char *pszRest = poOpenInfo->pszFilename+8; iSubdatasetIndex = atoi(pszRest);
while( *pszRest != '\0' && *pszRest != ':' )
pszRest++; if( *pszRest == ':' )
pszRest++; osFilename = pszRest;
}
else
osFilename = poOpenInfo->pszFilename; if(iSubdatasetIndex <-1 || iSubdatasetIndex > 3)
{
CPLError( CE_Failure, CPLE_IllegalArg, "The LANDSAT driver does not support %d subdatasets.\n", iSubdatasetIndex );
return NULL;
} /* -------------------------------------------------------------------- */
/* Try to load and parse the .MTL .TXT file. */
/* -------------------------------------------------------------------- */
VSILFILE *fp = VSIFOpenL( osFilename, "r" );
if( fp == NULL )
{
return NULL;
} CPLKeywordParser oParser;
if( !oParser.Ingest( fp ) )
{
VSIFCloseL( fp );
return NULL;
} VSIFCloseL( fp ); char **papszMTL = oParser.GetAllKeywords();
Satellite sat = LANDSAT7; const char* pszSatID = CSLFetchNameValue(papszMTL, "L1_METADATA_FILE.PRODUCT_METADATA.SPACECRAFT_ID");
if(pszSatID == NULL)
{
return NULL;
} if(strstr(pszSatID,"Landsat7") != NULL)
sat = LANDSAT7;
else if(strstr(pszSatID,"LANDSAT_8") != NULL)
sat = LANDSAT8;
else
{
return NULL;
} if(sat == LANDSAT7 && iSubdatasetIndex ==3) //landsat7 not quality
{
return NULL;
} /* -------------------------------------------------------------------- */
/* Create a corresponding GDALDataset. */
/* -------------------------------------------------------------------- */
LandsatDataset *poDS;
poDS = new LandsatDataset();
poDS->SetMetadata(papszMTL); char *papszName[4] = {"PAN", "REF", "THE", "QUA"};
char *papszDesc[4] = {"Panchromatic", "Reflective", "Thermal", "Quality"};
if( iSubdatasetIndex == -1 ) //not a subdataset
{
int nSubdataset = (sat==LANDSAT7) ? 3 : 4;
for (int i=0; i<nSubdataset; i++)
{
CPLString osKey, osValue;
osKey.Printf( "SUBDATASET_%d_NAME", i+1 );
osValue.Printf( "LANDSAT:%d:%s", i, osFilename.c_str() );
poDS->SetMetadataItem( osKey, osValue, "SUBDATASETS" ); osKey.Printf( "SUBDATASET_%d_DESC", i+1 );
osValue.Printf( "LANDSAT:%s", papszDesc[i] );
poDS->SetMetadataItem( osKey, osValue, "SUBDATASETS" );
} return( poDS );
} int nSuccess = FALSE;
if(sat == LANDSAT7)
nSuccess = ParserLandsat7(osFilename.c_str(), papszMTL, iSubdatasetIndex, &poDS);
else
nSuccess = ParserLandsat8(osFilename.c_str(), papszMTL, iSubdatasetIndex, &poDS); if(!nSuccess)
{
delete poDS;
return NULL;
} const char* pszDirname = CPLGetDirname(osFilename);
const char* pszBasename = CPLGetBasename(osFilename);
CPLString osTemp;
osTemp.Printf("%s_%s", pszBasename, papszName[iSubdatasetIndex]);
const char* pszSubFile = CPLFormFilename(pszDirname, osTemp, ""); /* -------------------------------------------------------------------- */
/* Initialize any PAM information. */
/* -------------------------------------------------------------------- */
poDS->SetDescription( pszSubFile );
poDS->TryLoadXML(); /* -------------------------------------------------------------------- */
/* Check for overviews. */
/* -------------------------------------------------------------------- */
poDS->oOvManager.Initialize( poDS, pszSubFile ); return( poDS );
} /************************************************************************/
/* GetFileList() */
/************************************************************************/ char **LandsatDataset::GetFileList() {
unsigned int i;
char **papszFileList = GDALPamDataset::GetFileList(); for( i = 0; i < apoTifDS.size(); i++ )
papszFileList = CSLAddString( papszFileList, apoTifDS[i]->GetDescription() ); return papszFileList;
} /************************************************************************/
/* GDALRegister_Landsat() */
/************************************************************************/ void GDALRegister_Landsat() {
GDALDriver *poDriver; if( GDALGetDriverByName( "LANDSAT" ) == NULL )
{
poDriver = new GDALDriver(); poDriver->SetDescription( "LANDSAT" );
poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, "LANDSAT 7/8 GeoTiff with Metadata" );
poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, "frmt_landsat.html" ); poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" ); poDriver->pfnOpen = LandsatDataset::Open;
poDriver->pfnIdentify = LandsatDataset::Identify; GetGDALDriverManager()->RegisterDriver( poDriver );
}
}

编译之后,使用gdalinfo命令查看是否编译成功,处理输出如下,可以看到最后一行就是新加的landsat的驱动。

F:\gdal\bin>gdalinfo.exe --formats
Supported Formats:
ECW (rov): ERDAS Compressed Wavelets (SDK 4.2)
JP2ECW (rov): ERDAS JPEG2000 (SDK 4.2)
FITS (rw+): Flexible Image Transport System
GeoRaster (rw+s): Oracle Spatial GeoRaster
HDF4 (ros): Hierarchical Data Format Release 4
HDF4Image (rw+): HDF4 Dataset
HDF5 (ros): Hierarchical Data Format Release 5
HDF5Image (ro): HDF5 Dataset
MG4Lidar (ro): MrSID Generation 4 / Lidar (.sid)
MrSID (rov): Multi-resolution Seamless Image Database (MrSID)
JP2MrSID (rov): MrSID JPEG2000
netCDF (rw+s): Network Common Data Format
GMT (rw): GMT NetCDF Grid Format
PostGISRaster (rws): PostGIS Raster driver
VRT (rw+v): Virtual Raster
GTiff (rw+vs): GeoTIFF
NITF (rw+vs): National Imagery Transmission Format
RPFTOC (rovs): Raster Product Format TOC format
ECRGTOC (rovs): ECRG TOC format
HFA (rw+v): Erdas Imagine Images (.img)
SAR_CEOS (rov): CEOS SAR Image
CEOS (rov): CEOS Image
。。。。太多了,删除了一些。。。
IRIS (rov): IRIS data (.PPI, .CAPPi etc)
WMTS (rwv): OGC Web Mab Tile Service
CNSDTF (rwv): China Geospatial Data Transfer Grid Format (.grd)
LANDSAT (rov): LANDSAT 7/8 GeoTiff with Metadata

再使用gdalinfo --format LANDSAT看看驱动详情

F:\gdal\bin>gdalinfo.exe --format LANDSAT
Format Details:
Short Name: LANDSAT
Long Name: LANDSAT 7/8 GeoTiff with Metadata
Help Topic: frmt_landsat.html
Supports: Virtual IO - eg. /vsimem/

如果输出上面的信息,说明gdal扩展成功,下面使用gdalinfo打开landsat8的数据试试,上面的驱动在实现的时候同时考虑了Landsat7的数据,所以这两个数据应该都可以支持。使用gdalinfo输出mtl.txt文件之后,输出内容如下:

F:\gdal\bin>gdalinfo.exe F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_MTL.txt
Driver: LANDSAT/LANDSAT 7/8 GeoTiff with Metadata
Files: F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_MTL.txt
Size is 512, 512
Coordinate System is `'
Metadata:
L1_METADATA_FILE.IMAGE_ATTRIBUTES.CLOUD_COVER=11.95
L1_METADATA_FILE.IMAGE_ATTRIBUTES.EARTH_SUN_DISTANCE=0.9925442
L1_METADATA_FILE.IMAGE_ATTRIBUTES.GEOMETRIC_RMSE_MODEL=8.958
L1_METADATA_FILE.IMAGE_ATTRIBUTES.GEOMETRIC_RMSE_MODEL_X=6.205
L1_METADATA_FILE.IMAGE_ATTRIBUTES.GEOMETRIC_RMSE_MODEL_Y=6.460
L1_METADATA_FILE.IMAGE_ATTRIBUTES.GEOMETRIC_RMSE_VERIFY=6.144
L1_METADATA_FILE.IMAGE_ATTRIBUTES.GROUND_CONTROL_POINTS_MODEL=141
L1_METADATA_FILE.IMAGE_ATTRIBUTES.GROUND_CONTROL_POINTS_VERIFY=36
L1_METADATA_FILE.IMAGE_ATTRIBUTES.IMAGE_QUALITY_OLI=9
L1_METADATA_FILE.IMAGE_ATTRIBUTES.IMAGE_QUALITY_TIRS=9
L1_METADATA_FILE.IMAGE_ATTRIBUTES.ROLL_ANGLE=-0.001
L1_METADATA_FILE.IMAGE_ATTRIBUTES.SUN_AZIMUTH=109.94537007
L1_METADATA_FILE.IMAGE_ATTRIBUTES.SUN_ELEVATION=59.45969108
L1_METADATA_FILE.METADATA_FILE_INFO.FILE_DATE=2014-03-08T06:54:18Z
L1_METADATA_FILE.METADATA_FILE_INFO.LANDSAT_SCENE_ID="LC81270562014067LGN00"
L1_METADATA_FILE.METADATA_FILE_INFO.ORIGIN="Image courtesy of the U.S. Geological Survey"
L1_METADATA_FILE.METADATA_FILE_INFO.PROCESSING_SOFTWARE_VERSION="LPGS_2.3.0"
L1_METADATA_FILE.METADATA_FILE_INFO.REQUEST_ID="0501403074153_00047"
L1_METADATA_FILE.METADATA_FILE_INFO.STATION_ID="LGN"
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_10=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_11=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_1=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_2=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_3=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_4=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_5=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_6=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_7=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_8=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_9=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_10=1
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_11=1
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_1=1
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_2=1
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_3=1
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_4=1
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_5=1
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_6=1
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_7=1
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_8=1
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_9=1
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_10=22.00180
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_11=22.00180
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_1=771.52448
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_2=790.05048
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_3=728.02478
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_4=613.91150
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_5=375.68323
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_6=93.42900
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_7=31.49057
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_8=694.77887
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_9=146.82552
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_10=0.10033
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_11=0.10033
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_1=-63.71274
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_2=-65.24262
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_3=-60.12052
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_4=-50.69701
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_5=-31.02404
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_6=-7.71540
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_7=-2.60050
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_8=-57.37506
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_9=-12.12490
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MAXIMUM_BAND_1=1.210700
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MAXIMUM_BAND_2=1.210700
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MAXIMUM_BAND_3=1.210700
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MAXIMUM_BAND_4=1.210700
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MAXIMUM_BAND_5=1.210700
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MAXIMUM_BAND_6=1.210700
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MAXIMUM_BAND_7=1.210700
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MAXIMUM_BAND_8=1.210700
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MAXIMUM_BAND_9=1.210700
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MINIMUM_BAND_1=-0.099980
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MINIMUM_BAND_2=-0.099980
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MINIMUM_BAND_3=-0.099980
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MINIMUM_BAND_4=-0.099980
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MINIMUM_BAND_5=-0.099980
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MINIMUM_BAND_6=-0.099980
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MINIMUM_BAND_7=-0.099980
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MINIMUM_BAND_8=-0.099980
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MINIMUM_BAND_9=-0.099980
L1_METADATA_FILE.PRODUCT_METADATA.BPF_NAME_OLI="LO8BPF20140308030904_20140308035315.01"
L1_METADATA_FILE.PRODUCT_METADATA.BPF_NAME_TIRS="LT8BPF20140308030510_20140308035408.01"
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_LL_LAT_PRODUCT=4.73612
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_LL_LON_PRODUCT=100.95098
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_LL_PROJECTION_X_PRODUCT=716400.000
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_LL_PROJECTION_Y_PRODUCT=523800.000
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_LR_LAT_PRODUCT=4.72733
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_LR_LON_PRODUCT=102.99592
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_LR_PROJECTION_X_PRODUCT=943500.000
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_LR_PROJECTION_Y_PRODUCT=523800.000
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_UL_LAT_PRODUCT=6.83546
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_UL_LON_PRODUCT=100.95819
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_UL_PROJECTION_X_PRODUCT=716400.000
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_UL_PROJECTION_Y_PRODUCT=756000.000
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_UR_LAT_PRODUCT=6.82274
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_UR_LON_PRODUCT=103.01065
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_UR_PROJECTION_X_PRODUCT=943500.000
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_UR_PROJECTION_Y_PRODUCT=756000.000
L1_METADATA_FILE.PRODUCT_METADATA.CPF_NAME="L8CPF20140101_20140331.03"
L1_METADATA_FILE.PRODUCT_METADATA.DATA_TYPE="L1T"
L1_METADATA_FILE.PRODUCT_METADATA.DATE_ACQUIRED=2014-03-08
L1_METADATA_FILE.PRODUCT_METADATA.ELEVATION_SOURCE="GLS2000"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_10="LC81270562014067LGN00_B10.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_11="LC81270562014067LGN00_B11.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_1="LC81270562014067LGN00_B1.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_2="LC81270562014067LGN00_B2.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_3="LC81270562014067LGN00_B3.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_4="LC81270562014067LGN00_B4.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_5="LC81270562014067LGN00_B5.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_6="LC81270562014067LGN00_B6.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_7="LC81270562014067LGN00_B7.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_8="LC81270562014067LGN00_B8.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_9="LC81270562014067LGN00_B9.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_QUALITY="LC81270562014067LGN00_BQA.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.METADATA_FILE_NAME="LC81270562014067LGN00_MTL.txt"
L1_METADATA_FILE.PRODUCT_METADATA.NADIR_OFFNADIR="NADIR"
L1_METADATA_FILE.PRODUCT_METADATA.OUTPUT_FORMAT="GEOTIFF"
L1_METADATA_FILE.PRODUCT_METADATA.PANCHROMATIC_LINES=15481
L1_METADATA_FILE.PRODUCT_METADATA.PANCHROMATIC_SAMPLES=15141
L1_METADATA_FILE.PRODUCT_METADATA.REFLECTIVE_LINES=7741
L1_METADATA_FILE.PRODUCT_METADATA.REFLECTIVE_SAMPLES=7571
L1_METADATA_FILE.PRODUCT_METADATA.RLUT_FILE_NAME="L8RLUT20130211_20431231v09.h5"
L1_METADATA_FILE.PRODUCT_METADATA.SCENE_CENTER_TIME=03:28:21.9117383Z
L1_METADATA_FILE.PRODUCT_METADATA.SENSOR_ID="OLI_TIRS"
L1_METADATA_FILE.PRODUCT_METADATA.SPACECRAFT_ID="LANDSAT_8"
L1_METADATA_FILE.PRODUCT_METADATA.TARGET_WRS_PATH=127
L1_METADATA_FILE.PRODUCT_METADATA.TARGET_WRS_ROW=56
L1_METADATA_FILE.PRODUCT_METADATA.THERMAL_LINES=7741
L1_METADATA_FILE.PRODUCT_METADATA.THERMAL_SAMPLES=7571
L1_METADATA_FILE.PRODUCT_METADATA.WRS_PATH=127
L1_METADATA_FILE.PRODUCT_METADATA.WRS_ROW=56
L1_METADATA_FILE.PROJECTION_PARAMETERS.DATUM="WGS84"
L1_METADATA_FILE.PROJECTION_PARAMETERS.ELLIPSOID="WGS84"
L1_METADATA_FILE.PROJECTION_PARAMETERS.GRID_CELL_SIZE_PANCHROMATIC=15.00
L1_METADATA_FILE.PROJECTION_PARAMETERS.GRID_CELL_SIZE_REFLECTIVE=30.00
L1_METADATA_FILE.PROJECTION_PARAMETERS.GRID_CELL_SIZE_THERMAL=30.00
L1_METADATA_FILE.PROJECTION_PARAMETERS.MAP_PROJECTION="UTM"
L1_METADATA_FILE.PROJECTION_PARAMETERS.ORIENTATION="NORTH_UP"
L1_METADATA_FILE.PROJECTION_PARAMETERS.RESAMPLING_OPTION="CUBIC_CONVOLUTION"
L1_METADATA_FILE.PROJECTION_PARAMETERS.UTM_ZONE=47
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_10=0.10000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_11=0.10000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_1=-63.72549
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_2=-65.25568
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_3=-60.13255
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_4=-50.70715
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_5=-31.03025
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_6=-7.71694
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_7=-2.60102
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_8=-57.38654
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_9=-12.12732
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_10=3.3420E-04
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_11=3.3420E-04
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_1=1.2745E-02
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_2=1.3051E-02
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_3=1.2027E-02
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_4=1.0141E-02
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_5=6.2060E-03
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_6=1.5434E-03
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_7=5.2020E-04
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_8=1.1477E-02
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_9=2.4255E-03
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_ADD_BAND_1=-0.100000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_ADD_BAND_2=-0.100000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_ADD_BAND_3=-0.100000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_ADD_BAND_4=-0.100000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_ADD_BAND_5=-0.100000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_ADD_BAND_6=-0.100000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_ADD_BAND_7=-0.100000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_ADD_BAND_8=-0.100000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_ADD_BAND_9=-0.100000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_MULT_BAND_1=2.0000E-05
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_MULT_BAND_2=2.0000E-05
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_MULT_BAND_3=2.0000E-05
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_MULT_BAND_4=2.0000E-05
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_MULT_BAND_5=2.0000E-05
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_MULT_BAND_6=2.0000E-05
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_MULT_BAND_7=2.0000E-05
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_MULT_BAND_8=2.0000E-05
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_MULT_BAND_9=2.0000E-05
L1_METADATA_FILE.TIRS_THERMAL_CONSTANTS.K1_CONSTANT_BAND_10=774.89
L1_METADATA_FILE.TIRS_THERMAL_CONSTANTS.K1_CONSTANT_BAND_11=480.89
L1_METADATA_FILE.TIRS_THERMAL_CONSTANTS.K2_CONSTANT_BAND_10=1321.08
L1_METADATA_FILE.TIRS_THERMAL_CONSTANTS.K2_CONSTANT_BAND_11=1201.14
Subdatasets:
SUBDATASET_1_NAME=LANDSAT:0:F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_MTL.txt
SUBDATASET_1_DESC=LANDSAT:Panchromatic
SUBDATASET_2_NAME=LANDSAT:1:F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_MTL.txt
SUBDATASET_2_DESC=LANDSAT:Reflective
SUBDATASET_3_NAME=LANDSAT:2:F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_MTL.txt
SUBDATASET_3_DESC=LANDSAT:Thermal
SUBDATASET_4_NAME=LANDSAT:3:F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_MTL.txt
SUBDATASET_4_DESC=LANDSAT:Quality
Corner Coordinates:
Upper Left ( 0.0, 0.0)
Lower Left ( 0.0, 512.0)
Upper Right ( 512.0, 0.0)
Lower Right ( 512.0, 512.0)
Center ( 256.0, 256.0)

从上面的输出内容可以看出,扩展的驱动可以将MTL中的所有的信息作为元数据进行输出,同时构造了四个subdataset。下面分别输出四个subdataset的信息。首先是subdataset1,也就是全色数据,子数据集的名称为LANDSAT:0:F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_MTL.txt,下面以这个作为gdalinfo的参数,输出内容如下:

F:\gdal\bin>gdalinfo.exe LANDSAT:0:F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_MTL.txt
Driver: LANDSAT/LANDSAT 7/8 GeoTiff with Metadata
Files: F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_B8.TIF
Size is 15141, 15481
Coordinate System is:
PROJCS["WGS 84 / UTM zone 47N",
GEOGCS["WGS 84",
DATUM["WGS_1984",
SPHEROID["WGS 84",6378137,298.257223563,
AUTHORITY["EPSG","7030"]],
AUTHORITY["EPSG","6326"]],
PRIMEM["Greenwich",0],
UNIT["degree",0.0174532925199433],
AUTHORITY["EPSG","4326"]],
PROJECTION["Transverse_Mercator"],
PARAMETER["latitude_of_origin",0],
PARAMETER["central_meridian",99],
PARAMETER["scale_factor",0.9996],
PARAMETER["false_easting",500000],
PARAMETER["false_northing",0],
UNIT["metre",1,
AUTHORITY["EPSG","9001"]],
AUTHORITY["EPSG","32647"]]
Origin = (716392.500000000000000,756007.500000000000000)
Pixel Size = (15.000000000000000,-15.000000000000000)
Metadata:
L1_METADATA_FILE.IMAGE_ATTRIBUTES.CLOUD_COVER=11.95
L1_METADATA_FILE.IMAGE_ATTRIBUTES.EARTH_SUN_DISTANCE=0.9925442
L1_METADATA_FILE.IMAGE_ATTRIBUTES.GEOMETRIC_RMSE_MODEL=8.958
L1_METADATA_FILE.IMAGE_ATTRIBUTES.GEOMETRIC_RMSE_MODEL_X=6.205
L1_METADATA_FILE.IMAGE_ATTRIBUTES.GEOMETRIC_RMSE_MODEL_Y=6.460
L1_METADATA_FILE.IMAGE_ATTRIBUTES.GEOMETRIC_RMSE_VERIFY=6.144
L1_METADATA_FILE.IMAGE_ATTRIBUTES.GROUND_CONTROL_POINTS_MODEL=141
L1_METADATA_FILE.IMAGE_ATTRIBUTES.GROUND_CONTROL_POINTS_VERIFY=36
L1_METADATA_FILE.IMAGE_ATTRIBUTES.IMAGE_QUALITY_OLI=9
L1_METADATA_FILE.IMAGE_ATTRIBUTES.IMAGE_QUALITY_TIRS=9
L1_METADATA_FILE.IMAGE_ATTRIBUTES.ROLL_ANGLE=-0.001
L1_METADATA_FILE.IMAGE_ATTRIBUTES.SUN_AZIMUTH=109.94537007
L1_METADATA_FILE.IMAGE_ATTRIBUTES.SUN_ELEVATION=59.45969108
L1_METADATA_FILE.METADATA_FILE_INFO.FILE_DATE=2014-03-08T06:54:18Z
L1_METADATA_FILE.METADATA_FILE_INFO.LANDSAT_SCENE_ID="LC81270562014067LGN00"
L1_METADATA_FILE.METADATA_FILE_INFO.ORIGIN="Image courtesy of the U.S. Geological Survey"
L1_METADATA_FILE.METADATA_FILE_INFO.PROCESSING_SOFTWARE_VERSION="LPGS_2.3.0"
L1_METADATA_FILE.METADATA_FILE_INFO.REQUEST_ID="0501403074153_00047"
L1_METADATA_FILE.METADATA_FILE_INFO.STATION_ID="LGN"
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_10=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_11=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_1=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_2=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_3=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_4=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_5=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_6=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_7=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_8=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MAX_BAND_9=65535
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_10=1
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_11=1
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_1=1
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_2=1
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_3=1
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_4=1
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_5=1
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_6=1
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_7=1
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_8=1
L1_METADATA_FILE.MIN_MAX_PIXEL_VALUE.QUANTIZE_CAL_MIN_BAND_9=1
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_10=22.00180
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_11=22.00180
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_1=771.52448
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_2=790.05048
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_3=728.02478
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_4=613.91150
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_5=375.68323
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_6=93.42900
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_7=31.49057
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_8=694.77887
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MAXIMUM_BAND_9=146.82552
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_10=0.10033
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_11=0.10033
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_1=-63.71274
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_2=-65.24262
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_3=-60.12052
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_4=-50.69701
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_5=-31.02404
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_6=-7.71540
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_7=-2.60050
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_8=-57.37506
L1_METADATA_FILE.MIN_MAX_RADIANCE.RADIANCE_MINIMUM_BAND_9=-12.12490
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MAXIMUM_BAND_1=1.210700
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MAXIMUM_BAND_2=1.210700
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MAXIMUM_BAND_3=1.210700
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MAXIMUM_BAND_4=1.210700
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MAXIMUM_BAND_5=1.210700
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MAXIMUM_BAND_6=1.210700
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MAXIMUM_BAND_7=1.210700
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MAXIMUM_BAND_8=1.210700
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MAXIMUM_BAND_9=1.210700
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MINIMUM_BAND_1=-0.099980
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MINIMUM_BAND_2=-0.099980
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MINIMUM_BAND_3=-0.099980
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MINIMUM_BAND_4=-0.099980
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MINIMUM_BAND_5=-0.099980
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MINIMUM_BAND_6=-0.099980
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MINIMUM_BAND_7=-0.099980
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MINIMUM_BAND_8=-0.099980
L1_METADATA_FILE.MIN_MAX_REFLECTANCE.REFLECTANCE_MINIMUM_BAND_9=-0.099980
L1_METADATA_FILE.PRODUCT_METADATA.BPF_NAME_OLI="LO8BPF20140308030904_20140308035315.01"
L1_METADATA_FILE.PRODUCT_METADATA.BPF_NAME_TIRS="LT8BPF20140308030510_20140308035408.01"
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_LL_LAT_PRODUCT=4.73612
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_LL_LON_PRODUCT=100.95098
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_LL_PROJECTION_X_PRODUCT=716400.000
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_LL_PROJECTION_Y_PRODUCT=523800.000
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_LR_LAT_PRODUCT=4.72733
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_LR_LON_PRODUCT=102.99592
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_LR_PROJECTION_X_PRODUCT=943500.000
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_LR_PROJECTION_Y_PRODUCT=523800.000
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_UL_LAT_PRODUCT=6.83546
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_UL_LON_PRODUCT=100.95819
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_UL_PROJECTION_X_PRODUCT=716400.000
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_UL_PROJECTION_Y_PRODUCT=756000.000
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_UR_LAT_PRODUCT=6.82274
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_UR_LON_PRODUCT=103.01065
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_UR_PROJECTION_X_PRODUCT=943500.000
L1_METADATA_FILE.PRODUCT_METADATA.CORNER_UR_PROJECTION_Y_PRODUCT=756000.000
L1_METADATA_FILE.PRODUCT_METADATA.CPF_NAME="L8CPF20140101_20140331.03"
L1_METADATA_FILE.PRODUCT_METADATA.DATA_TYPE="L1T"
L1_METADATA_FILE.PRODUCT_METADATA.DATE_ACQUIRED=2014-03-08
L1_METADATA_FILE.PRODUCT_METADATA.ELEVATION_SOURCE="GLS2000"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_10="LC81270562014067LGN00_B10.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_11="LC81270562014067LGN00_B11.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_1="LC81270562014067LGN00_B1.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_2="LC81270562014067LGN00_B2.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_3="LC81270562014067LGN00_B3.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_4="LC81270562014067LGN00_B4.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_5="LC81270562014067LGN00_B5.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_6="LC81270562014067LGN00_B6.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_7="LC81270562014067LGN00_B7.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_8="LC81270562014067LGN00_B8.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_9="LC81270562014067LGN00_B9.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.FILE_NAME_BAND_QUALITY="LC81270562014067LGN00_BQA.TIF"
L1_METADATA_FILE.PRODUCT_METADATA.METADATA_FILE_NAME="LC81270562014067LGN00_MTL.txt"
L1_METADATA_FILE.PRODUCT_METADATA.NADIR_OFFNADIR="NADIR"
L1_METADATA_FILE.PRODUCT_METADATA.OUTPUT_FORMAT="GEOTIFF"
L1_METADATA_FILE.PRODUCT_METADATA.PANCHROMATIC_LINES=15481
L1_METADATA_FILE.PRODUCT_METADATA.PANCHROMATIC_SAMPLES=15141
L1_METADATA_FILE.PRODUCT_METADATA.REFLECTIVE_LINES=7741
L1_METADATA_FILE.PRODUCT_METADATA.REFLECTIVE_SAMPLES=7571
L1_METADATA_FILE.PRODUCT_METADATA.RLUT_FILE_NAME="L8RLUT20130211_20431231v09.h5"
L1_METADATA_FILE.PRODUCT_METADATA.SCENE_CENTER_TIME=03:28:21.9117383Z
L1_METADATA_FILE.PRODUCT_METADATA.SENSOR_ID="OLI_TIRS"
L1_METADATA_FILE.PRODUCT_METADATA.SPACECRAFT_ID="LANDSAT_8"
L1_METADATA_FILE.PRODUCT_METADATA.TARGET_WRS_PATH=127
L1_METADATA_FILE.PRODUCT_METADATA.TARGET_WRS_ROW=56
L1_METADATA_FILE.PRODUCT_METADATA.THERMAL_LINES=7741
L1_METADATA_FILE.PRODUCT_METADATA.THERMAL_SAMPLES=7571
L1_METADATA_FILE.PRODUCT_METADATA.WRS_PATH=127
L1_METADATA_FILE.PRODUCT_METADATA.WRS_ROW=56
L1_METADATA_FILE.PROJECTION_PARAMETERS.DATUM="WGS84"
L1_METADATA_FILE.PROJECTION_PARAMETERS.ELLIPSOID="WGS84"
L1_METADATA_FILE.PROJECTION_PARAMETERS.GRID_CELL_SIZE_PANCHROMATIC=15.00
L1_METADATA_FILE.PROJECTION_PARAMETERS.GRID_CELL_SIZE_REFLECTIVE=30.00
L1_METADATA_FILE.PROJECTION_PARAMETERS.GRID_CELL_SIZE_THERMAL=30.00
L1_METADATA_FILE.PROJECTION_PARAMETERS.MAP_PROJECTION="UTM"
L1_METADATA_FILE.PROJECTION_PARAMETERS.ORIENTATION="NORTH_UP"
L1_METADATA_FILE.PROJECTION_PARAMETERS.RESAMPLING_OPTION="CUBIC_CONVOLUTION"
L1_METADATA_FILE.PROJECTION_PARAMETERS.UTM_ZONE=47
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_10=0.10000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_11=0.10000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_1=-63.72549
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_2=-65.25568
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_3=-60.13255
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_4=-50.70715
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_5=-31.03025
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_6=-7.71694
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_7=-2.60102
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_8=-57.38654
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_ADD_BAND_9=-12.12732
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_10=3.3420E-04
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_11=3.3420E-04
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_1=1.2745E-02
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_2=1.3051E-02
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_3=1.2027E-02
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_4=1.0141E-02
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_5=6.2060E-03
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_6=1.5434E-03
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_7=5.2020E-04
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_8=1.1477E-02
L1_METADATA_FILE.RADIOMETRIC_RESCALING.RADIANCE_MULT_BAND_9=2.4255E-03
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_ADD_BAND_1=-0.100000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_ADD_BAND_2=-0.100000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_ADD_BAND_3=-0.100000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_ADD_BAND_4=-0.100000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_ADD_BAND_5=-0.100000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_ADD_BAND_6=-0.100000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_ADD_BAND_7=-0.100000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_ADD_BAND_8=-0.100000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_ADD_BAND_9=-0.100000
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_MULT_BAND_1=2.0000E-05
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_MULT_BAND_2=2.0000E-05
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_MULT_BAND_3=2.0000E-05
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_MULT_BAND_4=2.0000E-05
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_MULT_BAND_5=2.0000E-05
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_MULT_BAND_6=2.0000E-05
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_MULT_BAND_7=2.0000E-05
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_MULT_BAND_8=2.0000E-05
L1_METADATA_FILE.RADIOMETRIC_RESCALING.REFLECTANCE_MULT_BAND_9=2.0000E-05
L1_METADATA_FILE.TIRS_THERMAL_CONSTANTS.K1_CONSTANT_BAND_10=774.89
L1_METADATA_FILE.TIRS_THERMAL_CONSTANTS.K1_CONSTANT_BAND_11=480.89
L1_METADATA_FILE.TIRS_THERMAL_CONSTANTS.K2_CONSTANT_BAND_10=1321.08
L1_METADATA_FILE.TIRS_THERMAL_CONSTANTS.K2_CONSTANT_BAND_11=1201.14
Corner Coordinates:
Upper Left ( 716392.500, 756007.500) (100d57'29.23"E, 6d50' 7.91"N)
Lower Left ( 716392.500, 523792.500) (100d57' 3.27"E, 4d44' 9.79"N)
Upper Right ( 943507.500, 756007.500) (103d 0'38.59"E, 6d49'22.11"N)
Lower Right ( 943507.500, 523792.500) (102d59'45.54"E, 4d43'38.14"N)
Center ( 829950.000, 639900.000) (101d58'44.08"E, 5d46'52.89"N)
Band 1 Block=15141x1 Type=UInt16, ColorInterp=Undefined
Metadata:
LC81270562014067LGN00_B8.TIF

从上面的输出可以看出,子数据集也将mtl中的元数据信息进行了输出,同时输出的全色数据的投影信息,四角坐标,分辨率等信息。

下面是多光谱数据,子数据集名称为LANDSAT:1:F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_MTL.txt,由于输出的元数据信息一样,所以使用参数-nomd禁止输出元数据。输出内容如下:

F:\gdal\bin>gdalinfo.exe -nomd LANDSAT:1:F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_MTL.txt
Driver: LANDSAT/LANDSAT 7/8 GeoTiff with Metadata
Files: F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_B1.TIF
F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_B2.TIF
F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_B3.TIF
F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_B4.TIF
F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_B5.TIF
F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_B6.TIF
F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_B7.TIF
F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_B9.TIF
Size is 7571, 7741
Coordinate System is:
PROJCS["WGS 84 / UTM zone 47N",
GEOGCS["WGS 84",
DATUM["WGS_1984",
SPHEROID["WGS 84",6378137,298.257223563,
AUTHORITY["EPSG","7030"]],
AUTHORITY["EPSG","6326"]],
PRIMEM["Greenwich",0],
UNIT["degree",0.0174532925199433],
AUTHORITY["EPSG","4326"]],
PROJECTION["Transverse_Mercator"],
PARAMETER["latitude_of_origin",0],
PARAMETER["central_meridian",99],
PARAMETER["scale_factor",0.9996],
PARAMETER["false_easting",500000],
PARAMETER["false_northing",0],
UNIT["metre",1,
AUTHORITY["EPSG","9001"]],
AUTHORITY["EPSG","32647"]]
Origin = (716385.000000000000000,756015.000000000000000)
Pixel Size = (30.000000000000000,-30.000000000000000)
Corner Coordinates:
Upper Left ( 716385.000, 756015.000) (100d57'28.99"E, 6d50' 8.15"N)
Lower Left ( 716385.000, 523785.000) (100d57' 3.03"E, 4d44' 9.55"N)
Upper Right ( 943515.000, 756015.000) (103d 0'38.83"E, 6d49'22.36"N)
Lower Right ( 943515.000, 523785.000) (102d59'45.78"E, 4d43'37.90"N)
Center ( 829950.000, 639900.000) (101d58'44.08"E, 5d46'52.89"N)
Band 1 Block=7571x1 Type=UInt16, ColorInterp=Undefined
Band 2 Block=7571x1 Type=UInt16, ColorInterp=Undefined
Band 3 Block=7571x1 Type=UInt16, ColorInterp=Undefined
Band 4 Block=7571x1 Type=UInt16, ColorInterp=Undefined
Band 5 Block=7571x1 Type=UInt16, ColorInterp=Undefined
Band 6 Block=7571x1 Type=UInt16, ColorInterp=Undefined
Band 7 Block=7571x1 Type=UInt16, ColorInterp=Undefined
Band 8 Block=7571x1 Type=UInt16, ColorInterp=Undefined

从上面的信息中可以看出,输出的多光谱一共有8个波段,以及空间参考信息,分辨率,四至范围等。

下面输出TIRS的数据,命令行如上,子数据集的名称为LANDSAT:2:F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_MTL.txt,输出的信息如下:

F:\gdal\bin>gdalinfo.exe -nomd LANDSAT:2:F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_MTL.txt
Driver: LANDSAT/LANDSAT 7/8 GeoTiff with Metadata
Files: F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_B10.TIF
F:\Data\LandSat\LC81270562014067LGN00\LC81270562014067LGN00_B11.TIF
Size is 7571, 7741
Coordinate System is:
PROJCS["WGS 84 / UTM zone 47N",
GEOGCS["WGS 84",
DATUM["WGS_1984",
SPHEROID["WGS 84",6378137,298.257223563,
AUTHORITY["EPSG","7030"]],
AUTHORITY["EPSG","6326"]],
PRIMEM["Greenwich",0],
UNIT["degree",0.0174532925199433],
AUTHORITY["EPSG","4326"]],
PROJECTION["Transverse_Mercator"],
PARAMETER["latitude_of_origin",0],
PARAMETER["central_meridian",99],
PARAMETER["scale_factor",0.9996],
PARAMETER["false_easting",500000],
PARAMETER["false_northing",0],
UNIT["metre",1,
AUTHORITY["EPSG","9001"]],
AUTHORITY["EPSG","32647"]]
Origin = (716385.000000000000000,756015.000000000000000)
Pixel Size = (30.000000000000000,-30.000000000000000)
Corner Coordinates:
Upper Left ( 716385.000, 756015.000) (100d57'28.99"E, 6d50' 8.15"N)
Lower Left ( 716385.000, 523785.000) (100d57' 3.03"E, 4d44' 9.55"N)
Upper Right ( 943515.000, 756015.000) (103d 0'38.83"E, 6d49'22.36"N)
Lower Right ( 943515.000, 523785.000) (102d59'45.78"E, 4d43'37.90"N)
Center ( 829950.000, 639900.000) (101d58'44.08"E, 5d46'52.89"N)
Band 1 Block=7571x1 Type=UInt16, ColorInterp=Undefined
Band 2 Block=7571x1 Type=UInt16, ColorInterp=Undefined

这里有个问题,可以看到输出的TIRS数据的分辨率为30m,但是网上的资料写的TIRS的分辨率都是100m,我直接使用gdalinfo输出了10.tif和11.tif的信息,发现里面的也是30m的分辨率,所以我觉得TIRS的分辨率应该也是30m才对。

有了上面的驱动,就可以直接使用gdal打开mtl文件从而自动将数据组合在一起了,在使用的时候也比较方便。希望对大家能有所帮助。