[GIS] Reading data from raster band with Java and GDAL

gdaljavaraster

After using GDAL with Python for a year or so now, I'm getting back into Java and trying to figure out how to use GDAL with it. I am wondering if anyone has had experience with reading data from a raster band with GDAL and Java. I can read the dataset and band in as follows:

Dataset theDataset = gdal.Open("k:/dem.asc", gdalconst.GA_ReadOnly);
Band theBand = theDataset.GetRasterBand(1);

…but I am not sure how to read data from theBand. From the API documentation it seems that I have to set up an array first, which means I have to know how many elements are in the block of data that I want to extract from the band. Like this:

double[] arr = new double[3];
theBand.ReadRaster(0, 0, 3, 1, arr);

I guess it works fine if you only want to extract one row of data, as above, because you end up with a one-dimensional array. Referencing elements is pretty easy. But if I want to extract a multi-row block of data, it has to be forced into a one-dimensional array. Something like this:

double[] arr = new double[9];
theBand.ReadRaster(0, 0, 3, 3, arr);

Then if I want to reference an individual raster cell in the array I just extracted (for example, if I want to process the block cell-by-cell), I need to convert my two-dimensional grid coordinate (proxy of easting and northing) into a one-dimensional integer array index.

I guess it's not too difficult to write a little method to convert from a grid reference to essentially a vector reference, but it just seems kind of convoluted, especially after being used to using grid references directly in Python-numpy-GDAL.

Is this the only way to extract data from a band in Java/GDAL?

From what I can tell, it is, but I am hoping there is a more intuitive way of processing large blocks of data.

Best Answer

There are a few ways to read the data. Forgive me, but I am not familiar with the java bindings and syntax. One method is to use GDALRasterBand->ReadBlock():

http://gdal.org/classGDALRasterBand.html#a09e1d83971ddff0b43deffd54ef25eef

That reads in the internal block defined by the driver, which is one scanline for the aaigrid driver. See the example in the documentation. To do this manually, similar to your example, use GDALRasterBand->RasterIO(), which appears to be wrapped in java with ReadRaster(). Loop over the raster GDALDataset->GetRasterYSize() times and read in one line:

double[]data = new double[nXSize];
for(int i = 0; i < nYSize; i++)
{
    band.ReadRaster(0, i, nXsize, 1, data);
    //do something with your data
}

You can change the size of your input window for whatever you would like to get from your data. For example, as above, use a 3x3 window on the ReadRaster() call to calculate slope and aspect. I just found a link to the javadoc here:

http://gdal.org/java/

Related Question