I need to create a sample console application on c++ that will use *.hdf file as an input and will read it.
As I got, I need a GDAL library. I've found a GDAL tutorial on official GDAL website, but it's splitted on unended parts, so I can't find a good working example of use.
Can someone provide it to me?
Also I have some troubles with the GDAL library. As I found, I need the stable library from gisinternals, yep?
Answer
Here's just the nuts-and-bolts from some working code:
#include "gdal_priv.h"
#include "gdal_alg.h"
// in main()...
GDALAllRegister(); // register all drivers
// open your raster - format doesn't matter as all the drivers are registered
GDALDataset* SourceRasterDS = (GDALDataset*) GDALOpen(Raster,GA_ReadOnly);
double GeoTransform[6]; // Get the geotransform object
SourceRasterDS->GetGeoTransform(GeoTransform); // from the raster dataset
GDALRasterBand* SrcBnd = SourceRasterDS->GetRasterBand(1); // just one band - 1 based, not 0. This raster has only one band.
// read 32bit floating point raster
float* RasterBlock = (float*)malloc(ReadRows*ReadCols*sizeof(float));
SrcBnd->RasterIO(GDALRWFlag::GF_Read,ColOff,RowOff,ReadCols,ReadRows,RasterBlock,ReadCols,ReadRows,GDALDataType::GDT_Float32,0,0);
// localize the X,Y offset to the raster block
LocalX = GeoTransform[0] + (ColOff * GeoTransform[1]);
LocalY = GeoTransform[3] + (RowOff * GeoTransform[5]);
// get a cell in the block - convert X,Y to Col,Row
ThisCol = (Xcoord - LocalX) / GeoTransform[1];
ThisRow = (Ycoord - LocalY) / GeoTransform[5];
// find the index in the 1-d (one dimension, not One Direction) array
LocInArray = (ReadCols*ThisRow) + ThisCol;
CellValue = RasterBlock[LocInArray];
free RasterBlock;
This code gets the value of one cell in a block in the raster.. the original raster was over 2TB as IMG so I couldn't read the whole thing into memory but I needed to do operations within a specified AOI which is translated to ColOff,RowOff and ReadCols by ReadRows rather than trying to read each cell directly from the source raster.
As I said in my comments it is important to set your paths and also add the additional dependency gdal_i.lib or the code will not link properly:
Creating/Writing raster is also fairly straightforward:
GDALDriver* IMGdriver = GetGDALDriverManager()->GetDriverByName(DRVname); // get the ERDAS Imagine driver
GDALDataset* AccumDS;
AccumDS = (GDALDataset*) IMGdriver->Create(AccumName,Cols,Rows,1,GDALDataType::GDT_UInt32,NULL);
AccumDS->SetGeoTransform(GeoTransform);
AccumDS->SetProjection(SR_Text);
AccumData = (unsigned __int32*) malloc(MaxLasRasterSize * 4); // sizeof(__int32) = 4 ALWAYS!!!
AccumDS->RasterIO(GDALRWFlag::GF_Write,ColOff,RowOff,BlockCols,BlockRows,AccumData,BlockCols,BlockRows,GDALDataType::GDT_UInt32,1,NULL,0,0,0);
GDALClose((GDALDatasetH)AccumDS); // very important to close the dataset
This code is missing about 500 lines between creating the memory (AccumData) and writing it - but that's not important in this context. Just remember that you need to address in Col,Row from this current block when modifying values in the memory and you should be fine.
When you download GDAL be sure to download the source, in the tools folder there are some spectacular examples of how to use GDAL that I used as a learning aid, you should find some value in them too.
In Visual Studio (this example from 2010) you need to set some properties in your project: To ensure that the compiler/linker can find the inputs that it needs.
No comments:
Post a Comment