您的位置:首页 > 其它

GDAL 数据模型

2016-02-18 15:58 429 查看
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,iXSize-1,1,pBufLine,iXSize-1,1,GDT_Byte,3,RGB,(GDT_Byte)*3,((GDT_Byte)*3*iXSize-1),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,0x12,sizeof(char));
                                                        memset(pBuf+i*3*512+j*3+1,0x52,sizeof(char));
                                                        memset(pBuf+i*3*512+j*3+2,0x52,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);
}
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息