2

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?

not working

  • Yes, absolutely, use the GISinternals download (make sure you get the right version and platform to suit your compiler and environment). I've found that you need to add an additional dependency of gdal_i.lib and have your paths set just right or it wont work. Which part are you having trouble with? Is it all of the concepts or one in particular? There is also a C/C++ help at gdal.org/annotated.html Which version of Visual Studio are you using? – Michael Stimson Jun 10 '15 at 0:31
  • @MichaelMiles-Stimson MS Visual 2013. I'm having troubles with including libraries, because I don't know exactly which ones do I need from GISinternals. As I got all this library was made for python, so there is not a lot guides for c++ – AKovtunov Jun 10 '15 at 11:20
  • I just include the lib/include paths from GDAL as installed and let the linker decide which ones it needs. I can't help with 2013 - Esri requires VS2010, so that's the version I use. In 2010 I open the project properties, find the VC++ Directories and add the paths to GDAL include and lib to the include path and lib path respecitvely then in linker\input\Additional Dependencies add the full path to gdal_i.lib. Hopefully VS2013 is similar. – Michael Stimson Jun 10 '15 at 22:11
  • @MichaelMiles-Stimson I've build gdal from sources, got .dll and .lib files, imported them into my project and included them in configuration. Should I copy that header files that you've linked? – AKovtunov Jun 14 '15 at 21:43
  • Wow, you've got it to build from source, that's more than I could do - I'm missing/unreferenced so many libs. Consider the code provided as an example of just the key points in how to open and access a single pixel (read the comments about what's going on) in conjunction with the tutorial and have a read of the source for GDAL_Translate for an awesome example of how everything works. – Michael Stimson Jun 14 '15 at 22:19
7

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: enter image description here

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: enter image description here To ensure that the compiler/linker can find the inputs that it needs.

  • Thank you very much. I will ask some questions after I will properly install this all. – AKovtunov Jun 10 '15 at 11:24
  • just a small question, do you have a hdf 4 file type support in this configuration? – AKovtunov Jun 15 '15 at 19:07
  • According to the docs once GDALAllRegister() is called any supported dataset can be opened using GDALOpen, you do not need to create a driver using GDALDriverManager::GetDriverByName for opening, only for creating. To test what formats are installed and available use GDALInfo --formats in a CMD window (be sure to limit your paths to the correct version) – Michael Stimson Jun 15 '15 at 22:10
  • I've printing list of drivers but there is no hdf4. So just asking if you had it in your build? Seems like not I need to recompile gdal again -_- – AKovtunov Jun 15 '15 at 22:13
  • No, the HDF4 could be one of the 'other' drivers.. read gis.stackexchange.com/questions/32328/… I can see the HDF5 lib in the download, perhaps it's in one of the other Zip files. Mine is in the gdalplugins dir, perhaps it's with the ECW or MrSID – Michael Stimson Jun 15 '15 at 22:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.