GDAL 数据模型

GDAL 数据模型

sf2gis@163.com

2012年1月19日

1  概述

GDAL:geospatial dataabstraction library(地理数据抽象库)。

用于将各种栅格数据转换为统一的抽象格式。

OGR:OpenGIS SimpleFeatures Reference Implementation(开源GIS简单元素参考实现)。

用于将各种矢量数据转换为统一的抽象格式。

CPL:common portabilitylibrary。通用可移植库。

用于针对不同OS声明的通用定义。

GDAL按照波段为操作单位,每个波段操作完成后再操作其它波段。

参考:http://www.baike.com/wiki/CPL

2  api

2.1 CPL

CSLFetchBoolean():获取CPL String List中的属性值boolean。

CSLSetNameValue():设置键值对。

CPLMalloc():申请内存。

2.1.1GDALProgressFunc:进度回调函数。

定义:

int (CPL_STDCALL *GDALProgressFunc)(double dfComplete,const char *pszMessage, void *pProgressArg);

dfComplete:表示当前完成的进度(0~1之间的小数)。

pszMessage:字符串消息,通常为NULL

pProgressArg:CreateCopy传递过来的参数。

返回值:TRUE/FALSE返回当前状态,如果需要终止当前操作,则返回FALSE,程序中断,返回TRUE,正常执行。

2.2 GDAL

GDALAllRegister():加载所有驱动。

GDALOpen():打开数据集。打开方式有GA_READONLY/GA_UPDATE。

GDALClose():关闭数据集。

GDALGetRasterDataTypeName():返回枚举值表示的像素大小。

GDALGetColorInterpretationName():返回枚举值表示的颜色类型。

GDALComputeRasterMinMax():计算当前图像波段像素值的最大值、最小值。

GDALReadBlock():读取波段内的块数据。

GetGDALDriverManager():获取GDALDriverManager类的单例。

2.3 WARP

用于高效的图形变换,以及大数据操作。包含一组重采样方法及一组Mask方法(GDALTransformerFunc函数族)。

使用方法:

使用GDALWarpOptions类设置操作的相关参数。

使用GDALWarpOperation类执行变换操作(需要使用GDALWarpOptions作为参数)。

2.3.1 GDALWarpOptions

hSrcDS:源数据集。

hDstDS:目标数据集。

nBandCount:波段数。

panSrcBand/panDstBand:源数据集、目标数据集波段排列。必须使用CPLMalloc在DLL内部申请(因为后面要调用GDALDestroyWarpOptions()的时候要释放,如果使用了外部内存,会出现错误)。如:(int*)CPLMalloc(sizeof(int)*3)

pfnProcess:进度回调函数指针。参见2.1.1。

pTransformerArg:为转换函数pFuncTransformer准备参数。需要一组参数列表。使用GDALCreateGenImgProjTransformer(),GDALCreateReprojectionTransformer(),GDALCreateGCPTransformer(),GDALCreateApproxTransformer()可以创建参数。

pFuncTransformer:转换函数指针。用于将输入和输出进行转换。这是图形变换的主要功能。有部分预定义函数可供使用,也可以自己定义。声明类型为

typedef int(*GDALTransformerFunc)( void *pTransformerArg,

                        int bDstToSrc, intnPointCount,

                        double *x, double *y,double *z, int *panSuccess );

2.3.2 GDALCreateGenImgProjTransformer()和GDALGenImgProjTransform()

创建GeneralImage Project Transform参数。为函数GDALGenImgProjTransform()的函数列表。

GDALGenImgProjTransform():用于进行源图像和目标图像之间的投影变换。变换过程为:Image图像转换为带有源坐标系统的Map,将Map的源坐标系统转换为目标目标系统,将目标坐标系统转换为目标图像。

在转换为的过程中,使用坐标系统,使用GeoTransform()6参数,如果没有,则使用GCP。

void*GDALCreateGenImgProjTransformer   (   GDALDatasetH    hSrcDS,

const char *    pszSrcWKT,

GDALDatasetH    hDstDS,

const char *    pszDstWKT,

int     bGCPUseOK,//TRUE:use gcp if no wkt

double dfGCPErrorThreshold,//ErrorThreshhold

int     nOrder  //GCP maxmum order

)          

2.3.3 GDALWarpOperation

用于执行变换。

Initialize():加载参数。

ChunkAndWarpImage():变换函数。

ChunkAndWarpMulti():多线程变换。

2.4 OGR

2.5 SpatialReference

2.6 DriverImplement

3  数据集GDALDataset

GDAL数据集,表示栅格图像的集合,通常是一个图像文件(及其相同的文件)。

3.1 成员函数

GDALDataset::GetGeoTransform():获取坐标转换参数(与worldfile文件格式相同,参见:..\..\GIS\worldfile.docx)。

GetRasterBand(index):获取影像波段。index的基数是1。

GetRasterCount():波段数。

GetRasterXSize()/GetRasterYSize():x和y方法像素数目。

GetProjectionRef():Proj格式的投影信息。

GetGeoTransform():获取仿射变换的参数。

3.1.1 RasterIO

3.1.1.1  定义

CPLErr GDALDataset::RasterIO

(

GDALRWFlag 

eRWFlag,

int 

nXOff,

int 

nYOff,

int 

nXSize,

int 

nYSize,

void * 

pData,

int 

nBufXSize,

int 

nBufYSize,

GDALDataType 

eBufType,

int 

nBandCount,

int * 

panBandMap,

int 

nPixelSpace,

int 

nLineSpace,

int 

nBandSpace

 

)

 

RasterIO(RWFlage,left,top,width,height,pBuf,dstWidth,dstHeight,type,bandCount,pixelSpace,lineSpace,bandSpace):操作Raster。可以同时操作多个波段。

eRWFlag读写标志

nXOff左上角X(读取图像的X起点)

nYOff左上角Y(读取图像的Y起点)

nXSize读取宽度

nYSize读取高度

pData返回的BUF(因为为从0,0开始,所以与nXoff,nYOff对应的参数为0,0省略)

nBufXSize:buf的宽度(如果与原始图像不同,也就缩放,则会抽取或复制图像像素)

nBufYSize:buf的高度(如果与原始图像不同,也就缩放,则会抽取或复制图像像素)

eBufType:读取的每个波段的每个像素(像素的子波段)的宽度(单位:字节)。

nBandCount:读取的波段数

panBandMap:buf的每个像素中波段的排列顺序。

nPixelSpace:buf中每个像素的宽度(每个像素的总大小=各波段像素的和)(单位:字节)

nLineSpace:buf中每行的大小(单位:字节)。

nBandSpace:buf中下一个波段的像素与上一个波段的像素之间间隔(单位:字节)。

3.1.1.2  参考

gdalAPI。

http://blog.csdn.net/liminlu0314/article/details/7072224

3.1.1.3  示例

#include<gdal_priv.h>

#include<cpl_conv.h>

#pragmacomment(lib,“gdal_i.lib”)

voidCioDlg::OnBnClickedButton1()

{

     // TODO:
在此添加控件通知处理程序代码

     GDALDataset*pDs=NULL;

     GDALAllRegister();

     pDs=(GDALDataset*)GDALOpen(“D:\\output\\out\\J50D001001_lonlat-L15.tif”,GA_ReadOnly);

     {//read all bytes

         intiXSize,iYSize;

         iXSize=pDs->GetRasterXSize();

         iYSize=pDs->GetRasterYSize();

         intRGB[]={1,2,3};

         char*pBufLine=(char*)CPLMalloc(sizeof(char)*iXSize*3*2);//缓冲一行,申请两行的内存(做实验,可能会用到较多内存

         pDs->RasterIO(GF_Read,0,0,iXSize,1,pBufLine,iXSize,1,GDT_Byte,3,RGB,(GDT_Byte)*3,(GDT_Byte)*3*iXSize,1);//读原始数据,第一行

         memset(pBufLine,0x00,sizeof(char)*iXSize*3*2);

         pDs->RasterIO(GF_Read,1,0,iXSize1,1,pBufLine,iXSize1,1,GDT_Byte,3,RGB,(GDT_Byte)*3,((GDT_Byte)*3*iXSize1),1);//读原始数据,第一行第一列至第一行结束

         memset(pBufLine,0x00,sizeof(char)*iXSize*3*2);

         pDs->RasterIO(GF_Read,0,0,iXSize,1,pBufLine,iXSize,1,GDT_Byte,3,RGB,(GDT_Byte)*3,(GDT_Byte)*3*iXSize,2);//读原始数据,第一行,波段间隔2,导致数据间隔2填充,如RGBRGB-R00R00-R0GR0G-R0GRBG…

         memset(pBufLine,0x00,sizeof(char)*iXSize*3*2);

         pDs->RasterIO(GF_Read,0,0,iXSize,1,pBufLine,iXSize,1,GDT_Byte,3,RGB,(GDT_Byte)*3,(GDT_Byte)*3*iXSize,3);//读原始数据,第一行,波段间隔3,导致数据间隔3填充,如RGBRGB-R00R00R00-R00G00G00-R00G00B00…

         TRACE(“OK”);

     }

     GDALClose((GDALDatasetH)pDs);

}

4  波段GDALRasterBand

数据波段,用于表示数据集中一个通道。

GetBlockSize(x,y):获取管理文件的单位块大小。对于不同的文件格式,有不同的大小。一般为一行的大小(x=width,y=1),而瓦片则是整个瓦片的大小。也有一些会被分割成不同的大小。

GetRasterDataType():获取像素数据类型。返回以GDT_xxx表示的枚举值。表示每个像素的大小。

GetColorInterpretation():获取颜色表类型。返回以GCI_xxx表示的枚举值。表示颜色对应的颜色表。

GetMinimum()、GetMaxmum():计算最小值、最大值,如果文件中不包含相关信息,则返回像素类型的最小值、最大值。

ComputeRasterMinMax():计算当前图像波段的最大值,最小值。

RasterIO(RWFlage,xleft,ytop,xRead,yRead,pbuf,xBuf,yBuf,type,pixelspace,linespace):读写IO。

5  坐标系统

坐标系统使用WKT格式。

有两种定义方式(AffineGeoTransform和GCP),可以不定义,但不能同时定义(因无法指定使用哪一个)。

GetProjectionRef():返回由AffineGeotransform(GetGeoTransform())定义的坐标系统。

GetGCPProjection():返回由GCP(GetGCPs())定义的坐标系统。

5.1 AffineGeoTransform仿射参数

由二元仿射变换参数指定。与Worldfile6(..\..\GIS\worldfile.docx)参数相同。

5.2 GCP控制点参数

控制点参数定义为:
typedef struct
{
    char  *pszId; //控制点ID
    char  *pszInfo;//附加信息,通常为NULL
    double          dfGCPPixel;//像素X
    double          dfGCPLine;//像素Y
    double          dfGCPX;//空间X
    double          dfGCPY;//空间Y
    double          dfGCPZ;//空间Z,通常为0
} GDAL_GCP;

6  元数据MetaData

一系列键值对。可以分为不同的Domain。

7  ColorTable颜色表和调色板

颜色表定义了各个波段的可能用到的颜色通道。

调用板定义了不同的颜色方案。

8  Overview缩略图

用于快速显示的抽稀图。

 

9  GDALDriverManager

GDAL支持的Raster格式驱动类。

用于管理所有的驱动。

单例。

使用GetGDALDriverManager()获取单例。

GetDriverByName():按照名称获取驱动。

10     格式驱动GDALDriver

Raster格式的驱动类实现。

用于管理Dataset。

Create/Delete/Rename::创建、删除、重命名Dataset。

CopyFiles():复制Dataset文件。

CreateCopy():复制Dataset到文件。默认使用Create()。可以添加回调函数返回当前的进度。需要参数从源数据集中取。

Create():有可能不支持。需指定必须参数:width,height,bandcount。

QuietDelete():删除。

GetMetaData():获取属性的键值对。

11     操作

11.1 读取图像为RGB

void CioDlg::OnBnClickedButton1()

{

              // TODO: 在此添加控件通知处理程序代码

              GDALDataset *pDs =NULL;

              GDALAllRegister();

              pDs = (GDALDataset*)GDALOpen(“D:\\output\\out\\J50D001001_lonlat-L15.tif”,GA_ReadOnly);

              {//read all bytes

                            intiXSize,iYSize;

                            iXSize =pDs->GetRasterXSize();

                            iYSize =pDs->GetRasterYSize();

                            intRGB[]={1,2,3};

                            char*pBufLine = (char *) CPLMalloc(sizeof(char)*iXSize*3*2);//缓冲一行,申请两行的内存(做实验,可能会用到较多内存

                            pDs->RasterIO(GF_Read,0,0,iXSize,1,pBufLine,iXSize,1,GDT_Byte,3,RGB,(GDT_Byte)*3,(GDT_Byte)*3*iXSize,1);//读原始数据,第一行

                            TRACE(“OK”);

              }

              GDALClose((GDALDatasetH)pDs);

}

11.2 创建文件

文件创建由Driver支持,一般有两种,CreateCopy():全部支持。Create():部分支持。

CreateCopy:由已经存在的Dataset复制到指定的文件。(需要的参数从源数据集中取)

Create():创建文件。必须指定大小和波段数。

//int (CPL_STDCALL *GDALProgressFunc)(double dfComplete, const char*pszMessage, void *pProgressArg);

int CPL_STDCALL pProcFun(double dfComplete, const char *pszMessage, void *pProgressArg)

{

              TRACE(“Process:%f%%,%s,%d\n”,dfComplete*100,pszMessage,(int)pProgressArg);

              return 1;

}

void createFile(void)

{

              GDALAllRegister();

              GDALDataset *pDs =(GDALDataset*)GDALOpen(“D:\\output\\out\\J50D001001_lonlat-L15.tif”,GA_ReadOnly);

 

              GDALDriverManager*pManager = GetGDALDriverManager();

              GDALDriver *pDriver =pManager->GetDriverByName(“GTiff”);

              char **pMetaData =pDriver->GetMetadata();

              {

                            int iTrue= CSLFetchBoolean(pMetaData,GDAL_DCAP_CREATECOPY,FALSE);

                            TRACE(“CreateCopy=%d\n”,iTrue);

              }

              {

                            int iTrue= CSLFetchBoolean(pMetaData,GDAL_DCAP_CREATE,FALSE);

                            TRACE(“Create=%d\n”,iTrue);

              }

              char **pOption = NULL;

              pOption =CSLSetNameValue(pOption,”TILED”,”YES”);

              pOption =CSLSetNameValue(pOption,”COMPRESS”,”PACKBITS”);

              //{

              //           GDALDataset *pDsDst =pDriver->CreateCopy(“D:\\output\\out\\J50D001001_lonlat-L15xxxx.tif”,pDs,FALSE,pOption,pProcFun,(void*)7);

              //           GDALClose(pDsDst);

              //}

              {

                            GDALDataset*pDsDst =pDriver->Create(“D:\\output\\out\\J50D001001_lonlat-little.tif”,512,512,1,GDT_Byte,NULL);

                            doublepAffine[6];

                            pDs->GetGeoTransform(pAffine);

                            pDsDst->SetGeoTransform(pAffine);

                            pDsDst->SetProjection(pDs->GetProjectionRef());

                            charpBuf[512*512];

                            memset(pBuf,0x7d,512*512*1);

                            pDsDst->GetRasterBand(1)->RasterIO(GF_Write,0,0,512,512,pBuf,512,512,GDT_Byte,0,0);

                            GDALClose(pDsDst);

              }

              GDALClose((GDALDatasetH)pDs);

}

11.3 RGB输出为文件

#include <gdal_priv.h>

#include <cpl_conv.h>

#pragma comment(lib,”gdal_i.lib”)

//int (CPL_STDCALL *GDALProgressFunc)(double dfComplete, const char*pszMessage, void *pProgressArg);

int CPL_STDCALL pProcFun(double dfComplete, const char *pszMessage, void*pProgressArg)

{

              TRACE(“Process:%f%%,%s,%d\n”,dfComplete*100,pszMessage,(int)pProgressArg);

              return 1;

}

void createFile(void)

{

              GDALAllRegister();

              GDALDataset *pDs =(GDALDataset*)GDALOpen(“D:\\output\\out\\J50D001001_lonlat-L15.tif”,GA_ReadOnly);

 

              GDALDriverManager*pManager = GetGDALDriverManager();

              GDALDriver *pDriver =pManager->GetDriverByName(“GTiff”);

              char **pMetaData = pDriver->GetMetadata();

              {

                            int iTrue= CSLFetchBoolean(pMetaData,GDAL_DCAP_CREATECOPY,FALSE);

                            TRACE(“CreateCopy=%d\n”,iTrue);

              }

              {

                            int iTrue= CSLFetchBoolean(pMetaData,GDAL_DCAP_CREATE,FALSE);

                            TRACE(“Create=%d\n”,iTrue);

              }

              char **pOption = NULL;

              pOption =CSLSetNameValue(pOption,”TILED”,”YES”);

              pOption =CSLSetNameValue(pOption,”COMPRESS”,”PACKBITS”);

              //{copy dataset to file

              //           GDALDataset *pDsDst =pDriver->CreateCopy(“D:\\output\\out\\J50D001001_lonlat-L15xxxx.tif”,pDs,FALSE,pOption,pProcFun,(void*)7);

              //           GDALClose(pDsDst);

              //}

              //{//rgb 2 file by band

              //           GDALDataset *pDsDst =pDriver->Create(“D:\\output\\out\\J50D001001_lonlat-little.tif”,512,512,3,GDT_Byte,NULL);

              //           double pAffine[6];

              //           pDs->GetGeoTransform(pAffine);

              //           pDsDst->SetGeoTransform(pAffine);

              //           pDsDst->SetProjection(pDs->GetProjectionRef());

              //           char pBuf[512*512];

              //           memset(pBuf,0x7d,512*512*1);

              //           pDsDst->GetRasterBand(1)->RasterIO(GF_Write,0,0,512,512,pBuf,512,512,GDT_Byte,0,0);

              //           memset(pBuf,0x00,512*512*1);

              //           pDsDst->GetRasterBand(2)->RasterIO(GF_Write,0,0,512,512,pBuf,512,512,GDT_Byte,0,0);

              //           memset(pBuf,0xFF,512*512*1);

              //           pDsDst->GetRasterBand(3)->RasterIO(GF_Write,0,0,512,512,pBuf,512,512,GDT_Byte,0,0);

              //           GDALClose(pDsDst);

              //}

              {//rgb 2 file entirely

                            GDALDataset*pDsDst =pDriver->Create(“D:\\output\\out\\J1.tif”,512,512,3,GDT_Byte,NULL);

                            doublepAffine[6];

                            pDs->GetGeoTransform(pAffine);

                            //pAffine[0]+= 0.02197265625;

                            //pAffine[3]-= 0.02197265625;

                            pDsDst->SetGeoTransform(pAffine);

                            pDsDst->SetProjection(pDs->GetProjectionRef());

                            charpBuf[512*512*3];

                            for(int i= 0;i<512;i++)

                            {

                                          for(intj = 0;j<512;j++)

                                          {

                                                        memset(pBuf+i*3*512+j*3+0,0×12,sizeof(char));

                                                        memset(pBuf+i*3*512+j*3+1,0×52,sizeof(char));

                                                        memset(pBuf+i*3*512+j*3+2,0×52,sizeof(char));

                                          }

                            }

                            intpanBand[] = {1,2,3};

                            pDsDst->RasterIO(GF_Write,0,0,512,512,pBuf,512,512,GDT_Byte,3,panBand,3*sizeof(char),3*512*sizeof(char),sizeof(char));

                            GDALClose(pDsDst);

              }

 

              GDALClose((GDALDatasetH)pDs);

}

11.4 图幅拼接

void combineImage(void)

{

              GDALAllRegister();

              GDALDriverManager*pManager = GetGDALDriverManager();

              GDALDriver *pDriver =pManager->GetDriverByName(“GTiff”);

              GDALDataset *pDsDst =pDriver->Create(“D:\\output\\dst-combine.tif”,512*2,512*2,3,GDT_Byte,NULL);

              //get image 1 rgb

              GDALDataset *pDs =NULL;

              pDs = (GDALDataset*)GDALOpen(“D:\\output\\J1.tif”,GA_ReadOnly);

              GDALDataset *pDs2 =NULL;

              pDs2 = (GDALDataset*)GDALOpen(“D:\\output\\J2.tif”,GA_ReadOnly);

              for(int iBand =1;iBand<=3;iBand++)

              {

                            charpBuf[512*512];

                            {//read

                                          memset(pBuf,0x00,512*512*1);

                                          pDs->GetRasterBand(iBand)->RasterIO(GF_Read,0,0,512,512,pBuf,512,512,GDT_Byte,0,0);

                            }

                            //getimage 2 rgb

                            charpBuf2[512*512];

                            {//read

                                          memset(pBuf2,0x00,512*512*1);

                                          pDs2->GetRasterBand(iBand)->RasterIO(GF_Read,0,0,512,512,pBuf2,512,512,GDT_Byte,0,0);

                            }

                                          //write

                                          for(inti = 0;i<512;i++)

                                          {

                                                        pDsDst->GetRasterBand(iBand)->RasterIO(GF_Write,0,i,512,1,pBuf+512*i,512,1,GDT_Byte,0,0);

                                                        pDsDst->GetRasterBand(iBand)->RasterIO(GF_Write,512,i,512,1,pBuf2+512*i,512,1,GDT_Byte,0,0);

                                          }

              }

}

11.5 重采样

#include<gdalwarper.h>

voidwarpImage(void)//resample

{

              GDALAllRegister();

              GDALDataset *pSrcDS =  (GDALDataset*)GDALOpen(“D:\\output\\J1.tif”,GA_ReadOnly);

              GDALDataset *pDstDS =  pSrcDS->GetDriver()->Create(“D:\\output\\warp_dst.tif”,pSrcDS->GetRasterXSize()/2,pSrcDS->GetRasterYSize()/2,

                            pSrcDS->GetRasterCount(),pSrcDS->GetRasterBand(1)->GetRasterDataType(),NULL);

              {//affine

                            double dAffine[6];

                            pSrcDS->GetGeoTransform(dAffine);

                            pDstDS->SetGeoTransform(dAffine);

              }

              pDstDS->SetProjection(pSrcDS->GetProjectionRef());

              GDALWarpOptions *pOptions =GDALCreateWarpOptions();

              pOptions->hSrcDS =(GDALDatasetH)pSrcDS;

              pOptions->hDstDS =(GDALDatasetH)pDstDS;

              pOptions->eResampleAlg =GRA_Bilinear;

              pOptions->nBandCount = 3;

              int panBandMap[] = {1,2,3};

              pOptions->panSrcBands = (int *)CPLMalloc(sizeof(int) * 3 );

              pOptions->panSrcBands[0] = 1;

              pOptions->panSrcBands[1] = 2;

              pOptions->panSrcBands[2] = 3;

              pOptions->panDstBands = (int *)CPLMalloc(sizeof(int) * 3 );

              pOptions->panDstBands[0] = 1;

              pOptions->panDstBands[1] = 2;

              pOptions->panDstBands[2] = 3;

              pOptions->pfnProgress =pProcFun;

              pOptions->pTransformerArg =GDALCreateGenImgProjTransformer(pOptions->hSrcDS,GDALGetProjectionRef(pOptions->hSrcDS),pOptions->hDstDS,GDALGetProjectionRef(pOptions->hSrcDS),FALSE,0.0,1);

              pOptions->pfnTransformer =GDALGenImgProjTransform;

 

              GDALWarpOperation pOperate;

              pOperate.Initialize(pOptions);

              pOperate.ChunkAndWarpImage(0,0,pDstDS->GetRasterXSize(),pDstDS->GetRasterYSize());

              GDALDestroyGenImgProjTransformer(pOptions->pTransformerArg);

              GDALDestroyWarpOptions(pOptions);

              GDALClose(pSrcDS);

              GDALClose(pDstDS);

}

 

转载自:https://blog.csdn.net/sf2gis2/article/details/50686742

You may also like...