剛剛開始學習GDAL,在http://blog.csdn.net/liminlu0314/article/details/7072007的參考下寫了第一個小代碼:
// GDAL_1.cpp : 定義控制檯應用程序的入口點。
//
#include "stdafx.h"
#include "gdal_priv.h"
#include "cpl_conv.h"
#include<iostream>
#include<string>
int _tmain(int argc, _TCHAR* argv[])
{
//註冊文件格式;
GDALAllRegister();
const char* pszFile= "psb.jpg";
GDALDataset* pDataset = (GDALDataset*)GDALOpen(pszFile,GA_ReadOnly);
if(NULL==pDataset)
{
std::cout<<"File doesn't exist!"<<std::endl;
return 0;
}
//輸出圖像格式信息:
//輸出文件格式信息,首先獲得Driver驅動指針?
CPLString strDrive = pDataset->GetDriver()->GetDescription();
CPLString strInfo = pDataset->GetDriver()->GetMetadataItem(GDAL_DMD_LONGNAME);
std::cout<<"文件格式:"<<strDrive<<" "<<strInfo<<std::endl;
//輸出文件大小;
int i = pDataset->GetRasterXSize();
int j = pDataset->GetRasterYSize();
int k = pDataset->GetRasterCount();
std::cout<<"影像寬:"<<i<<std::endl;
std::cout<<"影像高:"<<j<<std::endl;
std::cout<<"影像波段數:"<<k<<std::endl;
//輸出文件投影方式:
CPLString strProjection = pDataset->GetProjectionRef();
if(strProjection!="") //這裏如果沒有投影信息,返回一個空字符串;不是NULL;
{
//printf( "Projectionis `%s'\n", pDataset->GetProjectionRef());
std::cout<<"投影方式:"<<strProjection<<std::endl;
}
//輸出圖像的座標和分辨率信息;
double GeoTransform[6];
if(pDataset->GetGeoTransform(GeoTransform)==CE_None) //CE_None表示成功獲取設置的仿射變換參數
{ //默認的六個參數是0,1,0,0,0,1
for(i=0;i<6;i++)
{
std::cout<<GeoTransform[i]<<" ";
}
std::cout<<std::endl;
}
//圖像波段信息;
GDALRasterBand* poRasterBand;
poRasterBand = pDataset->GetRasterBand(1); //第一個波段的指針;
int nxBlock,nyBlock;
poRasterBand->GetBlockSize(&nxBlock,&nyBlock);
CPLString DataType =GDALGetDataTypeName(poRasterBand->GetRasterDataType()); //獲取數據類型名字;
CPLString ColorType = GDALGetColorInterpretationName(poRasterBand->GetColorInterpretation()); //獲取顏色類型名稱;
std::cout<<"分塊大小爲:"<<nxBlock<<"×"<<nyBlock<<DataType<<std::endl;
std::cout<<"顏色類型爲:"<<ColorType<<std::endl;
//統計像素的最大值最小值;
int ArrMaxMin[2];
ArrMaxMin[0] = poRasterBand->GetMaximum();
ArrMaxMin[1] = poRasterBand->GetMinimum();
std::cout<<"像素數據的最值爲:"<<ArrMaxMin[0]<<"和"<<ArrMaxMin[1]<<std::endl;
//輸出圖像的金字塔信息
if(poRasterBand->GetOverviewCount()!=0) //該函數獲得當前波段的金字塔層數,如果沒有金字塔返回0;
{
std::cout<<"金字塔數目爲:"<<poRasterBand->GetOverviewCount()<<std::endl;
}
//輸出圖像的顏色表信息:
if(poRasterBand->GetColorTable()!=NULL)
{
std::cout<<"顏色表信息:"<<poRasterBand->GetColorTable()->GetColorEntryCount()<<std::endl;
}
//讀取圖像數據:
int nXsize = poRasterBand->GetXSize();
int nYsize = poRasterBand->GetYSize();
char *pBuf = new char[sizeof(GDT_Byte)*nXsize];
poRasterBand->RasterIO(GF_Read,0,0,nXsize,1,pBuf,nXsize,1,GDT_Byte,0,0);
delete[] pBuf;
std::cin.get();
std::cin.get();
return 0;
}
1:首先介紹一下代碼中出現的幾個類:
GDALDataSet一套關聯柵格波段,通常來自一個文件。數據成員包括GDALDriver指針,波段的數目大小,波段列表,引用計數,是否被共享。等信息。以及一個GDALDefaultOverViews對象。提供一個IRasterIO接口給派生類使用,作爲讀取數據的接口。派生於GDALMajorObject類,該類是GDAL所有類的父類;
核心類 GDALMajorObject,它定義了一些操作元數據的屬性和方法供子類繼承。元數據:data about date 描述數據的數據,majorobject使用GDALMultiDomainMetadata
對象存儲元數據。該對象存在一個域名列表和一個元數據內容列表。用戶傳入域名以及元數據內容已進行數據設置。可序列化爲xml。
GDALDriver數據驅動類,只定義了成員方法,沒有成員變量,通過函數指針來實現對於不同的驅動類型採用不同的方式。有Create方法創建數據集,Delete刪除數據集,
Rename重命名數據集,CopyFile,CreateCopy另外定義了其他函數指針,算是接口了。在註冊的時候,根據對象類型創建driver,並設置driver的描述,元數據等,並設置函
數指針爲對應數據集的靜態函數。如poDriver->pfnOpen = JDEMDataset::Open。其中Open方法爲JDEMDataset中的靜態函數。
GDALRasterBand;一個單一的柵格數據波段類,存在一個GDALRasterBlock友元存在一個GDALDataset對象(GDAL貌似很喜歡把外層對象的指針存在分類的對象裏面。
如在學生的信息裏面存儲班級的信息,班級的信息裏面要有一個年級的指針,當然,班級類是學生類的友元,年級類是班級類的友元。難道是學生犯錯了,然後由班級處置的
意思?)Rasterband中定義了比rasterdataset更細緻的數據類型。
2:函數介紹:
Virtual GDALDriver * GetDriver(void); 取得dataset有關係的驅動;獲得當前數據集的驅動格式,返回當前數據集的驅動指針;
Int GetRasterXSize(void);取出柵格寬度,單位像素;
Int GetRasterYSize();取得柵格高度,單位像素
Int GetRasterCount();取得該dataset中柵格波段數目
Virtual const char *GetProjectionRef(void);取得該dataset的投影定義字符
Virtual CPLErr GetGeoTransform (double *); 取得仿射投影變換系數,返回值爲CPL_Err類型;關於該類型:
typedef enum
{
CE_None = 0,
CE_Debug = 1,
CE_Warning = 2,
CE_Failure = 3,
CE_Fatal = 4
} CPLErr;
其實就是一個包含五個數據的枚舉類型;void GetBlockSize(int* pnXsize,int* pnYsize);獲得數據默認的分塊大小;pnXsize和pnYsize分別表示分塊的X和Y大小;
Virtual GDALColorTable* GDALRasterBand::GetColorTable();獲得當前波段的顏色表信息,返回顏色表指針;
Virtual int GDALRasterBand::GetOverviewCount();獲得當前波段的金字塔層數,如果沒有金字塔返回0;
運行結果: