第一个GDAL代码实践
刚刚开始学习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;
运行结果:
转载自:https://blog.csdn.net/zhang_alongzd/article/details/51527360