GDALDatasetの作成と破棄
これまでGDALDestroyDriverManager解析ではdGDALDatasertの回収は見られませんでした.まず例プログラムを見て、この例はtifファイルを開いて、いくつかの基本情報を読みました.
簡単に示すために,C++と書かれていない種々のクラスが各ファイルに分散している.
main関数では、GDALOpenでtifファイルを開き、GDALDatasetオブジェクトのポインタを取得し、GDALCloseでオブジェクトを破棄します.次はGDALCloseコードです.
注記GDALDatasetでは、通常と参照カウント管理の2つのライフサイクル管理がサポートされています.コードには、破棄時に反発量が使用されているため、スレッドが安全であることが示されています.
簡単に示すために,C++と書かれていない種々のクラスが各ファイルに分散している.
#include "stdafx.h"
#include "gdal_priv.h"
#include "cpl_conv.h" // for CPLMalloc()
#include <string>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <boost/cstdint.hpp>
using namespace std;
void print_line() {
cout << "----------------------" << endl;
}
void printDataType(GDALDataType type) {
if (type == GDALDataType::GDT_Byte) {
cout << "GDALDataType: GDT_Byte" << endl;
} else {
cout << "GDALDataType: GDT_Unknown" << endl;
}
}
void printAccess(GDALAccess access) {
if (access == GDALAccess::GA_ReadOnly) {
cout << "GDALAccess: GA_ReadOnly" << endl;
} else {
cout << "GDALAccess: GA_Update" << endl;
}
}
void printCategoryNames(char** names) {
if (names == NULL) {
cout << "non category names" << endl;
return;
}
size_t i = 0;
char* str = names[i];
while(str != "") {
cout << str << endl;
str = names[i];
}
}
void printColorInterp(GDALColorInterp interp) {
switch(interp) {
case GDALColorInterp::GCI_AlphaBand:
cout << "GDALColorInterp: GCI_AlphaBand" << endl;
break;
case GDALColorInterp::GCI_BlackBand:
cout << "GDALColorInterp: GCI_BlackBand" << endl;
break;
case GDALColorInterp::GCI_RedBand:
cout << "GDALColorInterp: GCI_RedBand" << endl;
break;
case GDALColorInterp::GCI_GreenBand:
cout << "GDALColorInterp: GCI_GreenBand" << endl;
break;
case GDALColorInterp::GCI_BlueBand:
cout << "GDALColorInterp: GCI_BlueBand" << endl;
break;
default:
cout << "GDALColorInterp: GCI_Undefined: " << interp << endl;
}
}
void printColorTable(GDALColorTable* table) {
if (table == NULL) {
cout << "color table is null" << endl;
return;
}
cout << "ColorEntryCount: " << table->GetColorEntryCount() << endl;
}
string getBytesAsHexString(uint8_t * data, size_t size) {
stringstream stream;
stream << std::hex << std::uppercase << std::setfill('0');
for (size_t i = 0; i < size; ++i) {
stream <<std::setw(2) << static_cast<uint32_t>(data[i] & 0xff) << " ";
}
return stream.str();
}
void printBand(GDALRasterBand* band) {
cout << "XSize: " << band->GetXSize() << endl;
cout << "YSize: " << band->GetYSize() << endl;
cout << "Band number(index for itself): " << band->GetBand() << endl;
printDataType(band->GetRasterDataType());
int x_size = 0;
int y_size = 0;
band->GetBlockSize(&x_size, &y_size);
cout << "Band Block size, x size: " << x_size << " pixels , y size: " << y_size << " pixels" << endl;
printAccess(band->GetAccess());
printCategoryNames(band->GetCategoryNames());
cout << "no data value: " << band->GetNoDataValue() << endl;
cout << "minimum value: " << band->GetMinimum() << endl;
cout << "maximum value: " << band->GetMaximum() << endl;
cout << "offset value: " << band->GetOffset() << endl;
cout << "scale value: " << band->GetScale() << endl;
cout << "unit type: " << band->GetUnitType() << endl;
printColorInterp(band->GetColorInterpretation());
printColorTable(band->GetColorTable());
GByte * data = static_cast<GByte*>(CPLMalloc(x_size * y_size));
band->ReadBlock(5000, 3000, data);
cout << "one block data: " << getBytesAsHexString(data, x_size * y_size) << endl;
}
void printTiffInfo(GDALDataset* set) {
print_line();
cout << "Tiff info " << endl;
cout << "RasterXSize: " << set->GetRasterXSize() << endl;
cout << "RasterYSize: " << set->GetRasterYSize() << endl;
size_t band_count = set->GetRasterCount();
cout << "Raster band count: " << band_count << endl;
for (size_t i = 1; i <= band_count; ++i) {
GDALRasterBand* band = set->GetRasterBand(i);
print_line();
cout << "Band " << i << " : " << endl;
printBand(band);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
GDALAllRegister();
string data_dir = "../../../study/data/";
string tiffPath = data_dir + "v4_dem_gtopo30/v4_dem.tif";
GDALDataset* dataset = (GDALDataset *) GDALOpen(tiffPath.c_str(), GA_ReadOnly);
if (dataset == NULL) {
cout << "open ttf file in TiffCopy app failed" << endl;
GDALDestroyDriverManager();
exit(1);
}
cout << "loading tiff file successfully" << endl;
printTiffInfo(dataset);
GDALClose(dataset);
GDALDestroyDriverManager();
return 0;
}
main関数では、GDALOpenでtifファイルを開き、GDALDatasetオブジェクトのポインタを取得し、GDALCloseでオブジェクトを破棄します.次はGDALCloseコードです.
/**
* \brief Close GDAL dataset.
*
* For non-shared datasets (opened with GDALOpen()) the dataset is closed
* using the C++ "delete" operator, recovering all dataset related resources.
* For shared datasets (opened with GDALOpenShared()) the dataset is
* dereferenced, and closed only if the referenced count has dropped below 1.
*
* @param hDS The dataset to close. May be cast from a "GDALDataset *".
*/
void CPL_STDCALL GDALClose( GDALDatasetH hDS )
{
VALIDATE_POINTER0( hDS, "GDALClose" );
GDALDataset *poDS = (GDALDataset *) hDS;
CPLMutexHolderD( &hDLMutex );
CPLLocaleC oLocaleForcer;
if (poDS->GetShared())
{
/* -------------------------------------------------------------------- */
/* If this file is in the shared dataset list then dereference */
/* it, and only delete/remote it if the reference count has */
/* dropped to zero. */
/* -------------------------------------------------------------------- */
if( poDS->Dereference() > 0 )
return;
delete poDS;
return;
}
/* -------------------------------------------------------------------- */
/* This is not shared dataset, so directly delete it. */
/* -------------------------------------------------------------------- */
delete poDS;
}
注記GDALDatasetでは、通常と参照カウント管理の2つのライフサイクル管理がサポートされています.コードには、破棄時に反発量が使用されているため、スレッドが安全であることが示されています.