/* * Grid2DSquareCellDouble.java * Created on 5 November 2001, 17:00 */ package uk.ac.leeds.ccg.cluster.grids; import uk.ac.leeds.ccg.raster.*; import uk.ac.leeds.ccg.geotools.*; import java.io.*; import java.lang.*; import java.util.*; /** * Last updated on 17 December 01 * @author andyt * @version 1.0 */ public class Grid2DSquareCellDouble extends AbstractGrid2DSquareCellDouble { /** * A double array for storing all the grid values in row major order. */ protected double[] gridArray; /** * A hashtable for storing grid values with their ID as the key. The ID is the * row order position in the grid as an Integer. */ protected Hashtable gridHashtable; /** * For indicating if the grid is stored as a Hashtable or a double[]. */ protected boolean isHashtable = true; /** * Default constructor. */ public Grid2DSquareCellDouble() { this(1,1); } /** * Constructs a grid with nrows rows and ncols columns containing noDataValues. */ public Grid2DSquareCellDouble(int nrows,int ncols) { this(nrows,ncols,0.0d,0.0d,1.0d,Double.NaN); // use defaults } public Grid2DSquareCellDouble(int nrows,int ncols,double xllcorner,double yllcorner,double cellsize,double noDataValue) { this(nrows,ncols,xllcorner,yllcorner,cellsize,noDataValue,true); } public Grid2DSquareCellDouble(int nrows,int ncols,double xllcorner,double yllcorner,double cellsize,double noDataValue,boolean keepGridStatisticsUpToDate) { if (DEBUG>0) {System.out.println("Grid2DSquareCellDouble(nrows("+nrows+"),ncols("+ncols+"),xllcorner("+xllcorner+"),yllcorner("+yllcorner+"),cellsize("+cellsize+"),noDataValue("+noDataValue+"),keepGridStatisticsUpToDate("+keepGridStatisticsUpToDate+")) {");} initNrows(nrows); initNcols(ncols); setXllcorner(xllcorner); setYllcorner(yllcorner); setCellsize(cellsize); initNoDataValue(noDataValue); setGridHashtable(new Hashtable()); AbstractGridStatistics gridStatistics; if (keepGridStatisticsUpToDate) { gridStatistics = new GridStatistics1_0(this); } else { gridStatistics = new GridStatistics1_1(this); } initGridStatistics(gridStatistics); if (DEBUG>1) {System.out.println(toString());} if (DEBUG>0) {System.out.println("}");} } /** * Constructs from an AbstractGrid2DSquareCellDouble */ public Grid2DSquareCellDouble(AbstractGrid2DSquareCellDouble inputGrid) { this(inputGrid,0,0,(inputGrid.getNrows() - 1),(inputGrid.getNcols() - 1)); } public Grid2DSquareCellDouble(AbstractGrid2DSquareCellDouble inputGrid,int startRowIndex,int startColIndex,int endRowIndex,int endColIndex) { AbstractGridStatistics inputGridStatistics = inputGrid.getGridStatistics(); initNrows(endRowIndex - startRowIndex + 1); initNcols(endColIndex - startColIndex + 1); setXllcorner(inputGrid.getXllcorner()); setYllcorner(inputGrid.getYllcorner()); setCellsize(inputGrid.getCellsize()); initNoDataValue(inputGrid.getNoDataValue()); Grid2DSquareCellDouble dummy; if (inputGridStatistics instanceof GridStatistics1_0) { dummy = new Grid2DSquareCellDouble(inputGrid,startRowIndex,startColIndex,endRowIndex,endColIndex,true); } else { dummy = new Grid2DSquareCellDouble(inputGrid,startRowIndex,startColIndex,endRowIndex,endColIndex,false); } initGridStatistics(dummy.getGridStatistics()); boolean isHashtable = dummy.getIsHashtable(); if (isHashtable) { setGridHashtable(dummy.getGridHashtable()); } else { setGridArray(dummy.getGridArray()); } setIsHashtable(isHashtable); //dummy.clear(); } public Grid2DSquareCellDouble(AbstractGrid2DSquareCellDouble inputGrid,int startRowIndex,int startColIndex,int endRowIndex,int endColIndex,boolean keepGridStatisticsUpToDate) { if (DEBUG>0) {System.out.println("Grid2DSquareCellDouble(AbstractGrid2DSquareCellDouble("+inputGrid.toString()+"),startRowIndex("+startRowIndex+"),startColIndex("+startColIndex+"),endRowIndex("+endRowIndex+"),endColIndex("+endColIndex+"),keepGridStatisticsUpToDate("+keepGridStatisticsUpToDate+")) {");} int inputGridNrows = inputGrid.getNrows(); int inputGridNcols = inputGrid.getNcols(); double cellsize = inputGrid.getCellsize(); int outputGridNrows = (endRowIndex - startRowIndex + 1); int outputGridNcols = (endColIndex - startColIndex + 1); double outputGridSparseness; initNrows(outputGridNrows); initNcols(outputGridNcols); setXllcorner(inputGrid.getXllcorner() + (double) startColIndex * cellsize); setYllcorner(inputGrid.getYllcorner() + (double) (endRowIndex - inputGridNrows + 1) * cellsize); setCellsize(cellsize); double noDataValue = inputGrid.getNoDataValue(); initNoDataValue(noDataValue); AbstractGridStatistics inputGridStatistics = inputGrid.getGridStatistics(); AbstractGridStatistics outputGridStatistics; if (keepGridStatisticsUpToDate) { outputGridStatistics = new GridStatistics1_0(this); } else { outputGridStatistics = new GridStatistics1_1(this); } initGridStatistics(outputGridStatistics); double inputGridSparseness = inputGridStatistics.getSparseness(); if (inputGrid instanceof Grid2DSquareCellDouble) { Grid2DSquareCellDouble inGrid = (Grid2DSquareCellDouble) inputGrid; boolean isHashtable = inGrid.getIsHashtable(); if (startRowIndex <= 0 && startColIndex <= 0 && endRowIndex >= (inputGridNrows - 1) && endColIndex >= (inputGridNcols - 1)) { outputGridSparseness = ((inputGridSparseness * inputGridNrows * inputGridNcols) + ((outputGridNrows * outputGridNcols) - (inputGridNrows * inputGridNcols))) / (outputGridNrows * outputGridNcols); outputGridStatistics.updateGridStatisticsFrom(inputGridStatistics); outputGridStatistics.setSparseness(outputGridSparseness); if (isHashtable) { if (startRowIndex == 0 && startColIndex == 0 && endRowIndex == (inputGridNrows - 1) && endColIndex == (inputGridNcols - 1)) { setGridHashtable((Hashtable) inGrid.getGridHashtable().clone()); } else { Hashtable inputGridHashtable = inGrid.getGridHashtable(); int size = inputGridHashtable.size(); Hashtable outputGridHashtable = new Hashtable(size); Enumeration inputKeys = inputGridHashtable.keys(); Enumeration values = inputGridHashtable.elements(); int inGridID; for (int i = 0; i < size; i ++) { inGridID = ((Integer) inputKeys.nextElement()).intValue(); outputGridHashtable.put(new Integer(((inGrid.getRowIndex(inGridID) - startRowIndex) * outputGridNcols) + (inGrid.getColIndex(inGridID) - startColIndex)),values.nextElement()); } setGridHashtable(outputGridHashtable); } } else { if (startRowIndex == 0 && startColIndex == 0 && endRowIndex == (inputGridNrows - 1) && endColIndex == (inputGridNcols - 1)) { setGridArray((double[]) inGrid.getGridArray().clone()); } else { if (outputGridSparseness>0.6d) { inGrid.toHashtable(); Hashtable inputGridHashtable = inGrid.getGridHashtable(); int size = inputGridHashtable.size(); Hashtable outputGridHashtable = new Hashtable(size); Enumeration inputKeys = inputGridHashtable.keys(); Enumeration values = inputGridHashtable.elements(); int inGridID; for (int i = 0; i < size; i ++) { inGridID = ((Integer) inputKeys.nextElement()).intValue(); outputGridHashtable.put(new Integer(((inGrid.getRowIndex(inGridID) - startRowIndex) * outputGridNcols) + (inGrid.getColIndex(inGridID) - startColIndex)),values.nextElement()); } setGridHashtable(outputGridHashtable); } else { double[] inputGridArray = inGrid.getGridArray(); int outputGridArrayLength = outputGridNrows * outputGridNcols; double[] outputGridArray = new double[outputGridArrayLength]; Arrays.fill(outputGridArray,0,outputGridArrayLength,noDataValue); for (int i = 0; i = startRowIndex && inGridRow <= endRowIndex && inGridCol >= startColIndex && inGridCol <= endColIndex) { D1 = (Double) values.nextElement(); d1 = D1.doubleValue(); outputGridSparseness -= cellAsProportionOfOutputGrid; sum += d1; if (d1 == min) {minCount ++;} if (d1 < min) {minCount = 1; min = d1;} if (d1 == max) {maxCount ++;} if (d1 > max) {maxCount = 1; max = d1;} //outputGridHashtable.put(new Integer(((inGridRow - startRowIndex) * outputGridNcols) + (inGridCol - startColIndex)),D1); outputGridHashtable.put(new Integer(((inGridRow - startRowIndex) * outputGridNcols) + (inGridCol - startColIndex)),D1); } else { values.nextElement(); } } setGridHashtable(outputGridHashtable); outputGridStatistics.setSparseness(outputGridSparseness); outputGridStatistics.setSum(sum); outputGridStatistics.setMin(min); outputGridStatistics.setMinCount(minCount); outputGridStatistics.setMax(max); outputGridStatistics.setMaxCount(maxCount); if (outputGridStatistics instanceof GridStatistics1_1) { GridStatistics1_1 outGridStatistics = (GridStatistics1_1) outputGridStatistics; outGridStatistics.setIsUpToDate(true); } if (outputGridSparseness<0.4) { toArray(); } } else { Hashtable outputGridHashtable = new Hashtable(); double d1; for (int i = 0; i < inputGridNrows; i ++) { for (int j = 0; j < inputGridNcols; j ++) { if (i >= startRowIndex && i <= endRowIndex && j >= startColIndex && j <= endColIndex) { d1 = inGrid.getCell(i,j); if (d1 != noDataValue) { outputGridSparseness -= cellAsProportionOfOutputGrid; sum += d1; if (d1 == min) {minCount ++;} if (d1 < min) {minCount = 1; min = d1;} if (d1 == max) {maxCount ++;} if (d1 > max) {maxCount = 1; max = d1;} outputGridHashtable.put(new Integer(((i - startRowIndex) * outputGridNrows) + (j - startColIndex)),new Double(d1)); } } } } outputGridStatistics.setSparseness(outputGridSparseness); outputGridStatistics.setSum(sum); outputGridStatistics.setMin(min); outputGridStatistics.setMinCount(minCount); outputGridStatistics.setMax(max); outputGridStatistics.setMaxCount(maxCount); if (outputGridStatistics instanceof GridStatistics1_1) { GridStatistics1_1 outGridStatistics = (GridStatistics1_1) outputGridStatistics; outGridStatistics.setIsUpToDate(true); } setGridHashtable(outputGridHashtable); if (outputGridSparseness<0.4) { toArray(); } } } } else if (inputGrid instanceof Grid2DSquareCellDoubleFile) { Grid2DSquareCellDoubleFile inGrid = (Grid2DSquareCellDoubleFile) inputGrid; Hashtable outputGridHashtable = new Hashtable(); double d1 = noDataValue; double sparseness = 1.0; double sum = 0.0; double min = Double.POSITIVE_INFINITY; double max = Double.NEGATIVE_INFINITY; double outputGridSize = (double) (outputGridNrows * outputGridNcols); int minCount = 0; int maxCount = 0; int i1 = Math.max(startRowIndex,0); int i2 = Math.min(endRowIndex,(outputGridNrows - 1)); int j1 = Math.max(startColIndex,0); int j2 = Math.min(endColIndex,(outputGridNcols - 1)); int row = i1; int col = i2; for (int i = i1; i <= i2; i ++) { col = i2; for (int j = j1; j <= j2; j ++) { d1 = inGrid.getCell(i,j); if (d1 != noDataValue) { sparseness -= (double) 1.0 / outputGridSize; sum += d1; if (d1 == min) {minCount ++;} if (d1 < min) {minCount = 1; min = d1;} if (d1 == max) {maxCount ++;} if (d1 > max) {maxCount = 1; max = d1;} outputGridHashtable.put(new Double(d1),new Integer((row * outputGridNrows) + col)); } col ++; } row ++; } outputGridStatistics.setSparseness(sparseness); outputGridStatistics.setSum(sum); outputGridStatistics.setMin(min); outputGridStatistics.setMinCount(minCount); outputGridStatistics.setMax(max); outputGridStatistics.setMaxCount(maxCount); if (outputGridStatistics instanceof GridStatistics1_1) { GridStatistics1_1 outGridStatistics = (GridStatistics1_1) outputGridStatistics; outGridStatistics.setIsUpToDate(true); } setGridHashtable(outputGridHashtable); if (sparseness < 0.4) { toArray(); } } if (DEBUG > 1) {System.out.println(toString());} if (DEBUG > 0) {System.out.println("}");} } /** * Constructs from a binary file representation of a grid. * @param input - File containing the binary representation of a grid. * These are assumed to be double values written out in row major order. * @param gr1 - GeoRectangle which specifies the dimensions of the input grid * @param cellsize - the cell size of the constructed grid * @param noDataValue - the noDataValue of the grids. * The constructed grid has endColIndex-startColIndex+1 columns and * endRowIndex-startRowIndex+1 rows. The values in the constructed grid File * are initialized with noDataValue and replaced with coincident cells from * the input grid. */ public Grid2DSquareCellDouble(File gridFile,GeoRectangle gr1,double cellsize,double noDataValue,int startRowIndex,int startColIndex,int endRowIndex,int endColIndex) { this(gridFile,gr1,cellsize,noDataValue,startRowIndex,startColIndex,endRowIndex,endColIndex,true); } public Grid2DSquareCellDouble(File gridFile,GeoRectangle gr1,double cellsize,double noDataValue,int startRowIndex,int startColIndex,int endRowIndex,int endColIndex,boolean keepGridStatisticsUpToDate) { if (DEBUG > 0) {System.out.println("Grid2DSquareCellDouble(gridFile("+gridFile+"),GeoRectangle("+gr1.toString()+"),cellsize("+cellsize+"),noDataValue("+noDataValue+"),startRowIndex("+startRowIndex+"),startColIndex("+startColIndex+"),endRowIndex("+endRowIndex+"),endColIndex("+endColIndex+"),keepGridStatisticsUpToDate("+keepGridStatisticsUpToDate+")) {");} AbstractGridStatistics outputGridStatistics; if (keepGridStatisticsUpToDate) { outputGridStatistics = new GridStatistics1_0(this); } else { outputGridStatistics = new GridStatistics1_1(this); } initGridStatistics(outputGridStatistics); int inputGridNrows = (int) Math.floor(gr1.getHeight() / cellsize); int inputGridNcols = (int) Math.floor(gr1.getWidth() / cellsize); initNrows(endRowIndex - startRowIndex + 1); initNcols(endColIndex - startColIndex + 1); setXllcorner(gr1.getX() + (double) startColIndex * cellsize); setYllcorner(gr1.getY() + ((double) endRowIndex * cellsize) - gr1.getWidth() + cellsize); setCellsize(cellsize); initNoDataValue(noDataValue); try { RandomAccessFile gridRandomAccessFile = new RandomAccessFile(gridFile,"rw"); setGridHashtable(new Hashtable()); try { if (!(startColIndex >= inputGridNcols || endColIndex < 0 || startRowIndex >= inputGridNrows || endRowIndex < 0)) { // Only need do something if there are coincident values. int caseType=0; // There are 16 cases to deal with. if (startColIndex <= 0 && startRowIndex <= 0 && endRowIndex >= (inputGridNrows - 1) && endColIndex >= (inputGridNrows - 1)) {caseType = 1;} if (startColIndex <= 0 && startRowIndex <= 0 && endRowIndex >= (inputGridNrows - 1) && endColIndex < (inputGridNrows - 1)) {caseType = 2;} if (startColIndex <= 0 && startRowIndex <= 0 && endRowIndex < (inputGridNrows - 1) && endColIndex >= (inputGridNrows - 1)) {caseType = 3;} if (startColIndex <= 0 && startRowIndex <= 0 && endRowIndex < (inputGridNrows - 1) && endColIndex < (inputGridNrows - 1)) {caseType = 4;} if (startColIndex > 0 && startRowIndex <= 0 && endRowIndex >= (inputGridNrows - 1) && endColIndex >= (inputGridNrows - 1)) {caseType = 5;} if (startColIndex > 0 && startRowIndex <= 0 && endRowIndex >= (inputGridNrows - 1) && endColIndex < (inputGridNrows - 1)) {caseType = 6;} if (startColIndex > 0 && startRowIndex <= 0 && endRowIndex < (inputGridNrows - 1) && endColIndex >= (inputGridNrows - 1)) {caseType = 7;} if (startColIndex > 0 && startRowIndex <= 0 && endRowIndex < (inputGridNrows - 1) && endColIndex < (inputGridNrows - 1)) {caseType = 8;} if (startColIndex <= 0 && startRowIndex>0 && endRowIndex >= (inputGridNrows - 1) && endColIndex >= (inputGridNrows - 1)) {caseType = 9;} if (startColIndex <= 0 && startRowIndex>0 && endRowIndex >= (inputGridNrows - 1) && endColIndex < (inputGridNrows - 1)) {caseType = 10;} if (startColIndex <= 0 && startRowIndex>0 && endRowIndex < (inputGridNrows - 1) && endColIndex >= (inputGridNrows - 1)) {caseType = 11;} if (startColIndex <= 0 && startRowIndex>0 && endRowIndex < (inputGridNrows - 1) && endColIndex < (inputGridNrows - 1)) {caseType = 12;} if (startColIndex > 0 && startRowIndex>0 && endRowIndex >= (inputGridNrows - 1) && endColIndex >= (inputGridNrows - 1)) {caseType = 13;} if (startColIndex > 0 && startRowIndex>0 && endRowIndex >= (inputGridNrows - 1) && endColIndex < (inputGridNrows - 1)) {caseType = 14;} if (startColIndex > 0 && startRowIndex>0 && endRowIndex < (inputGridNrows - 1) && endColIndex >= (inputGridNrows - 1)) {caseType = 15;} if (startColIndex > 0 && startRowIndex>0 && endRowIndex < (inputGridNrows - 1) && endColIndex < (inputGridNrows - 1)) {caseType = 16;} //System.out.print("caseType "+caseType); switch (caseType) { case 1 : gridRandomAccessFile.seek(0); for (int i = 0; i < inputGridNrows; i ++) { for (int j = 0; j < inputGridNcols; j ++) { initCell((i - startRowIndex),(j - startColIndex),gridRandomAccessFile.readDouble()); } } break; case 2 : for (int i = 0; i < inputGridNrows; i ++) { gridRandomAccessFile.seek((i * inputGridNcols) * 8); for (int j = 0; j <= endColIndex; j ++) { initCell((i - startRowIndex),(j - startColIndex),gridRandomAccessFile.readDouble()); } } break; case 3 : for (int i = 0; i <= endRowIndex; i ++) { gridRandomAccessFile.seek((i * inputGridNcols) * 8); for (int j = 0; j < inputGridNcols; j ++) { initCell((i - startRowIndex),(j - startColIndex),gridRandomAccessFile.readDouble()); } } break; case 4 : for (int i = 0; i <= endRowIndex; i ++) { gridRandomAccessFile.seek((i * inputGridNcols) * 8); for (int j = 0; j <= endColIndex; j ++) { initCell((i - startRowIndex),(j - startColIndex),gridRandomAccessFile.readDouble()); } } break; case 5 : for (int i = 0; i < inputGridNrows; i ++) { gridRandomAccessFile.seek(((i * inputGridNcols) + startColIndex) * 8); for (int j = startColIndex; j < inputGridNcols; j ++) { initCell((i - startRowIndex),(j - startColIndex),gridRandomAccessFile.readDouble()); } } break; case 6 : for (int i = 0; i < inputGridNrows; i ++) { gridRandomAccessFile.seek(((i * inputGridNcols) + startColIndex) * 8); for (int j = startColIndex; j <= endColIndex; j ++) { initCell((i - startRowIndex),(j - startColIndex),gridRandomAccessFile.readDouble()); } } break; case 7 : for (int i = 0; i <= endRowIndex; i ++) { gridRandomAccessFile.seek(((i * inputGridNcols) + startColIndex) * 8); for (int j = startColIndex; j < inputGridNcols; j ++) { initCell((i - startRowIndex),(j - startColIndex),gridRandomAccessFile.readDouble()); } } break; case 8 : for (int i = 0; i <= endRowIndex; i ++) { gridRandomAccessFile.seek(((i * inputGridNcols) + startColIndex) * 8); for (int j = 0; j <= endColIndex; j ++) { initCell((i - startRowIndex),(j - startColIndex),gridRandomAccessFile.readDouble()); } } break; case 9 : for (int i = startRowIndex; i 1) {System.out.println(toString());} if (DEBUG > 0) {System.out.println("}");} } /** * Constructs from an Arcinfo gridascii file. */ public Grid2DSquareCellDouble(File asciiFile) { this(asciiFile,true); } public Grid2DSquareCellDouble(File asciiFile,boolean keepGridStatisticsUpToDate) { if (DEBUG > 0) {System.out.println("Grid2DSquareCellDouble(asciiFile("+asciiFile+"),keepGridStatisticsUpToDate("+keepGridStatisticsUpToDate+")) {");} AbstractGridStatistics outputGridStatistics; if (keepGridStatisticsUpToDate) { outputGridStatistics = new GridStatistics1_0(this); } else { outputGridStatistics = new GridStatistics1_1(this); } initGridStatistics(outputGridStatistics); try { StreamTokenizer st = (new StreamTokenizer(new BufferedReader(new InputStreamReader(new FileInputStream(asciiFile))))); st.wordChars('_','_'); st.parseNumbers(); st.eolIsSignificant(false); st.lowerCaseMode(true); // Read header and set parameters from inputGridasciiFile int type = st.nextToken(); st.nextToken(); int ncols = (int)st.nval; initNcols(ncols); st.nextToken(); st.nextToken(); int nrows = (int)st.nval; initNrows(nrows); st.nextToken(); boolean b1 = true; if (st.sval.equalsIgnoreCase("xllcenter") || st.sval.equalsIgnoreCase("xllcentre")) { b1 = false; } st.nextToken(); double xllcorner = st.nval; st.nextToken(); boolean b2 = true; if (st.sval.equalsIgnoreCase("yllcenter") || st.sval.equalsIgnoreCase("yllcentre")) { b2 = false; } st.nextToken(); double yllcorner = st.nval; st.nextToken(); st.nextToken(); cellsize = st.nval; // Correct for xllcorner and yllcorner if need be. if (!b1) { xllcorner -= (cellsize / 2.0d); } if (!b2) { yllcorner -= (cellsize / 2.0d); } setXllcorner(xllcorner); setYllcorner(yllcorner); // Try to get noDataValue as it's optional. type = st.nextToken(); double noDataValue = Double.NaN; if(type == StreamTokenizer.TT_NUMBER) { // Put it back to be read as data and set noDataValue default. // Warning - If there is no noDataValue and grid values are // non-numeric this will break. st.pushBack(); if (DEBUG > 2) {System.out.println("No noDataValue detected. Using default...");} } else { type = st.nextToken(); noDataValue = st.nval; } initNoDataValue(noDataValue); setGridHashtable(new Hashtable()); // Initialise cell values. double d1 = noDataValue; for (int i = 0; i < nrows; i ++) { for (int j = 0; j < ncols; j ++) { st.nextToken(); d1 = st.nval; type = st.nextToken(); if (type != StreamTokenizer.TT_NUMBER && type != StreamTokenizer.TT_EOF) { // Either an exponent term number or end of file marker or grid // value is non-numeric or something else. This assumes it is an // exponent number of the form 0.1E-5; where, E means times by // ten raised to the power of. st.nextToken(); d1 = d1 * Math.pow(10.0,st.nval); } else { st.pushBack(); } initCell(i,j,d1); } } if (outputGridStatistics.getSparseness()<0.4d) { toArray(); } } catch (java.io.IOException ioe1) { System.out.println(""+ioe1+" in Grid2DSquareCellDouble(asciiFile("+asciiFile+"),keepGridStatisticsUpToDate("+keepGridStatisticsUpToDate+"))"); System.exit(0); } if (DEBUG > 1) {System.out.println(toString());} if (DEBUG > 0) {System.out.println("}");} } /** * Constructs from a uk.ac.leeds.ccg.raster.Raster * This can probably be made faster by cloning the raster data array or * Hashtable, converting sparsenes and other summary stats. * Warning! raster.getMin() may not return the minimum value of the raster * Warning! raster.getMax() may not return the maximum value of the raster */ public Grid2DSquareCellDouble(Raster raster) { this(raster,true); } public Grid2DSquareCellDouble(Raster raster,boolean keepGridStatisticsUpToDate) { if (DEBUG > 0) {System.out.println("Grid2DSquareCellDouble(Raster("+raster.toString()+"),keepGridStatisticsUpToDate("+keepGridStatisticsUpToDate+")) {");} AbstractGridStatistics outputGridStatistics; if (keepGridStatisticsUpToDate) { outputGridStatistics = new GridStatistics1_0(this); } else { outputGridStatistics = new GridStatistics1_1(this); } initGridStatistics(outputGridStatistics); int ncols = raster.getWidth(); int nrows = raster.getHeight(); initNrows(nrows); initNcols(ncols); setXllcorner(raster.getOriginx()); setYllcorner(raster.getOriginy()); setCellsize(raster.getCellSize()); initNoDataValue(raster.getMissingValueCode()); //initNoDataValue(raster.getNoDataValue()); setGridHashtable(new Hashtable()); for (int i = 0; i < nrows; i ++) { for (int j = 0; j < ncols; j ++) { initCell(i,j,raster.getCell(i,j)); } } if (outputGridStatistics.getSparseness() < 0.4d) { toArray(); } if (DEBUG > 1) {System.out.println(toString());} if (DEBUG > 0) {System.out.println("}");} } /** * Basic methods */ /** * Returns the data type */ public int getDataType() {return 0;} /** * Returns Hashtable containing data. */ public Hashtable getGridHashtable() { if (!getIsHashtable()) {toHashtable();} return this.gridHashtable; } /** * Sets gridHashtable. */ public void setGridHashtable(Hashtable gridHashtable) {this.gridHashtable = gridHashtable;} /** * Gets isHashtable */ public boolean getIsHashtable() {return this.isHashtable;} /** * Sets isHashtable */ public void setIsHashtable(boolean isHashtable) {this.isHashtable = isHashtable;} /** * Returns double[] containing data. */ public double[] getGridArray() { if (getIsHashtable()) {toArray();} return this.gridArray; } /** * sets gridArray. */ public void setGridArray(double[] gridArray) {this.gridArray = gridArray;} /** * Returns a description of the grid. */ public String toString() { AbstractGridStatistics gridStatistics=getGridStatistics(); return ("isHashtable("+getIsHashtable()+"),nrows("+getNrows()+"),ncols("+getNcols()+"),xllcorner("+getXllcorner()+"),yllcorner("+getYllcorner()+"),cellsize("+getCellsize()+"),noDataValue("+getNoDataValue()+"),gridStatistics("+gridStatistics.toString()+"))"); } /** * Returns the value at row i, column j or noDataValue. */ public double getCell(int i,int j) { if (DEBUG > 3) {System.out.println("getCell(row("+i+"),col("+j+"))");} if (inGrid(i,j)) { if (getIsHashtable()) { Hashtable gridHashtable = getGridHashtable(); Double d1 = (Double)gridHashtable.get(new Integer(getCellID(i,j))); if (d1 != null) { return d1.doubleValue(); } } else { double[] gridArray = getGridArray(); return gridArray[(i * ncols) + j]; } } if (DEBUG > 3) {System.out.println("}");} return getNoDataValue(); } /** * Sets the value at row i column j to d1. */ public double setCell(int i,int j,double d1) { if (DEBUG > 3) {System.out.println("setCell(row("+i+"),col("+j+"),value("+d1+")) {");} double noDataValue=getNoDataValue(); if (inGrid(i,j)) { AbstractGridStatistics gridStatistics = getGridStatistics(); boolean keepGridStatisticsUpToDate = false; if (gridStatistics instanceof GridStatistics1_0) { keepGridStatisticsUpToDate = true; } gridStatistics.doMin(d1); gridStatistics.doMax(d1); int ncols = getNcols(); int nrows = getNrows(); if (getIsHashtable()) { Double d2; if (d1 != noDataValue) { // This sets the Hashtable key and value and returns the value for the key d2 = (Double)gridHashtable.put(new Integer((i * ncols) + j),new Double(d1)); if (d2 == null) { gridStatistics.setSparseness(gridStatistics.getSparseness() - 1.0d / (double) (nrows * ncols)); if (gridStatistics.getSparseness() < 0.4) {toArray();} if (keepGridStatisticsUpToDate) { gridStatistics.setSum(gridStatistics.getSum() + d1); } return noDataValue; } else { double d2doubleValue = d2.doubleValue(); if (keepGridStatisticsUpToDate) { if (d2doubleValue == gridStatistics.getMin()) {gridStatistics.setMinCount(gridStatistics.getMinCount() - 1);} if (d2doubleValue == gridStatistics.getMax()) {gridStatistics.setMaxCount(gridStatistics.getMaxCount() - 1);} gridStatistics.setSum(gridStatistics.getSum() - d2doubleValue + d1); } if (DEBUG > 3) {System.out.println("}");} return d2doubleValue; } } else { // This removes the Hashtable key and value and returns the value for the key d2 = (Double)gridHashtable.remove(new Integer(getCellID(i,j))); if (d2 != null) { gridStatistics.setSparseness(gridStatistics.getSparseness() + 1.0d / (double) (nrows * ncols)); double d2doubleValue = d2.doubleValue(); if (keepGridStatisticsUpToDate) { if (d2doubleValue == gridStatistics.getMin()) {gridStatistics.setMinCount(gridStatistics.getMinCount() - 1);} if (d2doubleValue == gridStatistics.getMax()) {gridStatistics.setMaxCount(gridStatistics.getMaxCount() - 1);} gridStatistics.setSum(gridStatistics.getSum() - d2doubleValue); } if (DEBUG > 3) {System.out.println("}");} return d2doubleValue; } } } else { double[] gridArray = getGridArray(); double d2 = gridArray[(i * ncols) + j]; if (keepGridStatisticsUpToDate) { if (d2 == gridStatistics.getMin()) {gridStatistics.setMinCount(gridStatistics.getMinCount() - 1);} if (d2 == gridStatistics.getMax()) {gridStatistics.setMaxCount(gridStatistics.getMaxCount() - 1);} } if (d1 == noDataValue) { gridStatistics.setSparseness(gridStatistics.getSparseness() + 1.0d / (double) (nrows * ncols)); } else { if (keepGridStatisticsUpToDate) { gridStatistics.setSum(gridStatistics.getSum() + d1); } } if (d2 == noDataValue) { gridStatistics.setSparseness(gridStatistics.getSparseness() - 1.0d / (double) (nrows * ncols)); } else { if (keepGridStatisticsUpToDate) { gridStatistics.setSum(gridStatistics.getSum() - d2); } } gridArray[(i * ncols) + j] = d1; if (gridStatistics.getSparseness() > 0.6) {toHashtable();} if (DEBUG > 3) {System.out.println("}");} return d2; } } if (DEBUG > 3) {System.out.println("}");} return noDataValue; } /** * Initilises the value at row i column j to d1. */ protected void initCell(int i, int j, double d1) { if (DEBUG > 3) {System.out.println("initCell(row("+i+"),col("+j+"),value("+d1+")) {");} if (inGrid(i,j)) { AbstractGridStatistics gridStatistics = getGridStatistics(); boolean keepGridStatisticsUpToDate = false; if (gridStatistics instanceof GridStatistics1_0) { keepGridStatisticsUpToDate = true; gridStatistics.doMin(d1); gridStatistics.doMax(d1); } int ncols = getNcols(); double noDataValue = getNoDataValue(); if (getIsHashtable()) { if (d1 != noDataValue) { gridStatistics.setSparseness(gridStatistics.getSparseness() - (1.0d / (double) (getNrows() * ncols))); if (keepGridStatisticsUpToDate) { gridStatistics.setSum(gridStatistics.getSum() + d1); } getGridHashtable().put(new Integer((i * ncols) + j),new Double(d1)); } } else { if (d1 != noDataValue) { gridStatistics.setSparseness(gridStatistics.getSparseness() - (1.0d / (double) (getNrows() * ncols))); if (keepGridStatisticsUpToDate) { gridStatistics.setSum(gridStatistics.getSum() + d1); } } double[] gridArray = getGridArray(); gridArray[(i * ncols) + j] = d1; } } if (DEBUG > 3) {System.out.println("}");} } /** * Sets a new value for noDataValue and replaces existing noDataValues with * the numeric value */ public void setNoDataValue(double newNoDataValue) { if (DEBUG > 3) {System.out.println("setNoDataValue(newNoDataValue("+newNoDataValue+")) {");} AbstractGridStatistics gridStatistics = getGridStatistics(); boolean keepGridStatisticsUpToDate = false; if (gridStatistics instanceof GridStatistics1_0) { keepGridStatisticsUpToDate = true; } double noDataValue = getNoDataValue(); if (newNoDataValue != noDataValue) { int ncols = getNcols(); int nrows = getNrows(); double d1 = noDataValue; double cellasProportionOfGrid = 1 / (double) (ncols * nrows); double sparseness = 1.0d; double sum = 0.0d; double min = Double.POSITIVE_INFINITY; int minCount = nrows * ncols; double max = Double.NEGATIVE_INFINITY; int maxCount = minCount; Hashtable hashtable = new Hashtable(); for (int i = 0 ; i < nrows ; i++) { for (int j = 0 ; j < ncols ; j++) { d1 = getCell(i,j); if (d1 == newNoDataValue) { sparseness -= cellasProportionOfGrid; } else { hashtable.put(new Integer((i * ncols) + j),new Double(d1)); if (keepGridStatisticsUpToDate) { sum += d1; if (d1 < min) {min = d1; minCount = 1;} if (d1 == min) {minCount += 1;} if (d1 > max) {max = d1; maxCount = 1;} if (d1 == max) {maxCount += 1;} } } } } initNoDataValue(d1); gridStatistics.setSparseness(sparseness); if (keepGridStatisticsUpToDate) { GridStatistics1_0 gridStats = (GridStatistics1_0) gridStatistics; gridStats.setSum(sum); gridStats.setMinCount(minCount); gridStats.setRecalculateMin(false); gridStats.setMin(min); gridStats.setMaxCount(maxCount); gridStats.setMax(max); gridStats.setRecalculateMax(false); } setIsHashtable(true); setGridHashtable(hashtable); if (sparseness < 0.4) { toArray(); } } if (DEBUG > 3) {System.out.println("}");} } /** * Clears all values from the grid. */ public void clear() { if (DEBUG > 3) {System.out.println("clear() {");} if (getIsHashtable()) { getGridHashtable().clear(); getGridStatistics().setSparseness(1.0d); System.gc(); } else { setGridHashtable(new Hashtable()); setIsHashtable(true); getGridStatistics().setSparseness(1.0d); System.gc(); } if (DEBUG > 3) {System.out.println("}");} } /** * Converters */ /** * Change internal storage from Array to Hashtable */ private void toHashtable() { if (DEBUG > 3) {System.out.println("toHashtable() {");} if (!getIsHashtable()) { int nrows = getNrows(); int ncols = getNcols(); double noDataValue = getNoDataValue(); double d1 = noDataValue; Hashtable gridHashtable = new Hashtable(); double[] gridArray = getGridArray(); for (int i = 0; i < nrows; i ++) { for (int j = 0; j < ncols; j ++) { d1=gridArray[(i * ncols) + j]; if (d1!=noDataValue) { gridHashtable.put(new Integer(getCellID(i,j)),new Double(d1)); } } } setGridHashtable(gridHashtable); setIsHashtable(true); System.gc(); } if (DEBUG > 3) {System.out.println("}");} } /** * Changes internal storage from Hashtable to Array */ private void toArray() { if (DEBUG > 3) {System.out.println("toArray() {");} if (getIsHashtable()) { int nrows = getNrows(); int ncols = getNcols(); double[] gridArray = new double[nrows * ncols]; double noDataValue = getNoDataValue(); Double D1; for (int i = 0; i < nrows; i ++) { for (int j = 0; j < ncols; j ++) { D1 = (Double) gridHashtable.get(new Integer((i * ncols) + j)); if (D1 != null) { gridArray[(i * ncols) + j] = D1.doubleValue(); } else { gridArray[(i * ncols) + j] = noDataValue; } } } setGridArray(gridArray); setIsHashtable(false); System.gc(); } if (DEBUG > 3) {System.out.println("}");} } }