GDAL一次多项式进行几何纠正

用代码说明一切!!!

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;

}


你可能感兴趣的:(地理信息系统)