用代码说明一切!!!
static int CreateGCPsList( const char * pszGCPsFilename,
GDAL_GCP *pasGCPs );
static void DestoryGCPs( int nGCPCount, GDAL_GCP *pasGCPs );
static int GCPTransformToGeoTransform( int nGCPCount,
GDAL_GCP *pasGCPs,
double *padfGeoTransform );
static int ApplyGeoTransformOnOtherTransform(
double *padfSrcGeoTransform,
double *padfInputGeoTransform );
static GDALDataset *CreateOutputDataset( GDALDataset *pSrcDataset,
const char *pszDstFileFormat,
const char *pszDstFilename );
static int WarpImage( GDALDataset *pSrcDataset,
GDALDataset *pDstDataset );
int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;
static const int MAX_GCP = 6;
int bRet = EXIT_FAILURE;
const char *pszSrcFilename = "../data/in.tif";
const char *pszGCPsFilename = "../data/gcps.txt";
const char *pszDstFilename = "../data/out.tif";
/* ----------------------------------------------------------------- */
/* -----------------------从输入文件读取控制点---------------------- */
/* ----------------------------------------------------------------- */
GDAL_GCP aGCPsList[MAX_GCP];
int nGCPsCount = 0;
nGCPsCount = CreateGCPsList( pszGCPsFilename, aGCPsList );
if ( nGCPsCount < 3 )
{
std::cerr << "CreateGCPsList failed!"
<< std::endl;
goto Main_clean;
}
GDALAllRegister();
/* ----------------------------------------------------------------- */
/* -----------------------从输入数据文件创建数据集------------------ */
/* ----------------------------------------------------------------- */
GDALDataset *pSrcDataset = (GDALDataset *)GDALOpen(
pszSrcFilename,
GA_Update );
if ( pSrcDataset == NULL )
{
std::cerr << "GDALOpen Source file failed!"
<< std::endl;
goto Main_clean;
}
/* ----------------------------------------------------------------- */
/* -----------------------将控制点变换转化为地理仿射变换------------ */
/* ----------------------------------------------------------------- */
double adfSrcGeoTransform[6];
pSrcDataset->GetGeoTransform( adfSrcGeoTransform );
double adfGCPGeoTransform[6];
if ( !GCPTransformToGeoTransform( nGCPsCount, aGCPsList,
adfGCPGeoTransform) )
{
std::cerr << "GCPTransformToGeoTransform failed!"
<< std::endl;
goto Main_clean;
}
if ( !ApplyGeoTransformOnOtherTransform( adfSrcGeoTransform,
adfGCPGeoTransform ) )
{
std::cerr << "ApplyGeoTransformOnOtherTransform"
<< std::endl;
goto Main_clean;
}
pSrcDataset->SetGeoTransform( adfSrcGeoTransform );
/* ----------------------------------------------------------------- */
/* -----------------------创建输出数据集---------------------------- */
/* ----------------------------------------------------------------- */
GDALDataset *pDstDataset = CreateOutputDataset(pSrcDataset,
"GTiff",
pszDstFilename );
if ( pDstDataset == NULL )
{
std::cerr << "CreateOutputDataset failed!"
<< std::endl;
goto Main_clean;
}
/* ----------------------------------------------------------------- */
/* -----------------------进行变换操作------------------------------ */
/* ----------------------------------------------------------------- */
if ( !WarpImage( pSrcDataset, pDstDataset ) )
{
std::cerr
<< "Running the WarpImage failed!"
<< std::endl;
goto Main_clean;
}
/* ----------------------------------------------------------------- */
/* ---------------------退出的清理工作------------------------------ */
/* ----------------------------------------------------------------- */
Main_clean:
DestoryGCPs( nGCPsCount, aGCPsList );
GDALClose( pDstDataset );
GDALClose( pSrcDataset );
return bRet;
}
static int CreateGCPsList( const char * pszGCPsFilename,
GDAL_GCP *pasGCPs )
{
std::ifstream infile;
infile.open( pszGCPsFilename );
if ( !infile.is_open() )
{
return 0;
}
int nGCPCount = 0;
infile >> nGCPCount;
for ( int i = 0; i < nGCPCount; i++ )
{
/* ----------------------------------------------------------------- */
/* ---------------------读取控制点---------------------------------- */
/* ----------------------------------------------------------------- */
infile >> pasGCPs[i].dfGCPX
>> pasGCPs[i].dfGCPY;
infile >> pasGCPs[i].dfGCPPixel
>> pasGCPs[i].dfGCPLine;
pasGCPs[i].dfGCPZ = 0.0;
/* ----------------------------------------------------------------- */
/* ---------------------为控制点添加附加信息------------------------ */
/* ----------------------------------------------------------------- */
char *pszId = new char[32];
sprintf_s( pszId, 32, "Id - %d", i );
pasGCPs[i].pszId = pszId;
char *pszInfo = new char[32];
sprintf_s( pszInfo, 32, "Info - %d", i );
pasGCPs[i].pszInfo = pszInfo;
}
infile.close();
return nGCPCount;
}
static void DestoryGCPs( int nGCPCount, GDAL_GCP *pasGCPs )
{
/* ----------------------------------------------------------------- */
/* ---------------------删除在CreateGCPsList中分配的内存------------ */
/* ----------------------------------------------------------------- */
for ( int i = 0; i < nGCPCount; ++i )
{
delete []pasGCPs[i].pszId;
delete []pasGCPs[i].pszInfo;
pasGCPs[i].pszId = NULL;
pasGCPs[i].pszInfo = NULL;
}
}
static GDALDataset *CreateOutputDataset( GDALDataset *pSrcDataset,
const char *pszDstFileFormat,
const char *pszDstFilename )
{
/* ----------------------------------------------------------------- */
/* -----------------------查找对应格式的驱动------------------------ */
/* ----------------------------------------------------------------- */
GDALDriver *pDriver = NULL;
void *hTransformArg;
double adfDstGeoTransform[6];
int nPixels = 0;
int nLines = 0;
pDriver = (GDALDriver *)GDALGetDriverByName( pszDstFileFormat );
if ( pDriver == NULL )
{
return NULL;
}
/* ----------------------------------------------------------------- */
/* ------------------计算投影变换目标影像的大小--------------------- */
/* ----------------------------------------------------------------- */
hTransformArg =
GDALCreateGenImgProjTransformer( (GDALDatasetH)pSrcDataset,
NULL, NULL, NULL, FALSE, 0.0, 0 );
assert( hTransformArg != NULL );
if ( GDALSuggestedWarpOutput( (GDALDatasetH)pSrcDataset,
GDALGenImgProjTransform, hTransformArg, adfDstGeoTransform,
&nPixels, &nLines) != CE_None )
{
return NULL;
}
GDALDestroyGenImgProjTransformer( hTransformArg );
/* ----------------------------------------------------------------- */
/* -----------------------根据计算的尺寸创建输出影像---------------- */
/* ----------------------------------------------------------------- */
GDALDataset *pDstDataset = NULL;
pDstDataset = pDriver->Create( pszDstFilename,
nPixels, nLines,
pSrcDataset->GetRasterCount(),
pSrcDataset->GetRasterBand(1)->GetRasterDataType(),
NULL );
assert( pDstDataset != NULL );
pDstDataset->SetGeoTransform( adfDstGeoTransform );
pDstDataset->SetProjection( "" );
return pDstDataset;
}
static int GCPTransformToGeoTransform( int nGCPCount,
GDAL_GCP *pasGCPs,
double *padfGeoTransform )
{
void *hTransformArg;
hTransformArg = GDALCreateGCPTransformer( nGCPCount,
pasGCPs, 0, TRUE );
/* ---------------------------------------------------------------- */
/* -----------------选择计算的样本点------------------------------- */
/* ---------------------------------------------------------------- */
static const int SAMPLE_POITN_COUNT = 4;
double xGeo[SAMPLE_POITN_COUNT] = { 1, 2, 0, 0 };
double yGeo[SAMPLE_POITN_COUNT] = { 0, 0, 1, 2 };
double zGeo[SAMPLE_POITN_COUNT] = { 0, 0, 0, 0 };
int anSuccess[SAMPLE_POITN_COUNT];
if ( !GDALGCPTransform( hTransformArg, FALSE, 4,
xGeo, yGeo, zGeo, anSuccess ) )
{
return FALSE;
}
GDALDestroyGCPTransformer( hTransformArg );
/* ----------------------------------------------------------------- */
/* ----------------------计算放射变换系数--------------------------- */
/* ----------------------------------------------------------------- */
padfGeoTransform[1] = xGeo[1] - xGeo[0];
padfGeoTransform[2] = xGeo[3] - xGeo[2];
padfGeoTransform[4] = yGeo[1] - yGeo[0];
padfGeoTransform[5] = yGeo[3] - yGeo[2];
padfGeoTransform[0] = xGeo[0] - padfGeoTransform[1];
padfGeoTransform[3] = yGeo[0] - padfGeoTransform[4];
return TRUE;
}
int ApplyGeoTransformOnOtherTransform( double *padfSrcGeoTransform,
double *padfInputGeoTransform )
{
/* ----------------------------------------------------------------- */
/* --------------------------计算转换之后的仿射变换系数------------- */
/* ----------------------------------------------------------------- */
padfSrcGeoTransform[0] =
padfInputGeoTransform[1] * padfSrcGeoTransform[0] +
padfInputGeoTransform[2] * padfSrcGeoTransform[3] +
padfInputGeoTransform[0];
padfSrcGeoTransform[3] =
padfInputGeoTransform[4] * padfSrcGeoTransform[0] +
padfInputGeoTransform[5] * padfSrcGeoTransform[3] +
padfInputGeoTransform[3];
double dfXPixelSize, dfXRotate, dfYRotate, dfYPixelSize;
dfXPixelSize =
padfInputGeoTransform[1] * padfSrcGeoTransform[1] +
padfInputGeoTransform[2] * padfSrcGeoTransform[4];
dfXRotate =
padfInputGeoTransform[1] * padfSrcGeoTransform[2] +
padfInputGeoTransform[2] * padfSrcGeoTransform[5];
dfYRotate =
padfInputGeoTransform[4] * padfSrcGeoTransform[1] +
padfInputGeoTransform[5] * padfSrcGeoTransform[4];
dfYPixelSize =
padfInputGeoTransform[4] * padfSrcGeoTransform[2] +
padfInputGeoTransform[5] * padfSrcGeoTransform[5];
padfSrcGeoTransform[1] = dfXPixelSize;
padfSrcGeoTransform[2] = dfXRotate;
padfSrcGeoTransform[4] = dfYRotate;
padfSrcGeoTransform[5] = dfYPixelSize;
return TRUE;
}
static int WarpImage( GDALDataset *pSrcDataset, GDALDataset *pDstDataset )
{
int bRet = FALSE;
/* ----------------------------------------------------------------- */
/* -----------------创建变化影像纠正的的选项------------------------ */
/* ----------------------------------------------------------------- */
void *hTransformArg = NULL;
GDALTransformerFunc pfnTransformer = NULL;
hTransformArg =
GDALCreateGenImgProjTransformer( (GDALDatasetH)pSrcDataset,
NULL, (GDALDatasetH)pDstDataset, NULL, FALSE, 0.0, 0 );
if( hTransformArg == NULL )
return bRet;
pfnTransformer = GDALGenImgProjTransform;
GDALWarpOptions *psWO = GDALCreateWarpOptions();
psWO->papszWarpOptions = NULL;
psWO->eWorkingDataType = GDT_Byte;
psWO->eResampleAlg = GRA_NearestNeighbour;
psWO->hSrcDS = pSrcDataset;
psWO->hDstDS = pDstDataset;
psWO->pfnTransformer = pfnTransformer;
psWO->pTransformerArg = hTransformArg;
psWO->pfnProgress = GDALTermProgress;
psWO->nBandCount = pSrcDataset->GetRasterCount();
psWO->panSrcBands = (int *)
CPLMalloc(psWO->nBandCount*sizeof(int));
psWO->panDstBands = (int *)
CPLMalloc(psWO->nBandCount*sizeof(int));
for( int i = 0; i < psWO->nBandCount; i++ )
{
psWO->panSrcBands[i] = i+1;
psWO->panDstBands[i] = i+1;
}
/* ----------------------------------------------------------------- */
/* ---------------------执行影像纠正的操作-------------------------- */
/* ----------------------------------------------------------------- */
GDALWarpOperation oWO;
if( oWO.Initialize( psWO ) == CE_None )
{
CPLErr eErr;
eErr = oWO.ChunkAndWarpImage( 0,
0,
pDstDataset->GetRasterXSize(),
pDstDataset->GetRasterYSize() );
if ( eErr == CE_None )
{
bRet = TRUE;
goto WarpImage_clean;
}
}
/* ----------------------------------------------------------------- */
/* ---------------------退出时的清理工作---------------------------- */
/* ----------------------------------------------------------------- */
WarpImage_clean:
GDALDestroyGenImgProjTransformer( hTransformArg );
GDALDestroyWarpOptions( psWO );
return bRet;
}