1.GDAL介绍
GDAL是一个转换各种栅格数据格式的库。包括读取、写入、转换、处理各种栅格数据格式(有些
特定的格式对一些操作如写入等不支持)。它使用了一个单一的抽象数据模型就支持了大多数的
栅格数据(GIS对栅格,矢量,3D数据模型的抽象能力实在令人叹服)。当然除了栅格操作,这
个库还同时包括了操作矢量数据的另一个有名的库ogr(转换矢量GIS数据),这样这个库就同时
具备了操作栅格和矢量数据的能力,
目前ogr能够支持的数据格式包括:
Arc/Info Binary Coverage、DWG、ESRI Personal GeoDatabase、ArcSDE、ESRIShapefile、GML、GRASS、Mapinfo File、Microstation DGN、ODBC、Oracle Spatial和PostgreSQL等。应该说,这就基本包括了我们平常用到的所有矢量型GIS文件格式了。Gdal支持的栅格数据格式参阅2.GDAL安装
(1)下载gdal的安装文件,,解压到某目录下
,如C:\gdalsrc下。
这里我们假定VC6的安装在默认目录C:\Program Files\Microsoft Visual Studio8下。(2)启动cmd,即打开控制台窗口。进入VC6的安装目录下,如cd C:\Program Files\MicrosoftVisual Studio8\VC\bin\,在此目录下有个文件VCVARS32.BAT,执行一下这个文件,然后重新回
到C:\gdalsrc下。运行命令nmake /f makefile.vc。编译完成后,用记事本打开文件
C:\gdalsrc\nmake.opt,根据自己的情况修改GDAL_HOME = 这一行,这个指的是最终GDAL的安装
目录,比如说我们安装在C:\GDAL,那么这一行就是GDAL_HOME = "C:\GDAL",在C:\gdalsrc下执
行nmake /f makefile.vc install,然后是nmake /f makefile.vc devinstall,然后我们需要
的东西就安装到了C:\GDAL下。
3.GDAL使用初次使用visual studio 对工具不熟悉,有些步骤可以配置的
(1)在VS2005中新建win32控制台程序 testGDALconsole,(向导中附加选项不能选为空项目)将C:\GDAL\bin\gdal14.dll拷贝到testGDALconsole目录下的debug目录中。(否则运行时会提示找不到gdal14.dll)
(2)在工程的Library files中和Include files中分别添加GDAL的LIB文件目录和头文件目录,这步我不会,就直接将gdal_priv.h拷贝到testGDALconsole.cpp所在目录下
(3)添加一个文件gdal_i.lib。使用 #pragma comment (lib,"..\\lib\\gdal_i.lib")(这步没做)
(4)程序文件样本程序如下:
#include "stdafx.h"
#include "gdal_priv.h"
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
if(argc!=2)
{
return 0;
}
GDALDataset *poDataset;
GDALAllRegister();
poDataset = (GDALDataset *) GDALOpen( argv[1], GA_ReadOnly );
if( poDataset != NULL )
{
cout<<"RasterXSize:"<<poDataset->GetRasterXSize()<<endl;
cout<<"RasterYSize:"<<poDataset->GetRasterYSize()<<endl;
cout<<"RasterCount:"<<poDataset->GetRasterCount()<<endl;
}
return 0;
}
假定生成的程序名为test.exe,假定有一个文件名为1.jpg的文件在C:\下,在命令行下test.exe
c:\1.jpg,程序将打印出此图片的横纵坐标和raster count,如:
C:\>test 1.JPG
RasterXSize:800
RasterYSize:600
RasterCount:3
练习总结:
1)使用 #pragma comment (lib,"..\\lib\\gdal_i.lib")来引入外部的库文件
或者在Visual studio里面设置
project-> properties-> Linker-> Input里面的Additional Dependencies里面加lib
-> properties-> General-> Additional Libary Directories加Lib目录下面附上一个一个GDAL的读写数据例子引自 //
#include "stdafx.h"
#include "fangshibo.h"#include <vector>
#include<math.h>///gdal头文件#include "..\\include\\gdal.h"#include "..\\include\\gdal_priv.h"#include "..\\include\\ogr_srs_api.h"#include "..\\include\\cpl_string.h"#include "..\\include\\cpl_conv.h"#pragma comment (lib,"..\\lib\\gdal_i.lib")/ #ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/
// The one and only application objectCWinApp theApp;
using namespace std;///
void MaxNDVI(vector<CString> files,CString maxNDVfile){ // GDALAllRegister(); vector<GDALDataset *> datasets; //打开文件 for(int i=0;i<files.size();i++) { CString filename=files[i]; GDALDataset *tmpDataset = (GDALDataset *) GDALOpen( files[i],GA_ReadOnly);
if(tmpDataset!=NULL) { datasets.push_back(tmpDataset); } else { fprintf( stderr, "GDALOpen failed - %d\n%s\n", CPLGetLastErrorNo(),CPLGetLastErrorMsg() );
} tmpDataset=NULL;//以后再释放 } 读取数据咯,按行来读取 //GDALDir if(datasets.size()==0)return; GDALDataset *tmpDataset=datasets[0]; if(tmpDataset!=NULL) { GDALDriver * driver=NULL; int index = maxNDVfile.ReverseFind('.'); if (index < 0) return ; if (index == maxNDVfile.GetLength()-1) return ; CString suffix = maxNDVfile.Right(maxNDVfile.GetLength()-1-index);suffix.MakeLower(); if (suffix == "bmp") driver = GetGDALDriverManager()->GetDriverByName("BMP"); else if (suffix == "jpg") driver = GetGDALDriverManager()->GetDriverByName("JPEG"); else if (suffix == "tif") driver = GetGDALDriverManager()->GetDriverByName("GTiff"); else if (suffix == "img") driver = GetGDALDriverManager()->GetDriverByName("HFA"); else if (suffix == "bt") driver = GetGDALDriverManager()->GetDriverByName("BT"); else if (suffix == "ecw") driver = GetGDALDriverManager()->GetDriverByName("ECW"); else if (suffix == "fits") driver = GetGDALDriverManager()->GetDriverByName("FITS"); else if (suffix == "gif") driver = GetGDALDriverManager()->GetDriverByName("GIF"); else if (suffix == "hdf") driver = GetGDALDriverManager()->GetDriverByName("HDF4"); else if (suffix == "hdr") driver = GetGDALDriverManager()->GetDriverByName("EHdr"); int w=tmpDataset->GetRasterXSize(); int h=tmpDataset->GetRasterYSize(); GDALDataset *maxNDV=driver->Create(maxNDVfile,w,h,1,GDT_Float32,NULL);
int xOff=0; int yOff=0; int width=w; int height=1;//一行一行地读取 vector<float*> bufs; for(int i=0;i<datasets.size();i++) { float *buf=new float[width*height]; bufs.push_back(buf); buf=NULL; } float *newbuf=new float[width*height]; GDALRasterBand * newpoband=maxNDV->GetRasterBand(1); for(int j=0;j<h;j++) { for(int i=0;i<datasets.size();i++) { GDALDataset *tmpDt=datasets[i]; GDALRasterBand * poband=tmpDt->GetRasterBand(1); float *buf=bufs[i]; xOff=0; yOff=j; poband->RasterIO
(GF_Read,xOff,yOff,width,height,buf,width,height,GDT_Float32,0,0);
buf=NULL; tmpDt=NULL;//在后面再释放,因为很多个指针指向同一一段内存,不能随便释放内存哦
} // //在这可以开始运算咯 for(int k=0;k<w;k++)//对于每个像元 { //下面这段代码以后要支持均值,极差,方差 for(int kk=0;kk<bufs.size();kk++) { float *buf=bufs[kk]; if(kk==0)//初始化 { newbuf[k]=buf[k]; } if(buf[k]>newbuf[k])//最大的,稍微改下就是最小值, { newbuf[k]=buf[k]; } } } //写入数据 newpoband->RasterIO(GF_Write,xOff,yOff,width,height,newbuf,width,height,GDT_Float32,0,0);
} delete newbuf; newbuf=NULL; for( i=0;i<bufs.size();i++) { if(bufs[i]!=NULL) delete bufs[i]; } bufs.resize(0); delete maxNDV; maxNDV=NULL; delete driver; driver=NULL; } tmpDataset=NULL; //释放掉内存 for( i=0;i<datasets.size();i++) { if(datasets[i]!=NULL) { delete datasets[i]; datasets[i]=NULL; } } datasets.resize(0);}