• GDALDataset的创建和销毁


    之前在GDALDestroyDriverManager 分析中没有看到对dGDALDatasert的回收。先看一个例子程序,这个例子打开了一个tif文件,读取了一些基本信息。

    为了简单示范,没有写成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代码:

    /**
     * rief 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支持普通和引用计数管理两种生命周期管理方式。代码中表明在销毁的时候使用了互斥量,因此是线程安全的。

  • 相关阅读:
    fopen和open的区别
    vc代码缩进
    防止u盘中autorun的一个小方法
    判断单链表是否有环
    四色原理
    Log4j的使用
    Ant学习笔记
    关于Oracle Exp00003问题的解决方法
    装机小记
    用iframe做编辑器
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3260706.html
Copyright © 2020-2023  润新知