/*
* Copyright 2011 by Mark Coletti, Keith Sullivan, Sean Luke, and
* George Mason University Mason University Licensed under the Academic
* Free License version 3.0
*
* See the file "LICENSE" for more information
*
* $Id$
*
*/
package sim.io.geo;
import com.vividsolutions.jts.geom.Envelope;
import java.io.FileNotFoundException;
import java.net.URL;
import org.gdal.gdal.Band;
import org.gdal.gdal.Dataset;
import org.gdal.gdal.gdal;
import org.gdal.gdalconst.gdalconstConstants;
import sim.field.geo.GeomGridField;
import sim.field.geo.GeomGridField.GridDataType;
import sim.field.grid.AbstractGrid2D;
import sim.field.grid.DoubleGrid2D;
import sim.field.grid.IntGrid2D;
/**
*
*/
public class GDALImporter
{
/** Read geospatial grid data from inputSource into field
*
* This only reads the first band of data.
*
* @param inputSource of grid data
* @param type denotes the base type as either integer or double-based
* @param field is field to populate
*
* @throws FileNotFoundException
* @thrown RuntimeException if unable to read data
*
* TODO: add support for reading specific band, or multiband datasets
*/
public static void read(final URL inputSource, GridDataType type, GeomGridField field) throws FileNotFoundException
{
gdal.AllRegister(); // register the plugins for all supported data formats
Dataset dataset = gdal.Open(inputSource.getFile());
if (dataset == null)
{
throw new FileNotFoundException(inputSource + " not found");
}
int xSize = dataset.getRasterXSize();
int ySize = dataset.getRasterYSize();
AbstractGrid2D grid = null;
// GDAL starts from 1, not zero
Band band = dataset.GetRasterBand(1);
if (band == null)
{
throw new RuntimeException("Unable to get raster band");
}
switch (type)
{
case INTEGER:
grid = new IntGrid2D(xSize, ySize);
readIntegerBased(xSize, ySize, band, (IntGrid2D) grid);
break;
case DOUBLE:
grid = new DoubleGrid2D(xSize, ySize);
readDoubleBased(xSize, ySize, band, (DoubleGrid2D) grid);
break;
}
field.setGrid(grid);
// See http://gdal.org/ for the magic meaning of transformData
double [] transformData = dataset.GetGeoTransform();
// Grab the pixel and image dimensions from the GeoTransform object
field.setPixelHeight(Math.abs(transformData[5]));
field.setPixelWidth(Math.abs(transformData[1]));
// Now to set up the image's MBR
Envelope MBR = new Envelope(transformData[0], transformData[0] + transformData[1] * xSize,
transformData[3] + transformData[5] * ySize, transformData[3]);
field.setMBR(MBR);
dataset.FlushCache();
dataset = null;
}
/** Not intended to be instantiated as there is no local state
*/
private GDALImporter()
{
}
/** Reads integer-based geospatial data
*
* Helper function for ingest().
*
* @param xSize
* @param ySize
* @param band
* @param grid
* @throws RuntimeException if GDAL complains about reading the data
*
* @see ingest()
*/
private static void readIntegerBased(int xSize, int ySize, Band band, IntGrid2D grid) throws RuntimeException
{
int result = 0;
int [] line = new int[xSize];
for (int currRow = 0; currRow < ySize; currRow++)
{
//result = band.ReadRaster(0, currRow, xSize, 1, line);
if (result != gdalconstConstants.CE_None)
{
throw new RuntimeException("Problem reading raster");
}
for (int currCol = 0; currCol < xSize; currCol++)
{
int i = line[currCol];
grid.set(currCol, currRow, i);
}
}
}
/** Reads double-based geospatial data
*
* Helper function for ingest().
*
* @param xSize
* @param ySize
* @param band
* @param grid
* @throws RuntimeException if GDAL complains about reading the data
*
* @see ingest()
*/
private static void readDoubleBased(int xSize, int ySize, Band band, DoubleGrid2D grid) throws RuntimeException
{
int result = 0;
float [] line = new float[xSize];
for (int currRow = 0; currRow < ySize; currRow++)
{
//result = band.ReadRaster(0, currRow, xSize, 1, line);
if (result != gdalconstConstants.CE_None)
{
throw new RuntimeException("Problem reading raster");
}
for (int currCol = 0; currCol < xSize; currCol++)
{
float f = line[currCol];
grid.set(currCol, currRow, f);
}
}
}
/**
* Ganked from GDAL/swig/java/apps/GDALtest.java
*/
public static void printLastError()
{
System.out.println("Last error: " + gdal.GetLastErrorMsg());
System.out.println("Last error no: " + gdal.GetLastErrorNo());
System.out.println("Last error type: " + gdal.GetLastErrorType());
}
}