GDAL库初学

打开文件

在打开一个GDAL支持的栅格资料之前,必需要注册驱动。 每个驱动对应各自支持的格式。

通常这个会被GDALAllRegister()函数完成。

C++

#include"gdal_priv.h"
#include"cpl_conv.h" // forCPLMalloc()
 
int main(){
    GDALDataset  *poDataset;
    GDALAllRegister();
    poDataset = (GDALDataset*) GDALOpen( pszFilename, GA_ReadOnly );
    if( poDataset == NULL )
    {
        ...;
    }

Python

    import gdal
    from gdalconst import *
 
    dataset = gdal.Open( filename, GA_ReadOnly )
    if dataset is None:
        ...

获取数据集信息

//   adfGeoTransform[0] /* top left x, 图像左上角x坐标值*/

//   adfGeoTransform[1] /* w-e pixel resolution,图像横坐标 ?米/每像素 */

//   adfGeoTransform[2] /* rotation, 0 if image is "north up" */

//   adfGeoTransform[3] /* top left y 图像左上角y坐标值*/

//   adfGeoTransform[4] /* rotation, 0 if image is "north up"  */

//   adfGeoTransform[5] /* n-s pixel resolution 图像纵坐标 ?米/每像素*/


//由像素计算地理坐标值:

//          Xgeo = GT(0) + Xpixel*GT(1) + Yline*GT(2)

//          Ygeo = GT(3) + Xpixel*GT(4) + Yline*GT(5)


通过GDAL存取栅格数据,每次只完成一个波段

以波段为基础的元数据,区块,颜色表和其他可见的信息

dataset通过GetRasterCount()方法获取GDALRasterBand对象 显示相关信息

C++:

        GDALRasterBand  *poBand;
        int             nBlockXSize, nBlockYSize;
        int             bGotMin, bGotMax;
        double          adfMinMax[2];
       
        poBand = poDataset->GetRasterBand( 1);
        poBand->GetBlockSize(&nBlockXSize, &nBlockYSize );
        printf( "Block=%dx%d Type=%s,ColorInterp=%s\n",
                nBlockXSize, nBlockYSize,
               GDALGetDataTypeName(poBand->GetRasterDataType()),
                GDALGetColorInterpretationName(
                   poBand->GetColorInterpretation()) );
 
        adfMinMax[0] = poBand->GetMinimum(&bGotMin );
        adfMinMax[1] = poBand->GetMaximum(&bGotMax );
        if( ! (bGotMin && bGotMax) )
           GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax);
 
        printf( "Min=%.3fd,Max=%.3f\n", adfMinMax[0], adfMinMax[1] );
       
        if( poBand->GetOverviewCount() >0 )
            printf( "Band has %doverviews.\n", poBand->GetOverviewCount() );
 
        if( poBand->GetColorTable() != NULL)
            printf( "Band has a colortable with %d entries.\n",
                    poBand->GetColorTable()->GetColorEntryCount() );
python:
        print 'Driver: ',dataset.GetDriver().ShortName,'/', \
          dataset.GetDriver().LongName
        print'Size is ',dataset.RasterXSize,'x',dataset.RasterYSize, \
          'x',dataset.RasterCount
        print'Projection is ',dataset.GetProjection()
   
        geotransform= dataset.GetGeoTransform()
        if not geotransform is None:
             print 'Origin = (',geotransform[0],',',geotransform[3],')'
             print 'Pixel Size = (',geotransform[1],',',geotransform[5],')'

Reading raster data:读取栅格数据

有很多方法去读取栅格数据,但是最常见的是通过GDALRasterBand::RasterIO()方法。

这个方法将会自动的处理数据类型转换,向上/向下取样和构建窗口。 

以下代码将会读取第一行数据到相同大小的缓冲区中,作为操作的一部分将其转换为浮点型。

C++:

        float *pafScanline;
        int  nXSize = poBand->GetXSize();
 
        pafScanline = (float *)CPLMalloc(sizeof(float)*nXSize);
        poBand->RasterIO( GF_Read, 0, 0,nXSize, 1,
                          pafScanline, nXSize,1, GDT_Float32,
                          0, 0 );

注:padScanline不再使用时用CPLFree()掉

python:
scanline = band.ReadRaster( 0, 0,band.XSize, 1, \
                                    band.XSize, 1, GDT_Float32 )

注:scanline是xsize*4字节的string floating pointer data,以下方法可以转换

        import struct

        tuple_of_floats = struct.unpack('f' * b2.XSize, scanline)

closing the dataset:关闭数据集

调用GDALClose()

Techniques for Creating Files:  createCopy() 和 Creat()

CreateCopy 方法需要调用格式驱动上的CreateCopy()方法,并且通过源dataset来复制

创建的方法需要调用驱动的Create()方法,然后清楚的写入所有的元数据和栅格波段通过不同的调用

所有支持创建新文件的驱动都支持CreateCopy()方法,但是仅仅一部分支持Create()方法

若要确定一个格式驱动对象是否支持Create()或者CreateCopy(),我们可以考察元数据DCAP_CREATE 和 DCAP_CREATECOPY。确保在调用GetDriverByName()方法之前已经调用了GDALAllRegister()方法。在下面的例子中,循环一个驱动,来确定它是否支持Create()或者CreateCopy()。

c++:
 #include "cpl_string.h"
...
    const char *pszFormat = "GTiff";
    GDALDriver *poDriver;
    char **papszMetadata;
 
    poDriver =GetGDALDriverManager()->GetDriverByName(pszFormat);
 
    if( poDriver == NULL )
        exit( 1 );
 
    papszMetadata = poDriver->GetMetadata();
    if( CSLFetchBoolean( papszMetadata,GDAL_DCAP_CREATE, FALSE ) )
        printf( "Driver %s supports Create()method.\n", pszFormat );
    if( CSLFetchBoolean( papszMetadata,GDAL_DCAP_CREATECOPY, FALSE ) )
        printf( "Driver %s supportsCreateCopy() method.\n", pszFormat );
python:
    format = "GTiff"
    driver = gdal.GetDriverByName( format )
    metadata = driver.GetMetadata()
    if metadata.has_key(gdal.DCAP_CREATE) \
       and metadata[gdal.DCAP_CREATE] == 'YES':
        print 'Driver %s supports Create()method.' % format
    if metadata.has_key(gdal.DCAP_CREATECOPY) \
       and metadata[gdal.DCAP_CREATECOPY] =='YES':
        print 'Driver %s supports CreateCopy()method.' % format

Using CreateCopy():

一个简单的拷贝,从一个名为pszSrcFilename的文件到一个新文件pszDstFilename,使用驱动是事先初始化好的默认选项格式拷贝方式

c++:
    GDALDataset *poSrcDS =
       (GDALDataset *) GDALOpen( pszSrcFilename,GA_ReadOnly );
    GDALDataset *poDstDS;
 
    poDstDS = poDriver->CreateCopy(pszDstFilename, poSrcDS, FALSE,
                                    NULL, NULL,NULL );
    /* Once we're done, close properly thedataset */
    if( poDstDS != NULL )
        GDALClose( (GDALDatasetH) poDstDS );
    GDALClose( (GDALDatasetH) poSrcDS );
python:
    src_ds = gdal.Open( src_filename )
    dst_ds = driver.CreateCopy( dst_filename,src_ds, 0 )
 
    # Once we're done, close properly thedataset
    dst_ds = None
    src_ds = None

包含自定义选项,使用预先定义的方式来传递选项值

c++:
#include "cpl_string.h"
    ...
    char **papszOptions = NULL;
   
    papszOptions = CSLSetNameValue(papszOptions, "TILED", "YES" );
    papszOptions = CSLSetNameValue(papszOptions, "COMPRESS", "PACKBITS" );
    poDstDS = poDriver->CreateCopy(pszDstFilename, poSrcDS, FALSE,
                                   papszOptions, GDALTermProgress, NULL );
 
    /* Once we're done, close properly thedataset */
    if( poDstDS != NULL )
        GDALClose( (GDALDatasetH) poDstDS );
    CSLDestroy( papszOptions );
python:
    src_ds = gdal.Open( src_filename )
    dst_ds = driver.CreateCopy( dst_filename,src_ds, 0,
                                [ 'TILED=YES','COMPRESS=PACKBITS' ] )
    # Once we're done, close properly thedataset
    dst_ds = None
    src_ds = None

Using Create()

有时候,你不仅输出一个现有文件到另一个新文件,一般来讲需要使用GDALDriver::Create()方法。该方法有跟CreateCopy()方法类似的属性选择列

表,但是图像大小,波段数和波段类型必须准确给出。

C++:
    GDALDataset *poDstDS;      
    char **papszOptions = NULL;
 
    poDstDS = poDriver->Create(pszDstFilename, 512, 512, 1, GDT_Byte,
                                papszOptions );

一旦数据集创建成功,所有的元数据和光栅数据必须被写入文件。这些数据的多样化依赖于个人设置习惯。这里是一个简单的例子。

    double adfGeoTransform[6] = { 444720, 30,0, 3751320, 0, -30 };
    OGRSpatialReference oSRS;
    char *pszSRS_WKT = NULL;
    GDALRasterBand *poBand;
    GByte abyRaster[512*512];
 
    poDstDS->SetGeoTransform( adfGeoTransform);
   
    oSRS.SetUTM( 11, TRUE );
    oSRS.SetWellKnownGeogCS( "NAD27");
    oSRS.exportToWkt( &pszSRS_WKT );
    poDstDS->SetProjection( pszSRS_WKT );
    CPLFree( pszSRS_WKT );
 
    poBand = poDstDS->GetRasterBand(1);
    poBand->RasterIO( GF_Write, 0, 0, 512,512,
                      abyRaster, 512, 512,GDT_Byte, 0, 0 );   
 
    /* Once we're done, close properly thedataset */
    GDALClose( (GDALDatasetH) poDstDS );
python:
    dst_ds = driver.Create( dst_filename, 512,512, 1, gdal.GDT_Byte )
 
    import osr
    import numpy
 
    dst_ds.SetGeoTransform( [ 444720, 30, 0,3751320, 0, -30 ] )
   
    srs = osr.SpatialReference()
    srs.SetUTM( 11, 1 )
    srs.SetWellKnownGeogCS( 'NAD27' )
    dst_ds.SetProjection( srs.ExportToWkt() )
 
    raster = numpy.zeros( (512, 512),dtype=numpy.uint8 )   
    dst_ds.GetRasterBand(1).WriteArray( raster)
 
    # Once we're done, close properly thedataset
    dst_ds = None

GDAL库的细节

关于ReadRaster

ReadAsArray,返回的是Numeric模块定义的Array

例:

dataset =gdal.Open("f:/pyproj/gtif/aspect.tif")

band =dataset.GetRasterBand(1)

band.ReadAsArray(100,100,5,5,10,10)

参数说明:

头两个100是取值窗口左上角在实际数据中所处象元的x,y位置

两个5是取值窗口覆盖面积的大小

两个10是取值窗口取出数组进行缩放后数组的大小(可以不指定,不指定同前两个参数)

注意:不要访问越界,越界会报错

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值