Skip to content
Snippets Groups Projects
Commit 3a26aee6 authored by Peter Alexander's avatar Peter Alexander
Browse files

Support non-square grid cells

parent 58db3a20
No related branches found
No related tags found
No related merge requests found
Showing
with 116 additions and 70 deletions
...@@ -101,8 +101,8 @@ public class ModelConfig { ...@@ -101,8 +101,8 @@ public class ModelConfig {
// Spatial (gridded) data // Spatial (gridded) data
public static final String SPATIAL_DATA_DIR = DATA_DIR; // + File.separator + "tinyTest"; public static final String SPATIAL_DATA_DIR = DATA_DIR; // + File.separator + "tinyTest";
public static final String INITAL_LAND_COVER_DIR = SPATIAL_DATA_DIR + File.separator + "initLandUse"; public static final String INITAL_LAND_COVER_DIR = SPATIAL_DATA_DIR + File.separator + "initLandUse";
public static final String COUNTRY_BOUNDARY_FILE = SPATIAL_DATA_DIR + File.separator + "country_boundaries.asc"; public static final String COUNTRY_BOUNDARY_FILE = SPATIAL_DATA_DIR + File.separator + "country_boundaries_72_96.asc";
public static final String IRRIGATION_COST_FILE = SPATIAL_DATA_DIR + File.separator + "irrigation_cost.asc";; public static final String IRRIGATION_COST_FILE = SPATIAL_DATA_DIR + File.separator + "irrigation_cost_72_96.asc";;
public static final double IRRIG_COST_SCALE_FACTOR = 3.0; public static final double IRRIG_COST_SCALE_FACTOR = 3.0;
......
...@@ -54,7 +54,7 @@ public class ModelMain { ...@@ -54,7 +54,7 @@ public class ModelMain {
/* setup models, reading inputs, etc. */ /* setup models, reading inputs, etc. */
private void setup() { private void setup() {
desiredProjection = new RasterHeaderDetails(720, 360, -180, -90, 0.5, "999"); desiredProjection = new RasterHeaderDetails(96, 72, -180, -90, 3.75, 2.5, "999");
countryToKeysMap = createCountryToKeysMap(); countryToKeysMap = createCountryToKeysMap();
demandManager = new DemandManager(ModelFitType.LOGISTIC, ModelConfig.SSP_SCENARIO); demandManager = new DemandManager(ModelFitType.LOGISTIC, ModelConfig.SSP_SCENARIO);
countryAgents = createCountryAgents(); countryAgents = createCountryAgents();
...@@ -285,6 +285,12 @@ public class ModelMain { ...@@ -285,6 +285,12 @@ public class ModelMain {
LandCoverReader lcReader = new LandCoverReader(initLC, landType); LandCoverReader lcReader = new LandCoverReader(initLC, landType);
initLC = lcReader.getRasterDataFromFile(rootDir + landType.getFileName()); initLC = lcReader.getRasterDataFromFile(rootDir + landType.getFileName());
} }
// scale all fractional areas read in by the actual area
for (Entry<RasterKey, LandCoverItem> entry : initLC.entrySet()) {
double cellArea = initLC.getAreaMha(entry.getKey());
entry.getValue().scaleAll(cellArea);
}
return initLC; return initLC;
} }
...@@ -302,7 +308,7 @@ public class ModelMain { ...@@ -302,7 +308,7 @@ public class ModelMain {
} }
} */ } */
LPJYieldResponseMapReader yieldReader = new LPJYieldResponseMapReader(ModelConfig.YIELD_DIR); LPJYieldResponseMapReader yieldReader = new LPJYieldResponseMapReader(ModelConfig.YIELD_DIR, desiredProjection);
for (FertiliserRate fr : FertiliserRate.values()) { for (FertiliserRate fr : FertiliserRate.values()) {
yieldReader.getRasterDataFromFile(fr); yieldReader.getRasterDataFromFile(fr);
......
...@@ -97,7 +97,7 @@ public class GamsCountryInput { ...@@ -97,7 +97,7 @@ public class GamsCountryInput {
// } // }
public double getMeatEfficiency() { public double getMeatEfficiency() {
return 0.5; // this is already handled by the feed conversion efficiency for each animal product return 1.0; // this is already handled by the feed conversion efficiency for each animal product
} }
public double getLandChangeEnergy() { public double getLandChangeEnergy() {
......
...@@ -47,7 +47,7 @@ public class GamsRasterTest extends GamsLocationTest { ...@@ -47,7 +47,7 @@ public class GamsRasterTest extends GamsLocationTest {
} }
public RasterSet<IrrigationCostItem> getIrrigationCost() { public RasterSet<IrrigationCostItem> getIrrigationCost() {
RasterSet<IrrigationCostItem> testIrrigationCostRaster= new RasterSet<IrrigationCostItem>(); RasterSet<IrrigationCostItem> testIrrigationCostRaster= new RasterSet<IrrigationCostItem>(null);
for (int i = 0; i<X_RANGE; i++) { for (int i = 0; i<X_RANGE; i++) {
for (int j = 0; j<Y_RANGE; j++) { for (int j = 0; j<Y_RANGE; j++) {
...@@ -63,7 +63,7 @@ public class GamsRasterTest extends GamsLocationTest { ...@@ -63,7 +63,7 @@ public class GamsRasterTest extends GamsLocationTest {
public RasterSet<AreasItem> getPreviousAreaRaster() { public RasterSet<AreasItem> getPreviousAreaRaster() {
RasterSet<AreasItem> testAreaRaster= new RasterSet<AreasItem>(); RasterSet<AreasItem> testAreaRaster= new RasterSet<AreasItem>(null);
for (int i = 0; i<X_RANGE; i++) { for (int i = 0; i<X_RANGE; i++) {
for (int j = 0; j<Y_RANGE; j++) { for (int j = 0; j<Y_RANGE; j++) {
......
...@@ -12,7 +12,9 @@ public class IrrigiationCostReader extends AbstractRasterReader<IrrigationCostIt ...@@ -12,7 +12,9 @@ public class IrrigiationCostReader extends AbstractRasterReader<IrrigationCostIt
@Override @Override
public void setData(IrrigationCostItem item, String token) { public void setData(IrrigationCostItem item, String token) {
double irrigCost = Double.parseDouble(token); if (!"nan".equals(token)) {
item.setIrrigCost(irrigCost * ModelConfig.IRRIG_COST_SCALE_FACTOR); double irrigCost = Double.parseDouble(token);
item.setIrrigCost(irrigCost * ModelConfig.IRRIG_COST_SCALE_FACTOR);
}
} }
} }
...@@ -2,6 +2,7 @@ package ac.ed.lurg.landuse; ...@@ -2,6 +2,7 @@ package ac.ed.lurg.landuse;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import ac.ed.lurg.types.LandCoverType; import ac.ed.lurg.types.LandCoverType;
import ac.sac.raster.RasterItem; import ac.sac.raster.RasterItem;
...@@ -20,6 +21,13 @@ public class LandCoverItem implements RasterItem { ...@@ -20,6 +21,13 @@ public class LandCoverItem implements RasterItem {
public void setLandCover(LandCoverType landType, double d) { public void setLandCover(LandCoverType landType, double d) {
landcover.put(landType, d); landcover.put(landType, d);
} }
public void scaleAll(double factor) {
for (Entry<LandCoverType, Double> entry : landcover.entrySet()) {
landcover.put(entry.getKey(), entry.getValue() * factor);
}
}
/*public double getTotal() { /*public double getTotal() {
double total = 0; double total = 0;
......
...@@ -18,7 +18,7 @@ public enum LandCoverType { ...@@ -18,7 +18,7 @@ public enum LandCoverType {
} }
public String getFileName() { public String getFileName() {
return name + ".asc"; return name + "_72_96.asc";
} }
} }
...@@ -16,9 +16,9 @@ public class LPJYieldResponseMapReader { ...@@ -16,9 +16,9 @@ public class LPJYieldResponseMapReader {
private YieldRaster dataset; private YieldRaster dataset;
private String rootDir; private String rootDir;
public LPJYieldResponseMapReader(String rootDir) { public LPJYieldResponseMapReader(String rootDir, RasterHeaderDetails rasterProj) {
this.rootDir = rootDir; this.rootDir = rootDir;
dataset = new YieldRaster(new RasterHeaderDetails(720,360,-180,-90,0.5,"999")); dataset = new YieldRaster(rasterProj);
} }
......
...@@ -10,6 +10,7 @@ import ac.ed.lurg.utils.LogWriter; ...@@ -10,6 +10,7 @@ import ac.ed.lurg.utils.LogWriter;
public abstract class AbstractRasterReader<D extends RasterItem> { public abstract class AbstractRasterReader<D extends RasterItem> {
protected static final boolean DEBUG = false; protected static final boolean DEBUG = false;
private static final int HEADER_LENGTH = 6; private static final int HEADER_LENGTH = 6;
private static final int HEADER_TITLE_COL = 0;
private static final int HEADER_DATA_COL = 1; private static final int HEADER_DATA_COL = 1;
private static final int NCOLUMN_ROW = 0; private static final int NCOLUMN_ROW = 0;
private static final int NROW_ROW = 1; private static final int NROW_ROW = 1;
...@@ -37,7 +38,8 @@ public abstract class AbstractRasterReader<D extends RasterItem> { ...@@ -37,7 +38,8 @@ public abstract class AbstractRasterReader<D extends RasterItem> {
int nrows=0; int nrows=0;
double xllCorner=0.0; double xllCorner=0.0;
double yllCorner = 0.0; double yllCorner = 0.0;
double cellSize = 1000; double xcellSize = 0;
double ycellSize = 0;
String nodataString=null; String nodataString=null;
for (int i=0; i<HEADER_LENGTH; i++) { for (int i=0; i<HEADER_LENGTH; i++) {
...@@ -65,17 +67,26 @@ public abstract class AbstractRasterReader<D extends RasterItem> { ...@@ -65,17 +67,26 @@ public abstract class AbstractRasterReader<D extends RasterItem> {
yllCorner = Double.parseDouble(tokens[HEADER_DATA_COL]); yllCorner = Double.parseDouble(tokens[HEADER_DATA_COL]);
break; break;
case CELL_SIZE: case CELL_SIZE:
cellSize = Double.parseDouble(tokens[HEADER_DATA_COL]); xcellSize = Double.parseDouble(tokens[HEADER_DATA_COL]);
ycellSize = xcellSize;
break; break;
case NODATA_VALUE_ROW: case NODATA_VALUE_ROW:
nodataString = tokens[HEADER_DATA_COL]; // deal with the case of files with x and y cell size is different. There are still 6 rows in the header as the nodata row is missing
if ("dy".equals(tokens[HEADER_TITLE_COL])) {
ycellSize = Double.parseDouble(tokens[HEADER_DATA_COL]);
nodataString = "0";
}
else {
nodataString = tokens[HEADER_DATA_COL];
}
break; break;
} }
} }
if (DEBUG) LogWriter.println("Creating RasterDataset col:"+ncolumns + ", rows:" + nrows); if (DEBUG) LogWriter.println("Creating RasterDataset col:"+ncolumns + ", rows:" + nrows);
RasterHeaderDetails headerDetails = new RasterHeaderDetails(ncolumns, nrows, xllCorner, yllCorner, cellSize, nodataString); RasterHeaderDetails headerDetails = new RasterHeaderDetails(ncolumns, nrows, xllCorner, yllCorner, xcellSize, ycellSize, nodataString);
if (dataset == null) createDataSet(headerDetails); if (dataset == null) createDataSet(headerDetails);
return headerDetails; return headerDetails;
} }
...@@ -96,7 +107,7 @@ public abstract class AbstractRasterReader<D extends RasterItem> { ...@@ -96,7 +107,7 @@ public abstract class AbstractRasterReader<D extends RasterItem> {
String line; String line;
while ((line=in.readLine()) != null) { while ((line=in.readLine()) != null) {
String[] tokens = parseLine(line); String[] tokens = parseLine(line.trim());
for (String token : tokens) { for (String token : tokens) {
......
...@@ -5,24 +5,23 @@ public class RasterHeaderDetails { ...@@ -5,24 +5,23 @@ public class RasterHeaderDetails {
private int nrows; private int nrows;
private double xllCorner; private double xllCorner;
private double yllCorner; private double yllCorner;
private double cellSize; private double xcellSize;
private double ycellSize;
private String nodataString; private String nodataString;
public RasterHeaderDetails(int ncolumns, int nrows, double xllCorner, double yllCorner, double cellSize, String nodataString) { public RasterHeaderDetails(int ncolumns, int nrows, double xllCorner, double yllCorner, double xcellSize, double ycellSize, String nodataString) {
super(); super();
this.ncolumns = ncolumns; this.ncolumns = ncolumns;
this.nrows = nrows; this.nrows = nrows;
this.xllCorner = xllCorner; this.xllCorner = xllCorner;
this.yllCorner = yllCorner; this.yllCorner = yllCorner;
this.cellSize = cellSize; this.xcellSize = xcellSize;
this.ycellSize = ycellSize;
this.nodataString = nodataString; this.nodataString = nodataString;
} }
public RasterHeaderDetails() {
}
public RasterHeaderDetails copy() { public RasterHeaderDetails copy() {
return new RasterHeaderDetails(ncolumns, nrows, xllCorner, yllCorner, cellSize, nodataString); return new RasterHeaderDetails(ncolumns, nrows, xllCorner, yllCorner, xcellSize, ycellSize, nodataString);
} }
public double getOriginX() { public double getOriginX() {
...@@ -30,7 +29,7 @@ public class RasterHeaderDetails { ...@@ -30,7 +29,7 @@ public class RasterHeaderDetails {
} }
public double getOriginY() { public double getOriginY() {
return yllCorner + cellSize * nrows; return yllCorner + ycellSize * nrows;
} }
public void incrementNcolumns() { public void incrementNcolumns() {
...@@ -39,7 +38,7 @@ public class RasterHeaderDetails { ...@@ -39,7 +38,7 @@ public class RasterHeaderDetails {
public void incrementNrows() { public void incrementNrows() {
nrows++; nrows++;
yllCorner = yllCorner - cellSize; yllCorner = yllCorner - ycellSize;
} }
public int getNcolumns() { public int getNcolumns() {
...@@ -58,10 +57,15 @@ public class RasterHeaderDetails { ...@@ -58,10 +57,15 @@ public class RasterHeaderDetails {
return yllCorner; return yllCorner;
} }
public double getCellSize() { public double getXCellSize() {
return cellSize; return xcellSize;
}
public double getYCellSize() {
return ycellSize;
} }
public String getNodataString() { public String getNodataString() {
return nodataString; return nodataString;
} }
...@@ -71,15 +75,17 @@ public class RasterHeaderDetails { ...@@ -71,15 +75,17 @@ public class RasterHeaderDetails {
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
long temp;
temp = Double.doubleToLongBits(cellSize);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + ncolumns; result = prime * result + ncolumns;
result = prime * result result = prime * result
+ ((nodataString == null) ? 0 : nodataString.hashCode()); + ((nodataString == null) ? 0 : nodataString.hashCode());
result = prime * result + nrows; result = prime * result + nrows;
long temp;
temp = Double.doubleToLongBits(xcellSize);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(xllCorner); temp = Double.doubleToLongBits(xllCorner);
result = prime * result + (int) (temp ^ (temp >>> 32)); result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(ycellSize);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(yllCorner); temp = Double.doubleToLongBits(yllCorner);
result = prime * result + (int) (temp ^ (temp >>> 32)); result = prime * result + (int) (temp ^ (temp >>> 32));
return result; return result;
...@@ -94,9 +100,6 @@ public class RasterHeaderDetails { ...@@ -94,9 +100,6 @@ public class RasterHeaderDetails {
if (getClass() != obj.getClass()) if (getClass() != obj.getClass())
return false; return false;
RasterHeaderDetails other = (RasterHeaderDetails) obj; RasterHeaderDetails other = (RasterHeaderDetails) obj;
if (Double.doubleToLongBits(cellSize) != Double
.doubleToLongBits(other.cellSize))
return false;
if (ncolumns != other.ncolumns) if (ncolumns != other.ncolumns)
return false; return false;
if (nodataString == null) { if (nodataString == null) {
...@@ -106,9 +109,15 @@ public class RasterHeaderDetails { ...@@ -106,9 +109,15 @@ public class RasterHeaderDetails {
return false; return false;
if (nrows != other.nrows) if (nrows != other.nrows)
return false; return false;
if (Double.doubleToLongBits(xcellSize) != Double
.doubleToLongBits(other.xcellSize))
return false;
if (Double.doubleToLongBits(xllCorner) != Double if (Double.doubleToLongBits(xllCorner) != Double
.doubleToLongBits(other.xllCorner)) .doubleToLongBits(other.xllCorner))
return false; return false;
if (Double.doubleToLongBits(ycellSize) != Double
.doubleToLongBits(other.ycellSize))
return false;
if (Double.doubleToLongBits(yllCorner) != Double if (Double.doubleToLongBits(yllCorner) != Double
.doubleToLongBits(other.yllCorner)) .doubleToLongBits(other.yllCorner))
return false; return false;
...@@ -121,7 +130,8 @@ public class RasterHeaderDetails { ...@@ -121,7 +130,8 @@ public class RasterHeaderDetails {
", nrows=" + nrows + ", nrows=" + nrows +
", xllCorner=" + xllCorner + ", xllCorner=" + xllCorner +
", yllCorner=" + yllCorner + ", yllCorner=" + yllCorner +
", cellSize" + cellSize + ", xcellSize" + xcellSize +
", ycellSize" + ycellSize +
", nodataString=" + nodataString; ", nodataString=" + nodataString;
} }
......
...@@ -37,20 +37,7 @@ public class RasterKey implements Serializable { ...@@ -37,20 +37,7 @@ public class RasterKey implements Serializable {
double d = Math.sqrt(Math.pow(col - x.col,2) + Math.pow(row - x.row,2)); double d = Math.sqrt(Math.pow(col - x.col,2) + Math.pow(row - x.row,2));
return d; return d;
} }
/** Assuming coordinates refer to global half degree in Mha */
public double getHalfDegreeArea() {
// https://badc.nerc.ac.uk/help/coordinates/cell-surf-area.html
double cellArea = Math.PI / 360.0 * (Math.sin(getLatInRadians(row)) - Math.sin(getLatInRadians(row+1))) * 6371.0 * 6371.0 / 10000.0;
return cellArea;
}
private static double getLatInRadians(double rowNum) {
double latDegrees = 90.0 - rowNum / 2;
double latRadian = latDegrees * Math.PI / 180.0;
return latRadian;
}
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
......
...@@ -19,6 +19,7 @@ import java.io.IOException; ...@@ -19,6 +19,7 @@ import java.io.IOException;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import ac.ed.lurg.ModelConfig; import ac.ed.lurg.ModelConfig;
import ac.ed.lurg.utils.LogWriter;
public abstract class RasterOutputer<D extends RasterItem> { public abstract class RasterOutputer<D extends RasterItem> {
protected RasterSet<D> results; protected RasterSet<D> results;
...@@ -76,6 +77,9 @@ public abstract class RasterOutputer<D extends RasterItem> { ...@@ -76,6 +77,9 @@ public abstract class RasterOutputer<D extends RasterItem> {
} }
private void writeHeader(BufferedWriter outputFile) throws IOException { private void writeHeader(BufferedWriter outputFile) throws IOException {
if (results.getHeaderDetails().getXCellSize() != results.getHeaderDetails().getYCellSize())
LogWriter.printlnError("Headers x and y cell sizes differ");
outputFile.write("ncols " + results.getNcolumns()); outputFile.write("ncols " + results.getNcolumns());
outputFile.newLine(); outputFile.newLine();
outputFile.write("nrows " + + results.getNrows()); outputFile.write("nrows " + + results.getNrows());
...@@ -84,7 +88,7 @@ public abstract class RasterOutputer<D extends RasterItem> { ...@@ -84,7 +88,7 @@ public abstract class RasterOutputer<D extends RasterItem> {
outputFile.newLine(); outputFile.newLine();
outputFile.write("yllcorner " + results.getHeaderDetails().getYllCorner()); outputFile.write("yllcorner " + results.getHeaderDetails().getYllCorner());
outputFile.newLine(); outputFile.newLine();
outputFile.write("cellsize " + results.getHeaderDetails().getCellSize()); outputFile.write("cellsize " + results.getHeaderDetails().getXCellSize());
outputFile.newLine(); outputFile.newLine();
outputFile.write("NODATA_value " + results.getHeaderDetails().getNodataString()); outputFile.write("NODATA_value " + results.getHeaderDetails().getNodataString());
outputFile.newLine(); outputFile.newLine();
......
...@@ -13,11 +13,7 @@ public class RasterSet<D extends RasterItem> extends HashMap<RasterKey, D> { ...@@ -13,11 +13,7 @@ public class RasterSet<D extends RasterItem> extends HashMap<RasterKey, D> {
private static final long serialVersionUID = 4180188703734898215L; private static final long serialVersionUID = 4180188703734898215L;
private RasterHeaderDetails header; private RasterHeaderDetails header;
public RasterSet() {
header = new RasterHeaderDetails();
}
public RasterSet(RasterHeaderDetails header) { public RasterSet(RasterHeaderDetails header) {
this.header = header; this.header = header;
} }
...@@ -29,18 +25,19 @@ public class RasterSet<D extends RasterItem> extends HashMap<RasterKey, D> { ...@@ -29,18 +25,19 @@ public class RasterSet<D extends RasterItem> extends HashMap<RasterKey, D> {
int c, r; int c, r;
if (source!=null && !source.equals(header)) { if (source!=null && !source.equals(header)) {
int xOffset = (int) Math.round((source.getXllCorner() - header.getXllCorner())/header.getCellSize()); int xOffset = (int) Math.round((source.getXllCorner() - header.getXllCorner())/header.getXCellSize());
int yOffset = (int) Math.round((-source.getOriginY() + header.getOriginY())/header.getCellSize()); // down from top int yOffset = (int) Math.round((-source.getOriginY() + header.getOriginY())/header.getYCellSize()); // down from top
if (source.getCellSize() % header.getCellSize() != 0) if (source.getXCellSize() % header.getXCellSize() != 0 && source.getYCellSize() % header.getYCellSize() != 0)
throw new RuntimeException("Cell sizes must be the same or souce an integer multiple of destination"); throw new RuntimeException("Cell sizes must be the same or souce an integer multiple of destination");
double cellRatio = source.getCellSize() / header.getCellSize(); double xcellRatio = source.getXCellSize() / header.getXCellSize();
double ycellRatio = source.getYCellSize() / header.getYCellSize();
for (int x = 0; x<cellRatio; x++) {
for (int y = 0; y<cellRatio; y++) { for (int x = 0; x<xcellRatio; x++) {
c = (int)(col*cellRatio) + x + xOffset; for (int y = 0; y<ycellRatio; y++) {
r = (int)(row*cellRatio) + y + yOffset; c = (int)(col*xcellRatio) + x + xOffset;
r = (int)(row*ycellRatio) + y + yOffset;
D d = get(c, r); D d = get(c, r);
if (d != null) if (d != null)
...@@ -59,10 +56,10 @@ public class RasterSet<D extends RasterItem> extends HashMap<RasterKey, D> { ...@@ -59,10 +56,10 @@ public class RasterSet<D extends RasterItem> extends HashMap<RasterKey, D> {
/** Method to get raster item for coordinates */ /** Method to get raster item for coordinates */
public D getFromCoordinates(double source_x, double source_y) { public D getFromCoordinates(double source_x, double source_y) {
int col = (int) Math.round((source_x - header.getXllCorner())/header.getCellSize()); int col = (int) Math.round((source_x - header.getXllCorner())/header.getXCellSize());
// header.getNrows() - 1, lower left basis. Minus 1 as nrows is number, but indexed from zero // header.getNrows() - 1, lower left basis. Minus 1 as nrows is number, but indexed from zero
int row = header.getNrows() - 1 - (int) Math.round((source_y - header.getYllCorner())/header.getCellSize()); int row = header.getNrows() - 1 - (int) Math.round((source_y - header.getYllCorner())/header.getYCellSize());
if (row < 0 || col < 0) { if (row < 0 || col < 0) {
LogWriter.println("Got negative values"); LogWriter.println("Got negative values");
...@@ -71,12 +68,17 @@ public class RasterSet<D extends RasterItem> extends HashMap<RasterKey, D> { ...@@ -71,12 +68,17 @@ public class RasterSet<D extends RasterItem> extends HashMap<RasterKey, D> {
} }
public double getXCoordin(RasterKey key) { public double getXCoordin(RasterKey key) {
double x = header.getCellSize() * key.getCol() + header.getXllCorner(); double x = header.getXCellSize() * key.getCol() + header.getXllCorner();
return x; return x;
} }
public double getYCoordin(RasterKey key) { public double getYCoordin(RasterKey key) {
double y = header.getCellSize() * (header.getNrows() - 1 - key.getRow()) + header.getYllCorner(); double y = getYCoordin(key.getRow());
return y;
}
private double getYCoordin(int row) {
double y = header.getYCellSize() * (header.getNrows() - 1 - row) + header.getYllCorner();
return y; return y;
} }
...@@ -98,6 +100,22 @@ public class RasterSet<D extends RasterItem> extends HashMap<RasterKey, D> { ...@@ -98,6 +100,22 @@ public class RasterSet<D extends RasterItem> extends HashMap<RasterKey, D> {
return data; return data;
} }
// Assuming coordinates refer to global half degree in Mha
public double getAreaMha(RasterKey key) {
// https://badc.nerc.ac.uk/help/coordinates/cell-surf-area.html
// http://mathforum.org/library/drmath/view/63767.html
int aRow = key.getRow();
double a = Math.sin(getRadiansFromDeg(getYCoordin(aRow)));
double b = Math.sin(getRadiansFromDeg(getYCoordin(aRow+1)));
double cellArea = header.getXCellSize() * Math.PI / 180.0 * (a-b) * 6371.0 * 6371.0 / 10000.0;
return cellArea;
}
private static double getRadiansFromDeg(double deg) {
double latRadian = deg * Math.PI / 180.0;
return latRadian;
}
/** Some classes do not create, those that do will need to override */ /** Some classes do not create, those that do will need to override */
protected D createRasterData() { protected D createRasterData() {
...@@ -119,7 +137,7 @@ public class RasterSet<D extends RasterItem> extends HashMap<RasterKey, D> { ...@@ -119,7 +137,7 @@ public class RasterSet<D extends RasterItem> extends HashMap<RasterKey, D> {
/** Check passed in header is consistent with one from this set. /** Check passed in header is consistent with one from this set.
* Actually only checks grid size as can shift rasters*/ * Actually only checks grid size as can shift rasters*/
public boolean isConstistentWithHeader(RasterHeaderDetails h) { public boolean isConstistentWithHeader(RasterHeaderDetails h) {
return h.getCellSize() == header.getCellSize(); return h.getXCellSize() == header.getXCellSize() && h.getYCellSize() == header.getYCellSize();
} }
public RasterSet<D> popSubsetForKeys(RasterSet<D> subset, Collection<RasterKey> keys) { public RasterSet<D> popSubsetForKeys(RasterSet<D> subset, Collection<RasterKey> keys) {
......
...@@ -8,7 +8,7 @@ public class RasterSetTest { ...@@ -8,7 +8,7 @@ public class RasterSetTest {
@Test @Test
public void test() { public void test() {
YieldRaster dataset = new YieldRaster(new RasterHeaderDetails(720,360,-180,-90,0.5,"")); YieldRaster dataset = new YieldRaster(new RasterHeaderDetails(720,360,-180,-90,0.5,0.5,""));
double y = dataset.getYCoordin(new RasterKey(0,179)); double y = dataset.getYCoordin(new RasterKey(0,179));
System.out.println("y=" +y); System.out.println("y=" +y);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment