第六节GDAL的利用与图片的显示.docx
- 文档编号:1060498
- 上传时间:2023-04-30
- 格式:DOCX
- 页数:10
- 大小:154.80KB
第六节GDAL的利用与图片的显示.docx
《第六节GDAL的利用与图片的显示.docx》由会员分享,可在线阅读,更多相关《第六节GDAL的利用与图片的显示.docx(10页珍藏版)》请在冰点文库上搜索。
第六节GDAL的利用与图片的显示
第六节GDAL的利用
一.什么是GDAL
GDAL(GeospatialDataAbstractionLibrary)是一个在X/MIT许可协议下的开源栅格空间数据转换库。
它利用抽象数据模型来表达所支持的各类文件格式。
它还有一系列命令行工具来进行数据转换和处置。
GDAL提供对多种栅格数据的支持,包括Arc/InfoASCIIGrid(asc),GeoTiff(tiff),ErdasImagineImages(img),ASCIIDEM(dem)等格式。
GDAL利用抽象数据模型(abstractdatamodel)来解析它所支持的数据格式,抽象数据模型包括数据集(dataset),坐标系统,仿射地理坐标转换(AffineGeoTransform),大地控制点(GCPs),元数据(Metadata),栅格波段(RasterBand),颜色表(ColorTable),子数据集域(SubdatasetsDomain),图像结构域(Image_StructureDomain),XML域(XML:
Domains)。
GDALMajorObject类:
带有元数据的对象。
GDALDdataset类:
一般是从一个栅格文件中提取的相关联的栅格波段集合和这些波段的元数据;GDALDdataset也负责所有栅格波段的地理坐标转换(georeferencingtransform)和坐标系概念。
GDALDriver类:
文件格式驱动类,GDAL会为每一个所支持的文件格式创建一个该类的实体,来管理该文件格式。
GDALDriverManager类:
文件格式驱动管理类,用来管理GDALDriver类。
二.GDAL的安装
GDAL编译详细进程:
1)网上/下载最新版本的proj开源投影库,解压到c:
\下
然后利用VS的命令行工具进入到该目录,执行nmakemakefile.vc
2)网上/下载最新版本的geos几何库,解压到c:
\下,双击目录下的autogen.bat,
执行后然后利用VS的命令行工具进入到该目录,执行nmakemakefile.vc
3)拷贝hdf和HDF五、HDF5SZLIB到C:
\
4)打开gdal主目录下的nmake.opt修改:
#UncommentforGEOSsupport
GEOS_DIR=C:
\geos-3.0.4
GEOS_CFLAGS=-I$(GEOS_DIR)/capi-I$(GEOS_DIR)/source/headers-DHAVE_GEOS
GEOS_LIB=$(GEOS_DIR)/source/geos_c_i.lib
#UncommentthefollowingandupdatetoenableNCSAHDFRelease4support.
HDF4_DIR=C:
\HDF
HDF4_LIB=$(HDF4_DIR)\dll\hd424m.lib$(HDF4_DIR)\dll\hm424m.lib\
$(HDF4_DIR)\lib\hd424.lib$(HDF4_DIR)\lib\hm424.libWs2_32.lib
#UncommentthefollowingandupdatetoenableNCSAHDFRelease5support.
HDF5_DIR=C:
\HDF5
SZIP_DIR=C:
\HDF5SZLIB
HDF5_LIB=$(HDF5_DIR)\dll\hdf5dll.lib$(HDF5_DIR)\dll\hdf5_hldll.lib\
$(SZIP_DIR)\dll\szlibdll.lib
5)静态链接proj4
编译GDAL时,你可以按需要添加其它支持,如ProJ,GeoTiff等等,添加方式只要在nmake.opt找到相关配置节,把前面的“#”去掉,即取消注释,然后修改相关的路径即可。
如:
nmake.opt中的PROJ.4stuff节
#PROJ.4stuff
#UncommentthefollowinglinestolinkPROJ.4librarystatically.Otherwise
#itwillbelinkeddynamicallyduringruntime.
#PROJ_FLAGS=-DPROJ_STATIC
#PROJ_INCLUDE=-ID:
\GDAL\proj-
#PROJ_LIBRARY=D:
\GDAL\proj-
本节的作用是控制链接方式,默许是注释的,即采用动态链接方式。
只需拷贝proj的动态库。
若要采用静态链接方式,通过取消gdal的该节注释,并设置proj源码的对应路径即可。
静态链接的益处是,加载之初就会判断库的依赖关系,这可以避免采用动态链接库而又缺少依赖库而出现莫名其妙的现象。
如:
#PROJ.4stuff
#UncommentthefollowinglinestolinkPROJ.4librarystatically.Otherwise
#itwillbelinkeddynamicallyduringruntime.
PROJ_FLAGS=-DPROJ_STATIC
PROJ_INCLUDE=-IC:
\proj-
PROJ_LIBRARY=C:
\proj-
6)去/下一个版本,解压到c:
\,修改frmts下leverers的CPP文件的?
号。
固然,若是没问题就不用修改
7)打开gdal文件夹下的nmake.opt修改GDAL_HOME="C:
\warmerda\bld"把路径改到需要把gdal安装的地方。
不改也可以。
若是需要python支持(我的主要目的,没有python活不下去)修改PY_INST_DIR=$(GDAL_HOME)\pymod把路径改成python下的Lib\site-packages文件夹下。
PYDIR="C:
\Software\Python24"改成python的安装路径。
下面的参数爱改什么就把前面的#删除(要看您有无那些库的源码),注意一下路径就可以够了。
后面就依次运行
nmake/fmakefile.vc
nmake/fmakefile.vcinstall
nmake/fmakefile.vcdevinstall
三.GDAL的利用
首先创建工程,选择‘单文档’,工程名为‘six’,基类选择‘CView’,创建完成后在项目—six属性—配置属性—常规—字符集选择‘利用多字节字符集’。
然后将GDAL相关的dll和proj等资料拷贝到工程的文件夹下。
在sixview.h中需要添加引用的头文件gdal_priv.h和ogrsf_frmts.h。
(1)调色板位图的显示
若是咱们需要显示图像,咱们需要添加上节咱们所利用的BitmapPainter类,并在sixview.h中引用该类的头文件“#include"include\BitmapPainter.h"”。
同时声明变量:
protected:
CPalBitmapPainterimage;
intnWidth;
intnHeight;
在sixview.cpp的构造函数中为nWidth和nHeight赋值:
Csixview:
:
Csixview()
{
//TODO:
在此处添加构造代码
nWidth=0;
nHeight=0;
}
添加OnCreat消息,生成的OnCreat函数中添加代码,用以读取图像信息,并将信息传给image。
代码如下:
intCTestGdalView:
:
OnCreate(LPCREATESTRUCTlpCreateStruct)
{
charszFilter[]="GeoTiff(*.tif)|*.tif|bmp(*.bmp)|*.bmp|AllFiles(*.*)|*.*||";//设置打开文件类型
CStringfilePath("");
CFileDialogfileOpenDlg(TRUE,"tif",NULL,OFN_HIDEREADONLY
szFilter);//打开阅读文件夹对话框
if(fileOpenDlg.DoModal()==IDOK)
{
VERIFY(filePath=fileOpenDlg.GetPathName());
}
else
return;
CStringstrFilePath(filePath);
//下面利用GDAL读取图像
GDALDataset*poDataset;
GDALAllRegister();
poDataset=(GDALDataset*)GDALOpen(strFilePath,GA_ReadOnly);
//用GDALOpen()函数来打开一个数据集dataset
doubleadfGeoTransform[6];
intCols=poDataset->GetRasterXSize();//图像的宽度
intRows=poDataset->GetRasterYSize();//图像的高度
//DOUBLELeft,Top,Right,Bottom;
//DOUBLEXCellSize,YCellSize;
//CStringsp;
//if(poDataset->GetGeoTransform(adfGeoTransform)==CE_None)//获取仿射影像
//{
//Left=adfGeoTransform[0];
//Top=adfGeoTransform[3];
//XCellSize=adfGeoTransform[1];
//YCellSize=fabs(adfGeoTransform[5]);
//Right=adfGeoTransform[0]+Cols*XCellSize;
//Bottom=adfGeoTransform[3]-Rows*YCellSize;
//}
//if(poDataset->GetProjectionRef()!
=NULL)
//{
//sp=poDataset->GetProjectionRef();
//}
GDALRasterBand*poBand;
intBandCount=poDataset->GetRasterCount();//取得图像的波段数
poBand=poDataset->GetRasterBand
(1);
BYTE*pafScanline;
pafScanline=newBYTE[Cols];//每行所需的byte数
nWidth=Cols;//OnDraw的时候需要用来调整设备区域和客户区域
nHeight=Rows;
image.InitialImage(Rows,Cols);//利用BitmapPainter类中的方式初始化图像
//CColorTable*pTable=newCColorTable;
//intColorCount=256;
//pTable->SetColorCount(ColorCount);
//image.CopyColorTable(pTable);
//deletepTable;
for(intk=0;k { poBand->RasterIO(GF_Read,0,k,Cols,1,pafScanline,Cols,1,GDT_Byte,0,0);//将图像读入pafScanline内存中去 image.CopyRowData(k,pafScanline); } delete[]pafScanline; GDALClose(poDataset);//关闭GDAL Invalidate();//使视图无效,然后刷新 } 此刻我就只需将图像显示出来就是了,图像的显示固然要在OnDraw函数中编写: voidCsixview: : OnDraw(CDC*pDC) { CTestGdalDoc*pDoc=GetDocument(); ASSERT_VALID(pDoc); if(! pDoc) return; CRectrect; GetClientRect(rect);//取得客户区范围 image.PaintDIB(pDC->m_hDC,CRect(0,0,nWidth,nHeight),CRect(0,0,nWidth,nHeight));//在此可以设定设备和图像的显示 } 效果如下图 (2)真彩色位图的显示 真彩色位图的显示与上面的位图显示方式相近,只是在GDAL读取的时候略有不同,因为真彩色图像具有三个波段,咱们需要对每一个波段都要别离读取,咱们需要先声明变量 CRGBBitmapPainterimage; IntnWidth; IntnHeight; 下面代码只修改了OnCreat中将影像读入的进程: GDALRasterBand*poBand1;//遥感的一个波段 GDALRasterBand*poBand2; GDALRasterBand*poBand3; intnBandCount; nBandCount=poDataset->GetRasterCount(); poBand1=poDataset->GetRasterBand (1); poBand2=poDataset->GetRasterBand (2); poBand3=poDataset->GetRasterBand(3); byte*pafscanblock1; byte*pafscanblock2; byte*pafscanblock3; pafscanblock1=newbyte[Cols]; pafscanblock2=newbyte[Cols]; pafscanblock3=newbyte[Cols]; image.InitialImage(Rows,Cols); for(intk=0;k { poBand1->RasterIO(GF_Read,0,k,Cols,1,pafscanblock1,Cols,1,GDT_Byte,0,0); image.CopyRowData(0,k,pafscanblock1); //将波段1读入内存pafscanblock1 poBand2->RasterIO(GF_Read,0,k,Cols,1,pafscanblock2,Cols,1,GDT_Byte,0,0); image.CopyRowData(1,k,pafscanblock2); //将波段2读入内存pafscanblock2 poBand3->RasterIO(GF_Read,0,k,Cols,1,pafscanblock3,Cols,1,GDT_Byte,0,0); image.CopyRowData(2,k,pafscanblock3); //将波段3读入内存pafscanblock3 } delete[]pafscanblock1; delete[]pafscanblock2; delete[]pafscanblock3; GDALClose(poDataset);//关闭GDAL Invalidate(); 运行后效果如下图: 附注: 1)friendclass可让友元类访问到自己类的私有成员。 virtualclassmember的声明可让程序访问到真正的对象的成员。 classa声明了classc是其友元类,所以classc可以访问到classa的私有成员。 可是friend关系是不可以继承的,也就是说,classd不可以访问到classa的私有成员。 2)void*memcpy(void*dest,void*src,unsignedintcount);用法: #include 由src所指内存区域复制count个字节到dest所指内存区域。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第六 GDAL 利用 图片 显示