There are two general techniques for creating files, using CreateCopy() and Create().
I had tried both methods in my MFC application. In the program, given one GDALDataset, all the bands were fetched and processed.
I wanted to save the data of those bands into the original GDALDataset, so at first I turned to CreateCopy().
Below are my code to save data into the same GDALDataset.
void SaveSeg(GDALDataset *m_pDataset)
{
int L=Height*Width;//height and width of image
int x,y,d,sernum,label;
int nByteWidth=d_*Width;
float* buf =new float[Width*Height];//to store the band data after process
GDALRasterBand *m_pBand=NULL;
for(d=1;d<d_+1;++d)
{
m_pBand= m_pDataset->GetRasterBand(d);
if (m_pBand)
{
sernum=0;
for(y=0;y<Height;++y)
{
for (x = 0; x < Width; ++x)
{
label=tag[sernum];
//assign buf[] values
buf[sernum]=(S[label].addition[d-1])/(S[label].size)*Range;
++sernum;
}
}
if (CE_None!=m_pBand->RasterIO( GF_Write,0,0, Width, Height, buf, Width,Height,GDT_Float32, 0, 0 ))
{
AfxMessageBox("error write mpdataset!");
}
}
}
delete[]buf;
const char *pszFormat = "GTiff";
GDALDriver *poDriver;
char **papszMetadata;
GDALDataset* poDstDS;
CString herald;
const char*pszDstFilename="contour seg.tif";//(const char*)real;
poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);
if( poDriver == NULL)
exit( 1 );
papszMetadata = poDriver->GetMetadata();
/*check
if( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATE, FALSE ) )
{ herald.Format( "Driver %s supports Create() method./n", pszFormat );
AfxMessageBox(herald);}
if( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATECOPY, FALSE ) )
{ herald.Format( "Driver %s supports CreateCopy() method./n", pszFormat );
AfxMessageBox(herald);}*/
if(poDstDS=poDriver->CreateCopy( pszDstFilename, m_pDataset, FALSE, NULL, NULL, NULL))
GDALClose( (GDALDatasetH) poDstDS);
}
AFfter several tests.I found that for large images, such as 1300x1300, this function did not work.
It only create a copy of the original image but data not processed.
I thought it was the problem of RasterIO, so I turned to WriteBlock() for GDALRasterBand.
But many faults prevents my plan. At last, I resorted to Create(), and I made it.
Below are codes for create().
void SaveSeg2(GDALDataset *m_pDataset)
{
GDALRasterBand *poBand=NULL;
GDALRasterBand *m_pBand=NULL;
poBand= m_pDataset->GetRasterBand(1);
GDALDataType dataType=poBand->GetRasterDataType();
int x,y;
int d,sernum,label;
const char *pszFormat = "GTiff";
GDALDriver *poDriver;
const char*pszDstFilename="inspector.tif";//(const char*)real;
poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);
if( poDriver == NULL)
{
AfxMessageBox("This format is not able to be created!");
exit( 1 );
}
//using create
GDALDataset *poDstDS;
char **papszOptions = NULL;
poDstDS = poDriver->Create( pszDstFilename,Width,Height, d_,dataType,
papszOptions );
double adfGeoTransform[6],backup[6] = { 444720, 30, 0, 3751320, 0, -30 };
if(CE_None==m_pDataset->GetGeoTransform( adfGeoTransform ))
poDstDS->SetGeoTransform( adfGeoTransform );
else
poDstDS->SetGeoTransform(backup);
const char *pszSRS_WKT=m_pDataset->GetProjectionRef();
poDstDS->SetProjection( pszSRS_WKT );
CPLFree( (void*)pszSRS_WKT );
float* buf =new float[Width*Height];
for(d=1;d<d_+1;++d)
{
m_pBand= m_pDataset->GetRasterBand(d);
poBand = poDstDS->GetRasterBand(d);
if (m_pBand)
{
sernum=0;
for(y=0;y<Height;++y)
{
for (x = 0; x < Width; ++x)
{
label=tag[sernum];
buf[sernum]=(S[label].addition[d-1])/(S[label].size)*Range;
++sernum;
}
}
if (CE_None!=poBand->RasterIO( GF_Write,0,0, Width, Height, buf, Width,Height,GDT_Float32, 0, 0 ))
{
AfxMessageBox("error write mpdataset!");
}
}
}
delete[]buf;
GDALClose( (GDALDatasetH) poDstDS );
}
It was said that WriteBlock is more efficient than RasterIO, but it requires more tricks, so I quitted exploring it.