![JAR search and dependency download from the Maven repository](/logo.png)
uk.ac.leeds.ccg.grids.process.Grids_Processor Maven / Gradle / Ivy
/*
* Copyright 2019 Andy Turner, University of Leeds.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package uk.ac.leeds.ccg.grids.process;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.Iterator;
import uk.ac.leeds.ccg.generic.io.Generic_Path;
import uk.ac.leeds.ccg.grids.d2.Grids_2D_ID_int;
import uk.ac.leeds.ccg.grids.d2.Grids_2D_ID_long;
import uk.ac.leeds.ccg.grids.d2.grid.Grids_Dimensions;
import uk.ac.leeds.ccg.grids.d2.grid.d.Grids_GridDouble;
import uk.ac.leeds.ccg.grids.d2.grid.Grids_GridNumber;
import uk.ac.leeds.ccg.grids.d2.grid.d.Grids_GridFactoryDouble;
import uk.ac.leeds.ccg.grids.d2.chunk.d.Grids_ChunkDouble;
import uk.ac.leeds.ccg.grids.d2.chunk.d.Grids_ChunkFactoryDoubleArray;
import uk.ac.leeds.ccg.grids.d2.grid.i.Grids_GridInt;
import uk.ac.leeds.ccg.grids.d2.chunk.i.Grids_ChunkInt;
import uk.ac.leeds.ccg.grids.d2.chunk.i.Grids_ChunkFactoryIntArray;
import uk.ac.leeds.ccg.grids.d2.grid.i.Grids_GridFactoryInt;
import uk.ac.leeds.ccg.grids.core.Grids_Environment;
import uk.ac.leeds.ccg.grids.core.Grids_Object;
import uk.ac.leeds.ccg.grids.d2.grid.b.Grids_GridFactoryBoolean;
import uk.ac.leeds.ccg.grids.d2.chunk.d.Grids_ChunkFactoryDoubleSinglet;
import uk.ac.leeds.ccg.grids.d2.chunk.i.Grids_ChunkFactoryIntSinglet;
import uk.ac.leeds.ccg.grids.d2.grid.b.Grids_GridFactoryBinary;
import uk.ac.leeds.ccg.grids.d2.stats.Grids_StatsNumber;
import uk.ac.leeds.ccg.grids.io.Grids_ESRIAsciiGridExporter;
import uk.ac.leeds.ccg.grids.io.Grids_Files;
import uk.ac.leeds.ccg.grids.io.Grids_ImageExporter;
import uk.ac.leeds.ccg.generic.io.Generic_FileStore;
import uk.ac.leeds.ccg.grids.d2.chunk.b.Grids_ChunkFactoryBinaryArray;
import uk.ac.leeds.ccg.grids.d2.chunk.b.Grids_ChunkFactoryBooleanArray;
import uk.ac.leeds.ccg.grids.d2.chunk.bd.Grids_ChunkFactoryBDArray;
import uk.ac.leeds.ccg.grids.d2.chunk.bd.Grids_ChunkFactoryBDSinglet;
import uk.ac.leeds.ccg.grids.d2.grid.bd.Grids_GridFactoryBD;
/**
* General methods for processing individual or multiple grids.
*
* @author Andy Turner
* @version 1.0.0
*/
public class Grids_Processor extends Grids_Object {
private static final long serialVersionUID = 1L;
/**
* For storing the start time of the processing.
*/
public final long startTime;
/**
* For convenience.
*/
protected Grids_Files files;
/**
* Grids_GridFactoryBoolean
*/
public Grids_GridFactoryBoolean gridFactoryBoolean;
/**
* Grids_GridFactoryBoolean
*/
public Grids_GridFactoryBinary gridFactoryBinary;
/**
* Grids_GridFactoryInt
*/
public Grids_GridFactoryInt gridFactoryInt;
/**
* Grids_GridFactoryDouble
*/
public Grids_GridFactoryDouble gridFactoryDouble;
/**
* Grids_GridFactoryBD
*/
public Grids_GridFactoryBD gridFactoryBD;
/**
* @param e The grids environment.
* @throws java.lang.Exception If encountered.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
public Grids_Processor(Grids_Environment e) throws Exception, IOException,
ClassNotFoundException {
super(e);
startTime = System.currentTimeMillis();
files = e.files;
int chunkNRows = 512;
int chunkNCols = 512;
initFactoriesAndFileStores(chunkNRows, chunkNCols);
}
/**
* Initialises factories and file stores.
*/
private void initFactoriesAndFileStores(int chunkNRows, int chunkNCols)
throws Exception {
// Boolean
Path dir = Paths.get(files.getGeneratedGridBooleanDir().toString());
Generic_FileStore fs = Generic_FileStore.getFileStore(dir);
gridFactoryBoolean = new Grids_GridFactoryBoolean(env, fs,
new Grids_ChunkFactoryBooleanArray(), chunkNRows, chunkNCols);
// Binary
dir = Paths.get(files.getGeneratedGridBinaryDir().toString());
fs = Generic_FileStore.getFileStore(dir);
gridFactoryBinary = new Grids_GridFactoryBinary(env, fs,
new Grids_ChunkFactoryBinaryArray(), chunkNRows, chunkNCols);
// Int
dir = Paths.get(files.getGeneratedGridIntDir().toString());
fs = Generic_FileStore.getFileStore(dir);
gridFactoryInt = new Grids_GridFactoryInt(env, fs,
new Grids_ChunkFactoryIntSinglet(Integer.MIN_VALUE),
new Grids_ChunkFactoryIntArray(),
chunkNRows, chunkNCols);
// Double
dir = Paths.get(files.getGeneratedGridDoubleDir().toString());
fs = Generic_FileStore.getFileStore(dir);
gridFactoryDouble = new Grids_GridFactoryDouble(env, fs,
new Grids_ChunkFactoryDoubleSinglet(-Double.MAX_VALUE),
new Grids_ChunkFactoryDoubleArray(),
chunkNRows, chunkNCols);
// BigDecimal
dir = Paths.get(files.getGeneratedGridBigDecimalDir().toString());
fs = Generic_FileStore.getFileStore(dir);
gridFactoryBD = new Grids_GridFactoryBD(env, fs,
new Grids_ChunkFactoryBDSinglet(BigDecimal.valueOf(-Double.MAX_VALUE)),
new Grids_ChunkFactoryBDArray(),
chunkNRows, chunkNCols);
}
protected Generic_FileStore getStore(Path dir, String s) throws IOException,
Exception {
Generic_FileStore r;
if (Files.exists(dir)) {
r = new Generic_FileStore(dir);
} else {
r = new Generic_FileStore(files.getGeneratedDir(), s);
}
return r;
}
/**
* @return {@link #startTime}
*/
public long getTime0() {
return startTime;
}
/**
* Modifies grid by setting to grid.noDataValue those cells coincident with
* mask.noDataValue cells. Warning!!! The grid and mask are assumed to be
* coincident have the same origin and the same chunk structure. @TODO add
* flexibility so the mask can have a different chunk structure to g.
*
* @param g The Grids_GridNumber that the mask will be applied to.
* @param mask The Grids_GridNumber to use as a mask.
* @throws java.lang.Exception If encountered.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
public void mask(Grids_GridNumber g, Grids_GridNumber mask)
throws IOException, ClassNotFoundException, Exception {
env.checkAndMaybeFreeMemory();
if (g instanceof Grids_GridInt) {
Grids_GridInt grid = (Grids_GridInt) g;
int noDataValue = grid.getNoDataValue();
if (mask instanceof Grids_GridInt) {
Grids_GridInt m = (Grids_GridInt) mask;
int maskNoDataValue = m.getNoDataValue();
Iterator ite = m.iterator().getGridIterator();
while (ite.hasNext()) {
Grids_ChunkInt maskIntChunk = m.getChunk(ite.next());
Grids_2D_ID_int i = maskIntChunk.getId();
env.addToNotToClear(g, i);
env.addToNotToClear(mask, i);
env.checkAndMaybeFreeMemory();
int cnr = m.getChunkNRows(i);
int cnc = m.getChunkNCols(i);
int cr = i.getRow();
int cc = i.getCol();
for (int ccr = 0; ccr < cnr; ccr++) {
for (int ccc = 0; ccc < cnc; ccc++) {
int v = maskIntChunk.getCell(ccr, ccc);
if (v == maskNoDataValue) {
long r = ((long) cr * (long) cnr) + (long) ccr;
long c = ((long) cc * (long) cnc) + (long) ccc;
grid.setCell(r, c, noDataValue);
}
}
}
env.removeFromNotToClear(g, i);
env.removeFromNotToClear(mask, i);
}
} else {
// ( mask.getClass() == Grids_GridDouble.class )
Grids_GridDouble m = (Grids_GridDouble) mask;
double maskNoDataValue = m.getNoDataValue();
Iterator ite = m.iterator().getGridIterator();
while (ite.hasNext()) {
Grids_ChunkDouble maskChunk = m.getChunk(ite.next());
Grids_2D_ID_int i = maskChunk.getId();
env.addToNotToClear(g, i);
env.addToNotToClear(mask, i);
env.checkAndMaybeFreeMemory();
int cnr = m.getChunkNRows(i);
int cnc = m.getChunkNCols(i);
int cr = i.getRow();
int cc = i.getCol();
for (int ccr = 0; ccr < cnr; ccr++) {
for (int ccc = 0; ccc < cnc; ccc++) {
double v = maskChunk.getCell(ccr, ccc);
if (v == maskNoDataValue) {
long r = ((long) cr * (long) cnr) + (long) ccr;
long c = ((long) cc * (long) cnc) + (long) ccc;
grid.setCell(r, c, noDataValue);
}
}
}
env.removeFromNotToClear(g, i);
env.removeFromNotToClear(mask, i);
}
}
} else {
Grids_GridDouble grid = (Grids_GridDouble) g;
double resultNoDataValue = grid.getNoDataValue();
if (mask.getClass() == Grids_GridInt.class) {
Grids_GridInt maskInt = (Grids_GridInt) mask;
int maskNoDataValue = maskInt.getNoDataValue();
Iterator ite = maskInt.iterator().getGridIterator();
while (ite.hasNext()) {
Grids_ChunkInt maskChunk = maskInt.getChunk(ite.next());
Grids_2D_ID_int i = maskChunk.getId();
env.addToNotToClear(g, i);
env.addToNotToClear(mask, i);
env.checkAndMaybeFreeMemory();
int cnr = maskInt.getChunkNRows(i);
int cnc = maskInt.getChunkNCols(i);
int cr = i.getRow();
int cc = i.getCol();
for (int ccr = 0; ccr < cnr; ccr++) {
for (int ccc = 0; ccc < cnc; ccc++) {
int v = maskChunk.getCell(ccr, ccc);
if (v == maskNoDataValue) {
long r = ((long) cr * (long) cnr) + (long) ccr;
long c = ((long) cc * (long) cnc) + (long) ccc;
grid.setCell(r, c, resultNoDataValue);
}
}
}
env.removeFromNotToClear(g, i);
env.removeFromNotToClear(mask, i);
}
} else {
// ( mask.getClass() == Grids_GridDouble.class )
Grids_GridDouble maskDouble = (Grids_GridDouble) mask;
double maskNoDataValue = maskDouble.getNoDataValue();
Iterator ite = maskDouble.getChunkIDs().iterator();
Grids_ChunkDouble maskChunk;
while (ite.hasNext()) {
maskChunk = (Grids_ChunkDouble) mask.getChunk(ite.next());
Grids_2D_ID_int i = maskChunk.getId();
env.addToNotToClear(g, i);
env.addToNotToClear(mask, i);
env.checkAndMaybeFreeMemory();
int cnr = maskDouble.getChunkNRows(i);
int cnc = maskDouble.getChunkNCols(i);
int cr = i.getRow();
int cc = i.getCol();
for (int ccr = 0; ccr < cnr; ccr++) {
for (int ccc = 0; ccc < cnc; ccc++) {
double value = maskChunk.getCell(ccr, ccc);
if (value == maskNoDataValue) {
long r = ((long) cr * (long) cnr) + (long) ccr;
long c = ((long) cc * (long) cnc) + (long) ccc;
grid.setCell(r, c, resultNoDataValue);
}
}
}
env.removeFromNotToClear(g, i);
env.removeFromNotToClear(mask, i);
}
}
}
env.checkAndMaybeFreeMemory();
}
/**
* Modifies grid {@code g} by setting all cells with values in the range
* [min,max] to it's noDataValue.
*
* @param g The grid to be masked.
* @param min The minimum value in the range.
* @param max The maximum value in the range.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
public void mask(Grids_GridNumber g, BigDecimal min, BigDecimal max)
throws IOException, ClassNotFoundException, Exception {
env.checkAndMaybeFreeMemory();
if (g.getClass() == Grids_GridInt.class) {
Grids_GridInt gi = (Grids_GridInt) g;
int ndv = gi.getNoDataValue();
Iterator ite = gi.iterator().getGridIterator();
while (ite.hasNext()) {
Grids_ChunkInt chunk = gi.getChunk(ite.next());
Grids_2D_ID_int i = chunk.getId();
int cr = i.getRow();
int cc = i.getCol();
env.addToNotToClear(g, i);
env.checkAndMaybeFreeMemory();
int cnr = gi.getChunkNRows(i);
int cnc = gi.getChunkNCols(i);
for (int ccr = 0; ccr < cnr; ccr++) {
for (int ccc = 0; ccc < cnc; ccc++) {
BigDecimal v = gi.getCellBigDecimal(chunk, cr, cc, ccr,
ccc);
if (v.compareTo(min) != -1 && v.compareTo(max) != 1) {
gi.setCell(chunk, ccr, ccc, ndv);
}
}
}
env.removeFromNotToClear(g, i);
}
} else {
// ( grid.getClass() == Grids_GridDouble.class )
Grids_GridDouble gd = (Grids_GridDouble) g;
double ndv = gd.getNoDataValue();
Iterator ite = gd.iterator().getGridIterator();
while (ite.hasNext()) {
Grids_ChunkDouble chunk = gd.getChunk(ite.next());
Grids_2D_ID_int i = chunk.getId();
int cr = i.getRow();
int cc = i.getCol();
env.addToNotToClear(g, i);
env.checkAndMaybeFreeMemory();
int cnr = g.getChunkNRows(i);
int cnc = g.getChunkNCols(i);
for (int ccr = 0; ccr < cnr; ccr++) {
for (int ccc = 0; ccc < cnc; ccc++) {
BigDecimal v = gd.getCellBigDecimal(chunk, cr, cc, ccr,
ccc);
if (v.compareTo(min) != -1 && v.compareTo(max) != 1) {
gd.setCell(chunk, ccr, ccc, ndv);
}
}
}
env.removeFromNotToClear(g, i);
}
}
//grid.setName( grid.getName() + "_mask" );
env.checkAndMaybeFreeMemory();
}
/**
* @param g The grid.
* @return a new Grids_GridDouble Values are either linearly rescaled into
* the range [min,max]. Or some Log rescaling is done
* @param type If type == null then a linear rescale is done. If type ==
* "Log" then a Log rescale is done.
* @param min The minimum value in the rescaled range.
* @param max The maximum value in the rescaled range.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
public Grids_GridDouble rescale(Grids_GridNumber g, String type, double min,
double max) throws IOException, ClassNotFoundException, Exception {
if (g instanceof Grids_GridDouble) {
return rescale((Grids_GridDouble) g, null, 0.0d, 255.0d);
} else {
return rescale((Grids_GridInt) g, null, 0.0d, 255.0d);
}
}
/**
* For rescaling the {@code double} type grid {@code g}. The type of
* rescaling is determined by {@code type}. If {@code type == null} the a
* linear rescaling is done. If {@code type = "log"} a log rescaling is
* done. For any other value of type this will throw an exception.
*
* There are other rescaling implementation that might be useful that are
* not currently implemented.
*
* @param g The grid for rescaling.
* @param type If {@code null} then a linear rescale is done. If
* {@code "log"}, then a log rescale is done.
*
* @param min The minimum value in the rescaled range.
* @param max The maximum value in the rescaled range.
* @return A grid which are the rescaled values of {@code g}.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
protected Grids_GridDouble rescale(Grids_GridDouble g, String type, double min,
double max) throws IOException, ClassNotFoundException, Exception {
env.checkAndMaybeFreeMemory();
int ncc = g.getNChunkCols();
int ncr = g.getNChunkCols();
double ndv = g.getNoDataValue();
double range = max - min;
Grids_StatsNumber stats = g.getStats();
double minGrid = stats.getMin(true).doubleValue();
double maxGrid = stats.getMax(true).doubleValue();
double rangeGrid = maxGrid - minGrid;
Grids_GridDouble r = gridFactoryDouble.create(g, 0, 0, g.getNRows() - 1,
g.getNCols() - 1);
r.setName(g.getName());
System.out.println(r.toString());
/**
* If range of either input or output range is zero return min for all
* non noDataValues.
*/
if (rangeGrid == 0.0d || range == 0.0d) {
/**
* Better to go through chunks rather than rows. Though it does
* assume that the chunk structure of the grid and outputGrid are
* the same.
*/
for (int cr = 0; cr < ncr; cr++) {
for (int cc = 0; cc < ncc; cc++) {
Grids_2D_ID_int i = new Grids_2D_ID_int(cr, cc);
env.addToNotToClear(g, i);
env.addToNotToClear(r, i);
env.checkAndMaybeFreeMemory();
int cnc = g.getChunkNCols(cc);
int cnr = g.getChunkNRows(cr);
Grids_ChunkDouble gc = g.getChunk(i);
Grids_ChunkDouble ogc = r.getChunk(i);
for (int ccr = 0; ccr < cnr; ccr++) {
for (int ccc = 0; ccc < cnc; ccc++) {
double v = gc.getCell(ccr, ccc);
if (v != ndv) {
r.setCell(ogc, ccr, ccc, min);
}
}
}
env.removeFromNotToClear(g, i);
env.removeFromNotToClear(r, i);
env.checkAndMaybeFreeMemory();
}
}
} else {
if (type == null) {
/**
* Better to go through chunks rather than rows. Though it does
* assume that the structure of the grid and outputGrid are the
* same.
*/
for (int cr = 0; cr < ncr; cr++) {
for (int cc = 0; cc < ncc; cc++) {
Grids_2D_ID_int i = new Grids_2D_ID_int(cr, cc);
env.addToNotToClear(g, i);
env.addToNotToClear(r, i);
env.checkAndMaybeFreeMemory();
int cnc = g.getChunkNCols(cc);
int cnr = g.getChunkNRows(cr);
Grids_ChunkDouble gc = g.getChunk(i);
Grids_ChunkDouble ogc = r.getChunk(i);
for (int ccr = 0; ccr < cnr; ccr++) {
for (int ccc = 0; ccc < cnc; ccc++) {
double v = gc.getCell(ccr, ccc);
if (v != ndv) {
v = (((v - minGrid) / rangeGrid)
* range) + min;
r.setCell(ogc, ccr, ccc, v);
}
}
}
env.removeFromNotToClear(g, i);
env.removeFromNotToClear(r, i);
env.checkAndMaybeFreeMemory();
}
}
r.setName(g.getName() + "_linearRescale");
env.checkAndMaybeFreeMemory();
} else if (type.equalsIgnoreCase("log")) {
r = rescale(r, null, 1.0d, 1000000.0d);
for (int cr = 0; cr < ncr; cr++) {
for (int cc = 0; cc < ncc; cc++) {
Grids_2D_ID_int i = new Grids_2D_ID_int(cr, cc);
env.addToNotToClear(g, i);
env.addToNotToClear(r, i);
env.checkAndMaybeFreeMemory();
int cnc = g.getChunkNCols(cc);
int cnr = g.getChunkNRows(cr);
Grids_ChunkDouble gc = g.getChunk(i);
Grids_ChunkDouble ogc = r.getChunk(i);
for (int ccr = 0; ccr < cnr; ccr++) {
for (int ccc = 0; ccc < cnc; ccc++) {
double v = gc.getCell(ccr, ccc);
if (v != ndv) {
r.setCell(ogc, ccr, ccc, Math.log(v));
}
}
}
}
}
r = rescale(r, null, min, max);
//grid.setName( grid.getName() + "_logRescale" );
env.checkAndMaybeFreeMemory();
} else {
throw new Exception("Type " + type + "not recognised.");
}
}
return r;
}
/**
* For rescaling the {@code int} type grid {@code g}. The type of rescaling
* is determined by {@code type}. If {@code type == null} the a linear
* rescaling is done. If {@code type = "log"} a log rescaling is done. For
* any other value of type this will throw an exception.
*
* There are other rescaling implementation that might be useful that are
* not currently implemented.
*
* @param g The grid for rescaling.
* @param type If {@code null} then a linear rescale is done. If
* {@code "log"}, then a log rescale is done.
*
* @param min The minimum value in the rescaled range.
* @param max The maximum value in the rescaled range.
* @return A grid which are the rescaled values of {@code g}.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
protected Grids_GridDouble rescale(Grids_GridInt g, String type, double min,
double max) throws IOException, ClassNotFoundException, Exception {
env.checkAndMaybeFreeMemory();
int ncc = g.getNChunkCols();
int ncr = g.getNChunkCols();
int ndv = g.getNoDataValue();
double range = max - min;
Grids_StatsNumber stats = g.getStats();
double minGrid = stats.getMin(true).doubleValue();
double maxGrid = stats.getMax(true).doubleValue();
double rangeGrid = maxGrid - minGrid;
Grids_GridDouble r = gridFactoryDouble.create(g, 0, 0, g.getNRows() - 1,
g.getNCols() - 1);
r.setName(g.getName());
System.out.println(r.toString());
/**
* If range of either input or output range is zero return min for all
* non noDataValues.
*/
if (rangeGrid == 0.0d || range == 0.0d) {
/**
* Better to go through chunks rather than rows. Though it does
* assume that the chunk structure of the grid and outputGrid are
* the same.
*/
for (int cr = 0; cr < ncr; cr++) {
for (int cc = 0; cc < ncc; cc++) {
Grids_2D_ID_int i = new Grids_2D_ID_int(cr, cc);
env.addToNotToClear(g, i);
env.addToNotToClear(r, i);
env.checkAndMaybeFreeMemory();
int cnc = g.getChunkNCols(cc);
int cnr = g.getChunkNRows(cr);
Grids_ChunkInt gc = g.getChunk(i);
Grids_ChunkDouble ogc = r.getChunk(i);
for (int ccr = 0; ccr < cnr; ccr++) {
for (int ccc = 0; ccc < cnc; ccc++) {
double v = gc.getCell(ccr, ccc);
if (v != ndv) {
r.setCell(ogc, ccr, ccc, min);
}
}
}
env.removeFromNotToClear(g, i);
env.removeFromNotToClear(r, i);
env.checkAndMaybeFreeMemory();
}
}
} else {
if (type == null) {
/**
* Better to go through chunks rather than rows. Though it does
* assume that the structure of the grid and outputGrid are the
* same.
*/
for (int cr = 0; cr < ncr; cr++) {
for (int cc = 0; cc < ncc; cc++) {
Grids_2D_ID_int i = new Grids_2D_ID_int(cr, cc);
env.addToNotToClear(g, i);
env.addToNotToClear(r, i);
env.checkAndMaybeFreeMemory();
int cnc = g.getChunkNCols(cc);
int cnr = g.getChunkNRows(cr);
Grids_ChunkInt gc = g.getChunk(i);
Grids_ChunkDouble ogc = r.getChunk(i);
for (int ccr = 0; ccr < cnr; ccr++) {
for (int ccc = 0; ccc < cnc; ccc++) {
double v = gc.getCell(ccr, ccc);
if (v != ndv) {
v = (((v - minGrid) / rangeGrid)
* range) + min;
r.setCell(ogc, ccr, ccc, v);
}
}
}
env.removeFromNotToClear(g, i);
env.removeFromNotToClear(r, i);
env.checkAndMaybeFreeMemory();
}
}
r.setName(g.getName() + "_linearRescale");
env.checkAndMaybeFreeMemory();
} else if (type.equalsIgnoreCase("log")) {
r = rescale(r, null, 1.0d, 1000000.0d);
for (int cr = 0; cr < ncr; cr++) {
for (int cc = 0; cc < ncc; cc++) {
Grids_2D_ID_int i = new Grids_2D_ID_int(cr, cc);
env.addToNotToClear(g, i);
env.addToNotToClear(r, i);
env.checkAndMaybeFreeMemory();
int cnc = g.getChunkNCols(cc);
int cnr = g.getChunkNRows(cr);
Grids_ChunkInt gc = g.getChunk(i);
Grids_ChunkDouble ogc = r.getChunk(i);
for (int ccr = 0; ccr < cnr; ccr++) {
for (int ccc = 0; ccc < cnc; ccc++) {
double v = gc.getCell(ccr, ccc);
if (v != ndv) {
r.setCell(ogc, ccr, ccc, Math.log(v));
}
}
}
}
}
r = rescale(r, null, min, max);
//grid.setName( grid.getName() + "_logRescale" );
env.checkAndMaybeFreeMemory();
} else {
throw new Exception("Type " + type + "not recognised.");
}
}
return r;
}
/**
* Modifies grid so value of cells with CellIDs in cellIDs are set to a
* value a little bit larger.
*
* @param g The Grids_GridDouble to be processed.
* @param cellIDs The CellIDs of the cells to be processed.
* @throws java.lang.Exception If encountered.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
public void setLarger(Grids_GridDouble g, HashSet cellIDs)
throws IOException, ClassNotFoundException, Exception {
double ndv = g.getNoDataValue();
Iterator ite = cellIDs.iterator();
while (ite.hasNext()) {
Grids_2D_ID_long cellID = ite.next();
double v = g.getCell(cellID.getRow(), cellID.getCol());
if (v != ndv) {
g.setCell(cellID.getRow(), cellID.getCol(), Math.nextUp(v));
}
}
}
/**
* Modifies grid so value of cells with CellIDs in _CellIDs are set to a
* value a little bit smaller.
*
* @param g The Grids_GridDouble to be processed.
* @param cellIDs The CellIDs of the cells to be processed.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
public void setSmaller(Grids_GridDouble g, HashSet cellIDs)
throws IOException, ClassNotFoundException, Exception {
double ndv = g.getNoDataValue();
Iterator ite = cellIDs.iterator();
while (ite.hasNext()) {
Grids_2D_ID_long cellID = ite.next();
double v = g.getCell(cellID.getRow(), cellID.getCol());
if (v != ndv) {
g.setCell(cellID.getRow(), cellID.getCol(), Math.nextDown(v));
}
}
}
/**
* Adds value to grid for cells with cell ID in cellIDs.
*
* @param g The grid to be processed.
* @param cellIDs The cell IDs.
* @param v The value to be added.
* @throws java.lang.Exception If encountered.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
public void addToGrid(Grids_GridNumber g, HashSet cellIDs,
BigDecimal v) throws IOException, ClassNotFoundException,
Exception {
env.checkAndMaybeFreeMemory();
Iterator ite = cellIDs.iterator();
while (ite.hasNext()) {
g.addToCell(ite.next(), v);
env.checkAndMaybeFreeMemory();
}
}
/**
* Adds value {@code v} to every cell of grid {@code g}.
*
* @param g The grid which is to have value {@code v} added.
* @param v The value to be added
* @throws java.lang.Exception If encountered.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
public void addToGrid(Grids_GridNumber g, BigDecimal v) throws IOException,
ClassNotFoundException, Exception {
env.checkAndMaybeFreeMemory();
int ncr = g.getNChunkRows();
int ncc = g.getNChunkCols();
for (int cr = 0; cr < ncr; cr++) {
for (int cc = 0; cc < ncc; cc++) {
env.checkAndMaybeFreeMemory();
int cnr = g.getChunkNRows(cr);
int cnc = g.getChunkNCols(cc);
for (int ccr = 0; ccr < cnr; ccr++) {
for (int ccc = 0; ccc < cnc; ccc++) {
g.addToCell(cr, cc, ccr, ccc, v);
}
}
}
}
env.checkAndMaybeFreeMemory();
}
/**
* Adds value to grid for cells with CellID in _CellIDs
*
* @param g The Grids_GridDouble to be processed
* @param cellIDs Array of CellIDs.
* @param value The value to be added.
* @throws java.lang.Exception If encountered.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
public void addToGrid(Grids_GridNumber g, Grids_2D_ID_long[] cellIDs,
BigDecimal value) throws IOException, ClassNotFoundException,
Exception {
env.checkAndMaybeFreeMemory();
for (Grids_2D_ID_long cellID : cellIDs) {
g.addToCell(cellID.getRow(), cellID.getCol(), value);
}
env.checkAndMaybeFreeMemory();
}
/**
* Add g2 to g with values from g2 multiplied by w.
*
* @param g Grid to be processed/modified.
* @param g2 Grid from which values are added.
* @param w Value g2 values are multiplied by.
* @param dp Decimal place precision for any BigDecimal Arithmetic.
* @param rm Rounding Mode for any BigDecimal Arithmetic.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
public void addToGrid(Grids_GridNumber g, Grids_GridNumber g2, BigDecimal w,
int dp, RoundingMode rm)
throws IOException, ClassNotFoundException, Exception {
env.checkAndMaybeFreeMemory();
if (g2 != null) {
addToGrid(g, g2, 0L, 0L, g2.getNRows() - 1L, g2.getNCols() - 1L, w, dp, rm);
}
}
/**
* Add g2 to g with values from g2 multiplied by w. Only values of g2 with
* row between startRow and endRow, and column between startCol and endCol
* are added.
*
* @param g Grid to be processed.
* @param g2 Grid from which values are added.
* @param startRow Index of the first row from which g2 values are added.
* @param startCol Index of the first column from which g2 values are added.
* @param endRow Index of the final row from which g2 values are added.
* @param endCol Index of the final column from which g2 values are added.
* @param w Value g2 values are multiplied by.
* @param dp Decimal place precision for any BigDecimal Arithmetic.
* @param rm Rounding Mode for any BigDecimal Arithmetic.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
public void addToGrid(Grids_GridNumber g, Grids_GridNumber g2,
long startRow, long startCol, long endRow, long endCol, BigDecimal w,
int dp, RoundingMode rm) throws IOException, ClassNotFoundException,
Exception {
env.checkAndMaybeFreeMemory();
Grids_Dimensions dimensions = g2.getDimensions();
BigDecimal xMin = dimensions.getXMin();
BigDecimal yMin = dimensions.getYMin();
BigDecimal c = dimensions.getCellsize();
BigDecimal[] dc = new BigDecimal[5];
dc[1] = xMin.add(new BigDecimal(startCol).multiply(c));
dc[2] = yMin.add(new BigDecimal(startRow).multiply(c));
dc[3] = xMin.add(new BigDecimal(endCol - startCol + 1L).multiply(c));
dc[4] = yMin.add(new BigDecimal(endRow - startRow + 1L).multiply(c));
addToGrid(g, g2, startRow, startCol, endRow, endCol, dc, w, dp, rm);
env.checkAndMaybeFreeMemory();
}
/**
* Returns a Grids_GridDouble with values of g added with values from g2
* (with row between startRow, endRow and column index between startCol,
* endCol) multiplied by w.
*
* @param g Grid to be modified.
* @param g2 Grid from which values are added.
* @param startRow Index of the first row from which g2 values are added.
* @param startCol Index of the first column from which g2 values are added.
* @param endRow Index of the final row from which g2 values are added.
* @param endCol Index of the final column from which g2 values are added.
* @param dc Dimension constraints: XMin, YMin, XMax, YMax of the region of
* g2 to be added.
* @param w Value g2 values are multiplied by.
* @param dp Decimal place precision for any BigDecimal Arithmetic.
* @param rm Rounding Mode for any BigDecimal Arithmetic.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
public void addToGrid(Grids_GridNumber g, Grids_GridNumber g2,
long startRow, long startCol, long endRow, long endCol,
BigDecimal[] dc, BigDecimal w, int dp, RoundingMode rm)
throws IOException, ClassNotFoundException, Exception {
env.checkAndMaybeFreeMemory();
long nrows = g.getNRows();
long ncols = g.getNCols();
BigDecimal noDataValue = getNoDataValueBigDecimal(g);
Grids_Dimensions gD = g.getDimensions();
BigDecimal g2NoDataValue = getNoDataValueBigDecimal(g);
Grids_Dimensions g2D = g2.getDimensions();
Grids_GridFactoryDouble gf = this.gridFactoryDouble;
// If the region to be added is outside g then return.
if ((dc[1].compareTo(gD.getXMax()) == 1)
|| (dc[3].compareTo(gD.getXMin()) == -1)
|| (dc[2].compareTo(gD.getYMax()) == 1)
|| (dc[4].compareTo(gD.getYMin()) == -1)) {
return;
}
BigDecimal gC = gD.getCellsize();
BigDecimal g2C = g2D.getCellsize();
BigDecimal g2CH = g2D.getHalfCellsize();
if (g2C.compareTo(gC) == -1) {
throw new UnsupportedOperationException();
} else {
// If g2Cellsize is the same as gCellsize g and g2 align
if ((g2C.compareTo(gC) == 0)
&& ((g2D.getXMin().remainder(gC)).compareTo(
(gD.getXMin().remainder(gC))) == 0)
&& ((g2D.getYMin().remainder(gC)).compareTo(
(gD.getYMin().remainder(gC))) == 0)) {
//println( "grids Align!" );
// TODO: Control precision using xBigDecimal and yBigDecimal
// rather than using x and y.
for (long row = startRow; row <= endRow; row++) {
env.checkAndMaybeFreeMemory();
BigDecimal y = g2.getCellY(row);
for (long col = startCol; col <= endCol; col++) {
BigDecimal x = g2.getCellX(col);
BigDecimal v = g2.getCellBigDecimal(row, col);
if (v.compareTo(g2NoDataValue) != 0) {
if (v.compareTo(BigDecimal.ZERO) != 0) {
g.addToCell(x, y, v.multiply(w));
}
}
}
}
return;
} else {
// println("Intersection!!!!");
// Need to intersect
// TODO:
// Clipping gridToAdd might improve matters here.
// Check
Grids_GridDouble tg1;
Grids_GridDouble tg2;
tg1 = gf.create(nrows, ncols, gD);
tg2 = gf.create(nrows, ncols, gD);
BigDecimal[] bounds;
Grids_2D_ID_long i0;
Grids_2D_ID_long i1;
Grids_2D_ID_long i2;
Grids_2D_ID_long i3;
// gCellsize halved
BigDecimal gCH = g.getCellsize().divide(BigDecimal.valueOf(2));
// gCellsize squared
BigDecimal gCS = gC.multiply(gC);
// g2Cellsize squared
BigDecimal g2CS = g2C.multiply(g2C);
// Area proportions
BigDecimal aP1 = (gCS.divide(g2CS, dp, rm));
BigDecimal aP;
for (int r = 0; r < nrows; r++) {
env.checkAndMaybeFreeMemory();
for (int c = 0; c < ncols; c++) {
bounds = g.getCellBounds(gCH, r, c);
//x = g.getCellXDouble(col);
//y = g.getCellYDouble(row);
i0 = g2.getCellID(bounds[0], bounds[3]);
i1 = g2.getCellID(bounds[2], bounds[3]);
i2 = g2.getCellID(bounds[0], bounds[1]);
i3 = g2.getCellID(bounds[2], bounds[1]);
BigDecimal d0 = g2.getCellBigDecimal(i0.getRow(), i0.getCol());
if (i0.equals(i1) && i1.equals(i2)) {
if (d0 != g2NoDataValue) {
tg1.addToCell(r, c, d0.multiply(aP1));
tg2.addToCell(r, c, aP1);
}
} else {
BigDecimal d1 = g2.getCellBigDecimal(i1.getRow(), i1.getCol());
BigDecimal d2 = g2.getCellBigDecimal(i2.getRow(), i2.getCol());
BigDecimal d3 = g2.getCellBigDecimal(i3.getRow(), i3.getCol());
if (!g2.isInGrid(i0.getRow(), i0.getCol())
&& d0 != g2NoDataValue) {
aP = getAP(bounds, g2, i0, i1, i2, gC, g2CS,
g2CH, dp, rm);
tg1.addToCell(r, c, d0.multiply(aP));
tg2.addToCell(r, c, aP);
}
if (!g2.isInGrid(i1) && d1 != g2NoDataValue) {
if (i1.equals(i0)) {
aP = getAP13(bounds, g2, i1, i3, gC, g2CS, g2CH, dp, rm);
tg1.addToCell(r, c, d1.multiply(aP));
tg2.addToCell(r, c, aP);
}
}
if (!g2.isInGrid(i2) && d2 != g2NoDataValue) {
if (!i2.equals(i0)) {
aP = getAP23(bounds, g2, i2, i3, gC, g2CS, g2CH, dp, rm);
tg1.addToCell(r, c, d2.multiply(aP));
tg2.addToCell(r, c, aP);
}
}
if (!g2.isInGrid(i3) && d3 != g2NoDataValue) {
if (i3 != i1 && i3 != i2) {
aP = getAP3(bounds, g2, i3, gC, g2CS, g2CH, dp, rm);
tg1.addToCell(r, c, d3.multiply(aP));
tg2.addToCell(r, c, aP);
}
}
}
}
}
// The values are normalised by dividing the aggregate Grid
// sum by the proportion of cells with grid values.
for (long r = 0; r < nrows; r++) {
env.checkAndMaybeFreeMemory();
for (long c = 0; c < ncols; c++) {
double d0 = tg2.getCell(r, c);
if (!(d0 != 0.0d || d0 != noDataValue.doubleValue())) {
g.addToCell(r, c, w.multiply(BigDecimal
.valueOf(tg1.getCell(r, c) / d0)));
}
}
}
}
}
env.checkAndMaybeFreeMemory();
}
protected BigDecimal getAP(BigDecimal[] bounds, Grids_GridNumber g2,
Grids_2D_ID_long i1, Grids_2D_ID_long i2, Grids_2D_ID_long i3,
BigDecimal gC, BigDecimal g2CS, BigDecimal g2CH, int dp,
RoundingMode rm) {
BigDecimal aP;
if (i1.equals(i2) || i1.equals(i3)) {
if (i1.equals(i2)) {
aP = (((bounds[3]).subtract(g2.getCellY(i1).subtract(g2CH))
.multiply(gC)).divide(g2CS, dp, rm)).abs();
} else {
aP = ((((g2.getCellX(i1).add(g2CH)).subtract((bounds[0])))
.multiply(gC)).divide(g2CS, dp, rm)).abs();
}
} else {
aP = (((bounds[3]).subtract(g2.getCellY(i1).subtract(g2CH)))
.multiply((g2.getCellX(i1).add(g2CH.subtract((bounds[0]))))
.divide(g2CS, dp, rm))).abs();
}
return aP;
}
protected BigDecimal getAP13(BigDecimal[] bounds, Grids_GridNumber g2,
Grids_2D_ID_long i1, Grids_2D_ID_long i3, BigDecimal gC,
BigDecimal g2CS, BigDecimal g2CH, int dp, RoundingMode rm) {
BigDecimal aP;
if (i1.equals(i3)) {
aP = ((((bounds[2]).subtract(g2.getCellX(i1).subtract(g2CH)))
.multiply(gC)).divide(g2CS, dp, rm)).abs();
} else {
aP = (((bounds[3]).subtract(g2.getCellY(i1).subtract(g2CH)))
.multiply((bounds[2]).subtract(g2.getCellX(i1)
.subtract(g2CH))).divide(g2CS, dp, rm)).abs();
}
return aP;
}
protected BigDecimal getAP23(BigDecimal[] bounds, Grids_GridNumber g2,
Grids_2D_ID_long i2, Grids_2D_ID_long i3, BigDecimal gC,
BigDecimal g2CS, BigDecimal g2CH, int dp, RoundingMode rm) {
BigDecimal aP;
if (i2.equals(i3)) {
aP = ((((g2.getCellY(i2).add(g2CH)).subtract((bounds[1])))
.multiply(gC)).divide(g2CS, dp, rm)).abs();
} else {
aP = ((((g2.getCellY(i2).add(g2CH)).subtract((bounds[1])))
.multiply((g2.getCellX(i2).add(g2CH))
.subtract((bounds[0])))).divide(g2CS, dp, rm))
.abs();
}
return aP;
}
protected BigDecimal getAP3(BigDecimal[] bounds, Grids_GridNumber g2,
Grids_2D_ID_long i3, BigDecimal gC, BigDecimal g2CS,
BigDecimal g2CH, int dp, RoundingMode rm) {
return ((((g2.getCellY(i3).add(g2CH)).subtract((bounds[1])))
.multiply((bounds[2]).subtract((g2.getCellX(i3))
.subtract(g2CH)))).divide(g2CS, dp, rm)).abs();
}
/**
* Multiply g0 and g1 and return a new grid.
*
* @param type Determines the type of Grid returned. BigDecimal, double or
* int.
* @param g0 The first grid to multiply.
* @param g1 The second grid to multiply
* @param dp Decimal place precision for any BigDecimal Arithmetic.
* @param rm Rounding Mode for any BigDecimal Arithmetic.
* @return g0 * g1
* @throws java.lang.Exception If encountered.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
public Grids_GridNumber multiply(Number type, Grids_GridNumber g0,
Grids_GridNumber g1, int dp, RoundingMode rm)
throws IOException, ClassNotFoundException, Exception {
env.checkAndMaybeFreeMemory();
Grids_GridNumber r;
long nRows = g0.getNRows();
long nCols = g0.getNCols();
if (type instanceof BigDecimal) {
r = gridFactoryBD.create(g0, 0L, 0L, nRows - 1, nCols - 1);
} else if (type instanceof Double) {
r = gridFactoryDouble.create(g0, 0L, 0L, nRows - 1, nCols - 1);
} else if (type instanceof Integer) {
r = gridFactoryInt.create(g0, 0L, 0L, nRows - 1, nCols - 1);
} else {
throw new Exception("Unknown type!");
}
BigDecimal ndv0 = g0.ndv;
BigDecimal ndv1 = g1.ndv;
int ncr = g0.getNChunkRows();
int ncc = g0.getNChunkCols();
if (g0.isCoincident(g1)) {
if (g0.isSameDimensionsAndChunks(g1)) {
if (g0.isSameDimensionsAndChunks(r)) {
/**
* Grids are coincident and have the same chunks.
*/
for (int cr = 0; cr < ncr; cr++) {
for (int cc = 0; cc < ncc; cc++) {
Grids_2D_ID_int i = new Grids_2D_ID_int(cr, cc);
env.addToNotToClear(g0, i);
env.addToNotToClear(g1, i);
env.addToNotToClear(r, i);
env.checkAndMaybeFreeMemory();
int cnr = g0.getChunkNRows(cr);
int cnc = g0.getChunkNCols(cc);
for (int ccr = 0; ccr < cnr; ccr++) {
for (int ccc = 0; ccc < cnc; ccc++) {
BigDecimal v0 = g0.getCellBigDecimal(cr, cc,
ccr, ccc);
if (v0.compareTo(ndv0) != 0) {
BigDecimal v1 = g1.getCellBigDecimal(cr,
cc, ccr, ccc);
if (v1.compareTo(ndv1) == 0) {
r.setCell(cr, cc, ccr, ccc, ndv0);
} else {
r.setCell(cr, cc, ccr, ccc,
v0.multiply(v1));
}
}
}
}
env.removeFromNotToClear(g0, i);
env.removeFromNotToClear(g1, i);
env.removeFromNotToClear(r, i);
}
}
} else {
/**
* Input grids are coincident and have the same chunks, but
* the result has different chunks.
*/
for (int cr = 0; cr < ncr; cr++) {
int cnr = g0.getChunkNRows(cr);
/**
* Prefer to keep a row of r chunks in memory.
*/
for (int ccr = 0; ccr < cnr; ccr++) {
long row = r.getRow(cr, ccr);
env.addToNotToClear(r, r.getChunkRow(row));
}
for (int cc = 0; cc < ncc; cc++) {
Grids_2D_ID_int i = new Grids_2D_ID_int(cr, cc);
env.addToNotToClear(g0, i);
env.addToNotToClear(g1, i);
env.checkAndMaybeFreeMemory();
int cnc = g0.getChunkNCols(cc);
for (int ccr = 0; ccr < cnr; ccr++) {
long row = r.getRow(cr, ccr);
env.addToNotToClear(r, r.getChunkRow(row));
for (int ccc = 0; ccc < cnc; ccc++) {
BigDecimal v0 = g0.getCellBigDecimal(cr, cc,
ccr, ccc);
if (v0.compareTo(ndv0) != 0) {
BigDecimal v1 = g1.getCellBigDecimal(cr, cc,
ccr, ccc);
if (v1.compareTo(ndv1) != 0) {
r.setCell(row, r.getCol(cc, ccc),
v0.multiply(v1));
}
}
}
}
env.removeFromNotToClear(g0, i);
env.removeFromNotToClear(g1, i);
}
/**
* Allow the row of r chunks to be swapped.
*/
for (int ccr = 0; ccr < cnr; ccr++) {
long row = r.getRow(cr, ccr);
env.removeFromNotToClear(r, r.getChunkRow(row));
}
}
}
return r;
} else {
multiply(g0, g1, r, ncr, ncc, ndv0, ndv1);
return r;
}
} else {
Grids_Dimensions dimg0 = g0.getDimensions();
Grids_Dimensions dimg1 = g1.getDimensions();
BigDecimal cg0 = dimg0.getCellsize();
BigDecimal cg1 = dimg1.getCellsize();
/**
* Deal with all cases.
*/
if (cg0.compareTo(cg1) == 1) {
Grids_GridDouble ag1 = aggregate(g1, "mean", dimg0, dp, rm);
return multiply(type, g0, ag1, dp, rm);
} else {
/**
* (cg0.compareTo(cg1) == 0) can be treated in the same way as
* (cg0.compareTo(cg1) == -1). If the frameworks align and g1 is
* a neat aggregation, then we can simply multiply the value of
* g1 at the centroid for each cell value of g0. Otherwise some
* intersection is needed to calculate some result cell values.
* The intersection can be achieved using a disaggregation to a
* cellsize smaller than g0 and then an aggregation.
*/
BigDecimal[] dar = cg1.divideAndRemainder(cg0);
if (dar[1].compareTo(BigDecimal.ZERO) == 0) {
BigDecimal x0 = dimg0.getXMin();
BigDecimal x1 = dimg1.getXMin();
boolean doSimple = false;
if (x1.compareTo(x0) == 0) {
doSimple = true;
} else if (x1.compareTo(x0) == -1) {
BigDecimal dx = x0.subtract(x1);
BigDecimal[] dar2 = dx.divideAndRemainder(cg1);
if (dar2[1].compareTo(BigDecimal.ZERO) == 0) {
doSimple = true;
}
} else {
BigDecimal dx = x1.subtract(x0);
BigDecimal[] dar2 = dx.divideAndRemainder(cg1);
if (dar2[1].compareTo(BigDecimal.ZERO) == 0) {
doSimple = true;
}
}
if (doSimple) {
multiply(g0, g1, r, ncr, ncc, ndv0, ndv1);
return r;
}
}
int factor = dar[0].toBigIntegerExact().intValue() + 1;
Grids_GridDouble dg1 = disaggregate(g1, factor);
Grids_GridDouble adg1 = aggregate(dg1, "mean", dimg0, dp, rm);
return multiply(type, g0, adg1, dp, rm);
}
}
}
protected void multiply(Grids_GridNumber g0, Grids_GridNumber g1,
Grids_GridNumber r, int ncr, int ncc, BigDecimal ndv0,
BigDecimal ndv1) throws Exception {
for (int cr = 0; cr < ncr; cr++) {
int cnr = g0.getChunkNRows(cr);
/**
* Prefer to keep a row of g0 and r chunks in memory.
*/
for (int ccr = 0; ccr < cnr; ccr++) {
long row = g0.getRow(cr, ccr);
BigDecimal y = g0.getCellY(row);
env.addToNotToClear(g1, g1.getChunkRow(y));
env.addToNotToClear(r, r.getChunkRow(y));
}
for (int cc = 0; cc < ncc; cc++) {
Grids_2D_ID_int i = new Grids_2D_ID_int(cr, cc);
env.addToNotToClear(g0, i);
env.checkAndMaybeFreeMemory();
int cnc = g0.getChunkNCols(cc);
for (int ccr = 0; ccr < cnr; ccr++) {
long row = r.getRow(cr, ccr);
BigDecimal y = g0.getCellY(row);
for (int ccc = 0; ccc < cnc; ccc++) {
long col = r.getCol(cc, ccc);
BigDecimal v0 = g0.getCellBigDecimal(cr, cc,
ccr, ccc);
if (v0.compareTo(ndv0) != 0) {
BigDecimal x = g0.getCellX(col);
BigDecimal v1 = g1.getCellBigDecimal(x, y);
if (v1.compareTo(ndv1) == 0) {
r.setCell(x, y, ndv0);
} else {
r.setCell(x, y, v0.multiply(v1));
}
//Debugging code
// env.env.log("result so far");
// env.env.log("x=" + x.toPlainString());
// env.env.log("y=" + y.toPlainString());
// env.env.log("row=" + row);
// env.env.log("col=" + col);
// env.env.log("v0=" + v0.toPlainString());
// env.env.log("v1=" + v1.toPlainString());
// r.log(10, 10);
}
}
}
env.removeFromNotToClear(g0, i);
}
/**
* Allow the row of g0 and r chunks to be swapped.
*/
for (int ccr = 0; ccr < cnr; ccr++) {
long row = g0.getRow(cr, ccr);
BigDecimal y = g0.getCellY(row);
env.addToNotToClear(g1, g1.getChunkRow(y));
env.addToNotToClear(r, r.getChunkRow(y));
}
}
}
/**
* This returns a grid with a {@code factor} greater resolution than
* {@code g}. If the cellsize of the result cannot be stored precisely, then
* this should result in a warning. IF the cellsize is divided by an even
* factor, in all cases except for very extreme cases it can be stored
* exactly. However, dividing by an odd power might result in a number that
* cannot be stored precisely as a decimal number. This in fact is a reason
* why cellsize should be stored not as a single BigDecimal Number, but as a
* fraction or rational number in two parts - a numerator and a denominator.
*
* @param g The grid on which the result values are based.
* @param factor The number of times smaller the cellsize of the result is.
* @return A grid with a {@code factor} greater resolution than {@code g}.
* @throws IOException If encountered.
* @throws ClassNotFoundException If encountered.
* @throws ArithmeticException If the cellsize of {@code g} cannot be
* divided by {@code factor} and stored exactly.
* @throws Exception If encountered.
*/
public Grids_GridDouble disaggregate(Grids_GridNumber g, int factor)
throws IOException, ClassNotFoundException, Exception {
Grids_Dimensions dim = g.getDimensions();
BigDecimal cellsize = dim.getCellsize();
BigDecimal rcellsize = cellsize.divide(BigDecimal.valueOf(factor),
RoundingMode.UNNECESSARY);
if (g instanceof Grids_GridDouble) {
return null;
} else if (g instanceof Grids_GridInt) {
return null;
} else {
return null;
}
}
/**
* Divide g0 by g1 and return a new grid. It is assumed that the dimensions
* are all the same;
*
* @param g0 Numerator
* @param g1 Denominator
* @return g0 / g1
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
public Grids_GridDouble divide(Grids_GridDouble g0, Grids_GridDouble g1)
throws IOException, ClassNotFoundException, Exception {
Grids_GridDouble r;
long nRows = g0.getNRows();
long nCols = g0.getNCols();
r = gridFactoryDouble.create(g0, 0L, 0L, nRows - 1, nCols - 1);
double noDataValue0 = g0.getNoDataValue();
double noDataValue1 = g1.getNoDataValue();
for (long row = 0L; row < nRows; row++) {
for (long col = 0L; col < nCols; col++) {
double v0 = g0.getCell(row, col);
double v1 = g1.getCell(row, col);
if (v0 != noDataValue0) {
if (v1 != noDataValue1) {
if (v1 != 0) {
r.setCell(row, col, v0 / v1);
}
}
}
}
}
return r;
}
/**
* For creating an aggregated Grids_GridDouble at a lower level of
* resolution than the grid {@code g}. The result values are either the sum,
* mean, max or min of values in grid depending on {@code statistic}.
*
* @param grid the Grids_GridDouble to be processed
* @param cellFactor the number of times wider/higher the aggregated grid
* cells are to be
* @param statistic "sum", "mean", "max", or "min" depending on what
* aggregate of values are wanted
* @param rowOffset The number of rows above or below the origin of grid
* where the aggregation is to start.
*
* - If {@code rowOffset > 0} then the result yllcorner will be above grid
* yllcorner
* - If {@code rowOffset < 0} result yllcorner will be below grid
* yllcorner
*
* @param colOffset The number of columns above or below the origin of grid
* where the aggregation is to start.
*
* - If {@code colOffset > 0} result xllcorner will be right of grid
* xllcorner
* - If {@code colOffset < 0} result xllcorner will be left of grid
* xllcorner
*
* @return An aggregated Grids_GridDouble at a lower level of resolution
* than the grid {@code g}. The result values are either the sum, mean, max
* or min of values in grid depending on {@code statistic}.
* @throws java.lang.Exception If encountered.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
public Grids_GridDouble aggregate(Grids_GridNumber grid, int cellFactor,
String statistic, int rowOffset, int colOffset) throws IOException,
ClassNotFoundException, Exception {
env.checkAndMaybeFreeMemory();
// Initial tests
if (cellFactor <= 0) {
System.err.println("Warning!!! cellFactor <= 0 : Returning!");
return null;
}
// Initialisation
long nrows = grid.getNRows();
long ncols = grid.getNCols();
Grids_Dimensions dimensions = grid.getDimensions();
BigDecimal cellsize = dimensions.getCellsize();
BigDecimal xMin = dimensions.getXMin();
BigDecimal yMin = dimensions.getYMin();
BigDecimal xMax = dimensions.getXMax();
BigDecimal yMax = dimensions.getYMax();
BigDecimal ndv = getNoDataValueBigDecimal(grid);
BigDecimal rC = cellsize.multiply(new BigDecimal(Integer.toString(cellFactor)));
BigDecimal rXMin = xMin.add(cellsize.multiply(BigDecimal.valueOf(colOffset)));
BigDecimal rYMin = yMin.add(cellsize.multiply(BigDecimal.valueOf(rowOffset)));
//double resultCellsize = cellsize * ( double ) cellFactor;
//double width = cellsize * ncols;
//double height = cellsize * nrows;
//double resultXllcorner = xllcorner + ( colOffset * cellsize );
//double resultYllcorner = yllcorner + ( rowOffset * cellsize );
// Calculate resultNrows and resultHeight
long rNrows = 1L;
BigDecimal rH = new BigDecimal(rC.toString());
while (rYMin.add(rH).compareTo(yMax) == -1) {
rNrows++;
rH = rH.add(rC);
}
//while ( ( resultYllcorner + resultHeight ) < ( yllcorner + height ) ) {
// resultNrows ++;
// resultHeight += resultCellsize;
//}
// Calculate resultNcols and resultWidth
long rNcols = 1L;
BigDecimal rWidth = new BigDecimal(rC.toString());
//double resultWidth = resultCellsize;
while (rXMin.add(rWidth).compareTo(xMax) == -1) {
rNrows++;
rWidth = rWidth.add(rC);
}
//while ( ( resultXllcorner + resultWidth ) < ( xllcorner + width ) ) {
// resultNcols ++;
// resultWidth += resultCellsize;
//}
BigDecimal rXMax = rXMin.add(rWidth);
BigDecimal rYMax = rYMin.add(rH);
Grids_Dimensions rD = new Grids_Dimensions(rXMin,
rXMax, rYMin, rYMax, rC);
// Initialise result
double ndvd = ndv.doubleValue();
gridFactoryDouble.setNoDataValue(ndv.doubleValue());
Grids_GridDouble r = gridFactoryDouble.create(rNrows, rNcols, rD);
// sum
if (statistic.equalsIgnoreCase("sum")) {
Grids_GridDouble count = gridFactoryDouble.create(rNrows, rNcols, rD);
Grids_GridDouble normaliser = gridFactoryDouble.create(rNrows, rNcols, rD);
for (long row = 0; row < nrows; row++) {
for (long col = 0; col < ncols; col++) {
BigDecimal x = grid.getCellX(col);
BigDecimal y = grid.getCellY(row);
if (r.isInGrid(x, y)) {
BigDecimal value = grid.getCellBigDecimal(row, col);
if (value.compareTo(ndv) != 0) {
count.addToCell(x, y, 1.0d);
r.addToCell(x, y, value.doubleValue());
}
normaliser.addToCell(x, y, 1.0d);
}
}
}
// // Add the nearest values for the noDataValues so long as there is a value
// for ( row = 0; row < nrows; row ++ ) {
// for ( col = 0; col < ncols; col ++ ) {
// x = grid.getCellXDouble( col, hoome );
// y = grid.getCellYDouble( row, hoome );
// if ( result.inGrid( x, y, hoome ) ) {
// if ( dataCount.getCell( x, y, hoome ) != noDataValue ) {
// result.addToCell( x, y, grid.getNearestValueDouble( row, col, hoome ), hoome );
// }
// }
// }
// }
// Normalise
double count0;
for (int row = 0; row < rNrows; row++) {
for (int col = 0; col < rNcols; col++) {
count0 = count.getCell(row, col);
if (count0 != 0.0d) {
r.setCell(row, col, ((r.getCell(row, col)
* normaliser.getCell(row, col)) / count0));
}
}
}
}
// mean
if (statistic.equalsIgnoreCase("mean")) {
Grids_GridDouble numerator = gridFactoryDouble.create(rNrows, rNcols, rD);
Grids_GridDouble denominator = gridFactoryDouble.create(rNrows, rNcols, rD);
for (int row = 0; row < nrows; row++) {
for (int col = 0; col < ncols; col++) {
BigDecimal x = grid.getCellX(col);
BigDecimal y = grid.getCellY(row);
if (r.isInGrid(x, y)) {
BigDecimal value = grid.getCellBigDecimal(row, col);
if (value.compareTo(ndv) != 0) {
numerator.addToCell(x, y, value.doubleValue());
denominator.addToCell(x, y, 1.0d);
}
}
}
}
for (int row = 0; row < rNrows; row++) {
for (int col = 0; col < rNcols; col++) {
BigDecimal value = numerator.getCellBigDecimal(row, col);
if (value.compareTo(ndv) != 0) {
r.setCell(row, col, value.doubleValue()
/ denominator.getCell(row, col));
}
}
}
}
// min
if (statistic.equalsIgnoreCase("min")) {
for (int row = 0; row < nrows; row++) {
for (int col = 0; col < ncols; col++) {
BigDecimal x = grid.getCellX(col);
BigDecimal y = grid.getCellY(row);
if (r.isInGrid(x, y)) {
BigDecimal value = grid.getCellBigDecimal(row, col);
if (value.compareTo(ndv) != 0) {
double min = r.getCell(x, y);
if (min != ndvd) {
r.setCell(x, y, Math.min(min, value.doubleValue()));
} else {
r.setCell(x, y, value.doubleValue());
}
}
}
}
}
}
// max
if (statistic.equalsIgnoreCase("max")) {
double max;
for (int row = 0; row < nrows; row++) {
for (int col = 0; col < ncols; col++) {
BigDecimal x = grid.getCellX(col);
BigDecimal y = grid.getCellY(row);
if (r.isInGrid(x, y)) {
BigDecimal value = grid.getCellBigDecimal(row, col);
if (value.compareTo(ndv) != 0) {
max = r.getCell(x, y);
if (max != ndvd) {
r.setCell(x, y, Math.max(max, value.doubleValue()));
} else {
r.setCell(x, y, value.doubleValue());
}
}
}
}
}
}
return r;
}
// /**
// * Returns an Grids_GridDouble at a lower level of resolution than grid. The result values
// * are either the sum, mean, max or min of values in grid depending on statistic.
// * @param grid - the Grids_GridDouble to be processed
// * @param resultCellsize - output grid cellsize
// * @param statistic - "sum", "mean", "max", or "min" depending on what aggregate of values are wanted
// * @param resultXllcorner - the x-coordinate of the aggregate grid lower left corner
// * @param resultYllcorner - the y-coordinate of the aggregate grid lower left corner
// * Use this aggregate method to force origin of the result to be ( resultXllcorner, resultYllcorner ) and
// * if resultCellsize is not an integer multiple of cellsize.
// * NB. In the calculation of the sum and the mean if there is a cell in grid which has a data value then
// * the result which incorporates that cell has a data value. For this result cell, any of the cells in
// * grid which have noDataValues their value is taken as that of the average of its nearest cells with
// * a value.
// * In the calculation of the max and the min noDataValues are simply ignored.
// * Formerly noDataValues were treated as the average of values within a result cell.
// * TODO: implement median, mode and variance aggregations.
// */
// public Grids_GridDouble aggregate( Grids_GridDouble grid, double resultCellsize, String statistic, double resultXllcorner, double resultYllcorner ) {
// try {
// return aggregate( grid, resultCellsize, statistic, resultXllcorner, resultYllcorner, new Grids_GridFactoryDouble() );
// } catch ( OutOfMemoryError e ) {
// return aggregate( grid, resultCellsize, statistic, resultXllcorner, resultYllcorner, new Grid2DSquareCellDoubleFileFactory() );
// }
// }
public BigDecimal getNoDataValueBigDecimal(Grids_GridNumber g) throws Exception {
BigDecimal r = BigDecimal.valueOf(-Double.MAX_VALUE);
if (g.getClass() == Grids_GridInt.class) {
r = BigDecimal.valueOf(((Grids_GridInt) g).getNoDataValue());
} else {
if (g.getClass() == Grids_GridDouble.class) {
r = BigDecimal.valueOf(((Grids_GridDouble) g).getNoDataValue());
} else {
throw new Exception("Unrecognized Grids_Number type.");
}
}
return r;
}
/**
* Returns an Grids_GridDouble at a lower level of resolution than grid. The
* result values are either the sum, mean, max or min of values in grid
* depending on statistic. Use this aggregate method if result is to have a
* new spatial frame. NB. In the calculation of the sum and the mean if
* there is a cell in grid which has a data value then the result which
* incorporates that cell has a data value. For this result cell, any of the
* cells in grid which have noDataValues their value is taken as that of the
* average of its nearest cells with a value. In the calculation of the max
* and the min noDataValues are simply ignored. Formerly noDataValues were
* treated as the average of values within a result cell.
*
* @param g The stats to be processed
* @param stats "sum", "mean", "max", or "min" depending on what aggregate
* of values are wanted
* @param rD result dimensions.
* @param dp Decimal place precision for any BigDecimal Arithmetic.
* @param rm Rounding Mode for any BigDecimal Arithmetic.
* @return An aggregate grid.
* @throws java.lang.Exception If encountered.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
public Grids_GridDouble aggregate(Grids_GridNumber g, String stats,
Grids_Dimensions rD, int dp, RoundingMode rm)
throws IOException, ClassNotFoundException, Exception {
env.checkAndMaybeFreeMemory();
// Initialistaion
long nrows = g.getNRows();
long ncols = g.getNCols();
Grids_Dimensions dim = g.getDimensions();
BigDecimal ndv = getNoDataValueBigDecimal(g);
double ndvd = ndv.doubleValue();
BigDecimal rC = rD.getCellsize();
BigDecimal rXMin = rD.getXMin();
BigDecimal rYMin = rD.getYMin();
//BigDecimal rXMax = rD.getXMax();
//BigDecimal rYMax = rD.getYMax();
BigDecimal rCH = rC.divide(BigDecimal.valueOf(2));
BigDecimal rCS = rC.multiply(rC);
BigDecimal c = dim.getCellsize();
BigDecimal xMin = dim.getXMin();
BigDecimal yMin = dim.getYMin();
BigDecimal xMax = dim.getXMax();
BigDecimal yMax = dim.getYMax();
BigDecimal cS = c.multiply(c);
BigDecimal cH = c.divide(BigDecimal.valueOf(2));
//double width = cellsize * ncols;
//double height = cellsize * nrows;
// Test this is an aggregation
if (rC.compareTo(c) != 1) {
env.env.log("!!!Warning: Not an aggregation as "
+ "resultCellsize < cellsize. Returning null!");
return null;
}
// Test for intersection
if ((rXMin.compareTo(xMin.add(c.multiply(BigDecimal.valueOf(ncols)))) == 1)
|| (rYMin.compareTo(yMin.add(c.multiply(BigDecimal.valueOf(nrows)))) == 1)) {
System.err.println(
"!!!Warning: No intersection for aggregation. Returning null!");
return null;
}
/**
* If rC is an integer multiple of c and g aligns with r then return a
* cellFactor aggregation as it should be faster.
*/
if (true) {
BigDecimal t0 = rC.divide(c, Math.max(rC.scale(), c.scale()) + 2, rm);
BigDecimal t1 = rXMin.divide(c, Math.max(rXMin.scale(), c.scale()) + 2, rm);
BigDecimal t2 = xMin.divide(c, Math.max(xMin.scale(), c.scale()) + 2, rm);
BigDecimal t3 = rYMin.divide(c, Math.max(rYMin.scale(), c.scale()) + 2, rm);
BigDecimal t4 = yMin.divide(c, Math.max(yMin.scale(), c.scale()) + 2, rm);
if ((t0.compareTo(new BigDecimal(t0.toBigInteger().toString())) == 0)
&& (t1.compareTo(new BigDecimal(t1.toBigInteger().toString()))
== t2.compareTo(new BigDecimal(t2.toBigInteger().toString())))
&& (t3.compareTo(new BigDecimal(t3.toBigInteger().toString()))
== t4.compareTo(new BigDecimal(t4.toBigInteger().toString())))) {
int cellFactor = rC.divide(c, 2, RoundingMode.UNNECESSARY).intValue();
int rowOffset = yMin.subtract(rYMin.divide(c, dp, rm)).intValue();
int colOffset = xMin.subtract(rXMin.divide(c, dp, rm)).intValue();
return aggregate(g, cellFactor, stats, rowOffset, colOffset);
}
}
// Calculate number of rows and height of result.
long rNrows = 1L;
BigDecimal rH = new BigDecimal(rC.toString());
while (rYMin.add(rH).compareTo(yMax) == -1) {
rNrows++;
rH = rH.add(rC);
}
// Calculate number of columns and width of result.
long rNcols = 1L;
BigDecimal rW = new BigDecimal(rC.toString());
while (rXMin.add(rW).compareTo(xMax) == -1) {
rNrows++;
rW = rW.add(rC);
}
//rXMax = xMin.add(rW);
//rYMax = yMin.add(rH);
// Initialise result
gridFactoryDouble.setNoDataValue(ndvd);
Grids_GridDouble r = gridFactoryDouble.create(rNrows, rNcols, rD);
// sum
BigDecimal aP;
if (stats.equalsIgnoreCase("sum")) {
Grids_GridDouble totalValueArea = gridFactoryDouble.create(rNrows, rNcols, rD);
Grids_2D_ID_long[] cellIDs = new Grids_2D_ID_long[4];
for (int row = 0; row < nrows; row++) {
for (int col = 0; col < ncols; col++) {
BigDecimal[] bounds = g.getCellBounds(cH, row, col);
cellIDs[0] = r.getCellID(bounds[0], bounds[3]);
cellIDs[1] = r.getCellID(bounds[2], bounds[3]);
cellIDs[2] = r.getCellID(bounds[0], bounds[1]);
cellIDs[3] = r.getCellID(bounds[2], bounds[1]);
BigDecimal value = g.getCellBigDecimal(row, col);
if (value != ndv) {
if (cellIDs[0].equals(cellIDs[1]) && cellIDs[1].equals(
cellIDs[2])) {
r.addToCell(cellIDs[0], value.doubleValue());
totalValueArea.addToCell(cellIDs[0], 1.0d);
} else {
aP = getAP(bounds, r, cellIDs[0], cellIDs[1],
cellIDs[2], c, rCS, rCH, dp, rm);
r.addToCell(cellIDs[0], value.multiply(aP));
totalValueArea.addToCell(cellIDs[0], aP);
}
if (!cellIDs[1].equals(cellIDs[0])) {
aP = getAP13(bounds, r, cellIDs[1], cellIDs[3], c,
rCS, rCH, dp, rm);
r.addToCell(cellIDs[1], value.multiply(aP));
totalValueArea.addToCell(cellIDs[0], aP);
}
if (!cellIDs[2].equals(cellIDs[0])) {
aP = getAP23(bounds, r, cellIDs[2], cellIDs[3], c,
rCS, rCH, dp, rm);
r.addToCell(cellIDs[2], value.multiply(aP));
}
if (!cellIDs[3].equals(cellIDs[1]) && !cellIDs[3]
.equals(cellIDs[2])) {
aP = getAP3(bounds, r, cellIDs[3], c, rCS, rCH, dp,
rm);
r.addToCell(cellIDs[3], value.multiply(aP));
totalValueArea.addToCell(cellIDs[0], aP);
}
}
}
}
// Normalise
double totalValueArea0;
double dCDiff2 = rC.subtract(c).pow(2).doubleValue();
for (int row = 0; row < rNrows; row++) {
for (int col = 0; col < rNcols; col++) {
totalValueArea0 = totalValueArea.getCell(row, col);
if (totalValueArea0 != 0.0d) {
r.setCell(row, col, ((r.getCell(row, col) * dCDiff2)
/ totalValueArea.getCell(row, col)));
}
}
}
}
// mean
if (stats.equalsIgnoreCase("mean")) {
double denominator = (rC.doubleValue() * rC.doubleValue())
/ (c.doubleValue() * c.doubleValue());
Grids_GridDouble sum = aggregate(g, "sum", rD, dp, rm);
addToGrid(r, sum, BigDecimal.valueOf(1.0d / denominator), dp, rm);
}
// max
if (stats.equalsIgnoreCase("max")) {
for (long row = 0; row < nrows; row++) {
for (long col = 0; col < ncols; col++) {
BigDecimal value = g.getCellBigDecimal(row, col);
if (value.compareTo(ndv) != 0) {
//BigDecimal x = g.getCellX(col);
//BigDecimal y = g.getCellY(row);
BigDecimal[] bounds = g.getCellBounds(cH, row, col);
double max = r.getCell(bounds[0], bounds[3]);
if (max != ndvd) {
r.setCell(bounds[0], bounds[3], Math.max(max, value.doubleValue()));
} else {
r.setCell(bounds[0], bounds[3], value.doubleValue());
}
max = r.getCell(bounds[2], bounds[3]);
if (max != ndvd) {
r.setCell(bounds[2], bounds[3], Math.max(max, value.doubleValue()));
} else {
r.setCell(bounds[2], bounds[3], value.doubleValue());
}
max = r.getCell(bounds[0], bounds[1]);
if (max != ndvd) {
r.setCell(bounds[0], bounds[1], Math.max(max, value.doubleValue()));
} else {
r.setCell(bounds[0], bounds[1], value.doubleValue());
}
max = r.getCell(bounds[2], bounds[1]);
if (max != ndvd) {
r.setCell(bounds[2], bounds[1], Math.max(max, value.doubleValue()));
} else {
r.setCell(bounds[2], bounds[1], value.doubleValue());
}
}
}
}
}
// min
if (stats.equalsIgnoreCase("min")) {
double min;
BigDecimal[] bounds;
double halfCellsize = cH.doubleValue();
for (long row = 0; row < nrows; row++) {
for (long col = 0; col < ncols; col++) {
BigDecimal value = g.getCellBigDecimal(row, col);
if (value.compareTo(ndv) != 0) {
double vD = value.doubleValue();
BigDecimal x = g.getCellX(col);
BigDecimal y = g.getCellY(row);
bounds = g.getCellBounds(cH, row, col);
min = r.getCell(bounds[0], bounds[3]);
if (min != ndvd) {
r.setCell(bounds[0], bounds[3], Math.min(min, vD));
} else {
r.setCell(bounds[0], bounds[3], vD);
}
min = r.getCell(bounds[2], bounds[3]);
if (min != ndvd) {
r.setCell(bounds[2], bounds[3], Math.min(min, vD));
} else {
r.setCell(bounds[2], bounds[3], vD);
}
min = r.getCell(bounds[0], bounds[1]);
if (min != ndvd) {
r.setCell(bounds[0], bounds[1], Math.min(min, vD));
} else {
r.setCell(bounds[0], bounds[1], vD);
}
min = r.getCell(bounds[2], bounds[1]);
if (min != ndvd) {
r.setCell(bounds[2], bounds[1], Math.min(min, value.doubleValue()));
} else {
r.setCell(bounds[2], bounds[1], vD);
}
}
}
}
}
/*
// Initialistaion
int nrows = grid.getNRows();
int ncols = grid.getNCols();
double xllcorner = grid.getXllcorner();
double yllcorner = grid.getYllcorner();
double cellsize = grid.getCellsize();
double noDataValue = grid.getNoDataValue();
double width = cellsize * ncols;
double height = cellsize * nrows;
// Test this is an aggregation
if ( resultCellsize <= cellsize ) {
println( "!!!Warning: resultCellsize <= cellsize in aggregate( cellsize( " + resultCellsize + " ), statistic( " + statistic + " ), resultXllcorner( " + resultXllcorner + " ), resultYllcorner( " + resultYllcorner + " ), noDataValue( " + noDataValue + " ), gridFactory( " + gridFactory.toString() + " ) ). Returning null!" );
return null;
}
// Test for intersection
if ( ( resultXllcorner > xllcorner + ( ( double ) ncols * cellsize ) ) || ( resultYllcorner > yllcorner + ( ( double ) nrows * cellsize ) ) ) {
println( "!!!Warning: No intersection in aggregate( cellsize( " + resultCellsize + " ), statistic( " + statistic + " ), resultXllcorner( " + resultXllcorner + " ), resultYllcorner( " + resultYllcorner + " ), noDataValue( " + noDataValue + " ), gridFactory( " + gridFactory.toString() + " ) ). Returning null!" );
return null;
}
// If resultCellsize is an integer multiple of cellsize and grid aligns with result then use
// a cellFactor aggregation as it should be faster.
//println("resultCellsize % cellsize == " + ( resultCellsize % cellsize ) );
//println("resultXllcorner % cellsize = " + ( resultXllcorner % cellsize ) + ", xllcorner % cellsize = " + ( xllcorner % cellsize ) );
//println("resultYllcorner % cellsize = " + ( resultYllcorner % cellsize ) + ", yllcorner % cellsize = " + ( yllcorner % cellsize ) );
if ( ( resultCellsize % cellsize == 0.0d ) && ( ( resultXllcorner % cellsize ) == ( xllcorner % cellsize ) ) && ( ( resultYllcorner % cellsize ) == ( yllcorner % cellsize ) ) ) {
int cellFactor = ( int ) ( resultCellsize / cellsize );
int rowOffset = ( int ) ( yllcorner - resultYllcorner / cellsize );
int colOffset = ( int ) ( xllcorner - resultXllcorner / cellsize );
return aggregate( grid, cellFactor, statistic, rowOffset, colOffset, gridFactory );
}
// Calculate resultNrows and resultHeight
int resultNrows = 1;
double resultHeight = resultCellsize;
while ( ( resultYllcorner + resultHeight ) < ( yllcorner + height ) ) {
resultNrows ++;
resultHeight += resultCellsize;
}
// Calculate resultNcols and resultWidth
int resultNcols = 1;
double resultWidth = resultCellsize;
while ( ( resultXllcorner + resultWidth ) < ( xllcorner + width ) ) {
resultNcols ++;
resultWidth += resultCellsize;
}
//println( "resultNcols " + resultNcols + ", resultNrows " + resultNrows );
//println( "gridToAddNcols " + ncols + ", gridToAddNrows " + nrows );
// Initialise result
Grids_GridDouble result = gridFactory.createGrid2DSquareCellDouble( resultNrows, resultNcols, resultXllcorner, resultYllcorner, resultCellsize, noDataValue );
// sum
if ( statistic.equalsIgnoreCase( "sum" ) ) {
Grids_GridDouble tempGrid1 = gridFactory.createGrid2DSquareCellDouble( resultNrows, resultNcols, resultXllcorner, resultYllcorner, resultCellsize, noDataValue, 1 );
Grids_GridDouble tempGrid2 = gridFactory.createGrid2DSquareCellDouble( resultNrows, resultNcols, resultXllcorner, resultYllcorner, resultCellsize, noDataValue, 1 );
double x = 0.0d;
double y = 0.0d;
double d1 = noDataValue;
double areaProportion = 0.0d;
double[] bounds = new double[ 4 ];
int cellID1 = -1;
int cellID2 = -1;
int cellID3 = -1;
int cellID4 = -1;
//double totalArea = 0;
for ( int i = 0; i < nrows * ncols; i ++ ) {
d1 = grid.getCell( i );
if ( d1 != noDataValue ) {
x = grid.getCellXDouble( i );
y = grid.getCellYDouble( i );
bounds = grid.getCellBounds( i );
cellID1 = result.getCellID( bounds[ 0 ], bounds[ 3 ] );
cellID2 = result.getCellID( bounds[ 2 ], bounds[ 3 ] );
cellID3 = result.getCellID( bounds[ 0 ], bounds[ 1 ] );
cellID4 = result.getCellID( bounds[ 2 ], bounds[ 1 ] );
if ( cellID1 == cellID2 && cellID2 == cellID3 ) {
if ( cellID1 != Integer.MIN_VALUE ) {
areaProportion = 1.0d;
tempGrid1.addToCell( x, y, d1 * areaProportion );
tempGrid2.addToCell( x, y, areaProportion );
}
} else {
if ( cellID1 != Integer.MIN_VALUE ) {
if ( cellID1 == cellID2 || cellID1 == cellID3 ) {
if ( cellID1 == cellID2 ) {
areaProportion = ( Math.abs( bounds[3] - ( result.getCellYDouble( cellID1 ) - ( resultCellsize / 2.0d ) ) ) * cellsize ) / ( cellsize * cellsize );
} else {
areaProportion = ( Math.abs( ( result.getCellXDouble( cellID1 ) + ( resultCellsize / 2.0d ) ) - bounds[0] ) * cellsize ) / ( cellsize * cellsize );
}
} else {
areaProportion = ( ( Math.abs( bounds[3] - ( result.getCellYDouble( cellID1 ) - ( resultCellsize / 2.0d ) ) ) * Math.abs( ( result.getCellXDouble( cellID1 ) + ( resultCellsize / 2.0d ) ) - bounds[0] ) ) / ( cellsize * cellsize ) );
}
tempGrid1.addToCell( cellID1, d1 * areaProportion );
tempGrid2.addToCell( cellID1, areaProportion );
}
if ( cellID2 != Integer.MIN_VALUE ) {
if ( cellID2 != cellID1 ) {
if ( cellID2 == cellID4 ) {
areaProportion = ( Math.abs( bounds[2] - ( result.getCellXDouble( cellID2 ) - ( resultCellsize / 2.0d ) ) ) * cellsize ) / ( cellsize * cellsize );
} else {
areaProportion = ( ( Math.abs( bounds[3] - ( result.getCellYDouble( cellID2 ) - ( resultCellsize / 2.0d ) ) ) * Math.abs( bounds[2] - ( result.getCellXDouble( cellID2 ) - ( resultCellsize / 2.0d ) ) ) ) / ( cellsize * cellsize ) );
}
tempGrid1.addToCell( cellID2, d1 * areaProportion );
tempGrid2.addToCell( cellID2, areaProportion );
}
}
if ( cellID3 != Integer.MIN_VALUE ) {
if ( cellID3 != cellID1 ) {
if ( cellID3 == cellID4 ) {
areaProportion = ( Math.abs( ( result.getCellYDouble( cellID3 ) + ( resultCellsize / 2.0d ) ) - bounds[1] ) * cellsize ) / ( cellsize * cellsize );
} else {
areaProportion = ( ( Math.abs( ( result.getCellYDouble( cellID3 ) + ( resultCellsize / 2.0d ) ) - bounds[1] ) * Math.abs( ( result.getCellXDouble( cellID3 ) + ( resultCellsize / 2.0d) ) - bounds[0] ) ) / ( cellsize * cellsize ) );
}
tempGrid1.addToCell( cellID3, d1 * areaProportion );
tempGrid2.addToCell( cellID3, areaProportion );
}
}
if ( cellID4 != Integer.MIN_VALUE ) {
if ( cellID4 != cellID2 && cellID4 != cellID3 ) {
areaProportion = ( ( Math.abs( ( result.getCellYDouble( cellID4 ) + ( resultCellsize / 2.0d ) ) - bounds[1] ) * Math.abs( bounds[2] - ( result.getCellXDouble( cellID4 ) - ( resultCellsize / 2.0d ) ) ) ) / ( cellsize * cellsize ) );
tempGrid1.addToCell( cellID4, d1 * areaProportion );
tempGrid2.addToCell( cellID4, areaProportion );
}
}
// Check fails due to rounding errors!
//if ( cellID1 != Integer.MIN_VALUE && cellID2 != Integer.MIN_VALUE && cellID3 != Integer.MIN_VALUE && cellID4 != Integer.MIN_VALUE && totalArea != 1.0 ) { println( "id = " + i + " : totalArea = " + totalArea + " (cellID1,cellID2,cellID3,cellID4) = (" + cellID1 + "," + cellID2 + "," + cellID3 + "," + cellID4 + ")" );
// throw an exception!!!
//}
}
}
}
// The values are normalised by dividing the aggregate Grid sum by the proportion of cells with grid values.
for ( int i = 0; i < resultNrows * resultNcols; i ++ ) {
d1 = tempGrid2.getCell( i );
if ( d1 != 0.0d && d1 != noDataValue ) {
result.setCell( i, tempGrid1.getCell( i ) / ( Math.pow( ( resultCellsize / cellsize ), 2.0d ) / d1 ) );
}
}
tempGrid1.clear();
tempGrid2.clear();
}
// mean
if ( statistic.equalsIgnoreCase( "mean" ) ) {
// To calculate the mean and cope with NODATA it is necessary to pass
// through the data twice or for each aggregated cell get all
// intersecting cells. This is because each cells area as a proportion
// of the non noDataValue area of an aggregated cell is needed. This
// cannot be simply done as it all depends on NODATA. In the
// implementation below the data is read through twice. First read
// involves calculating NODATA in each aggregated cell.
Grids_GridDouble tempGrid1 = gridFactory.createGrid2DSquareCellDouble( resultNrows, resultNcols, resultXllcorner, resultYllcorner, resultCellsize, noDataValue, 1 );
Grids_GridDouble tempGrid2 = gridFactory.createGrid2DSquareCellDouble( resultNrows, resultNcols, resultXllcorner, resultYllcorner, resultCellsize, noDataValue, 1 );
double x;
double y;
double d1;
double area;
double[] bounds = new double[4];
int cellID1;
int cellID2;
int cellID3;
int cellID4;
//double totalArea = 0;
for ( int i = 0; i < nrows * ncols; i ++ ) {
d1 = grid.getCell( i );
if ( d1 != noDataValue ) {
x = grid.getCellXDouble( i );
y = grid.getCellYDouble( i );
bounds = grid.getCellBounds( i );
cellID1 = result.getCellID( bounds[0], bounds[3] );
cellID2 = result.getCellID( bounds[2], bounds[3] );
cellID3 = result.getCellID( bounds[0], bounds[1] );
cellID4 = result.getCellID( bounds[2], bounds[1] );
if ( cellID1 == cellID2 && cellID2 == cellID3 ) {
if ( cellID1 != Integer.MIN_VALUE ) {
area = cellsize * cellsize;
tempGrid1.addToCell( x, y, area );
}
} else {
if ( cellID1 != Integer.MIN_VALUE ) {
if ( cellID1 == cellID2 || cellID1 == cellID3 ) {
if ( cellID1 == cellID2 ) {
area = ( Math.abs( bounds[3] - ( result.getCellYDouble( cellID1 ) - ( resultCellsize / 2.0d ) ) ) * cellsize );
} else {
area = ( Math.abs( ( result.getCellXDouble( cellID1 ) + ( resultCellsize / 2.0d ) ) - bounds[0] ) * cellsize );
}
} else {
area = ( Math.abs( bounds[3] - ( result.getCellYDouble( cellID1 ) - ( resultCellsize / 2.0d ) ) ) * Math.abs( ( result.getCellXDouble( cellID1 ) + ( resultCellsize / 2.0d ) ) - bounds[0] ) );
}
tempGrid1.addToCell( cellID1, area );
}
if ( cellID2 != Integer.MIN_VALUE ) {
if ( cellID2 != cellID1 ) {
if ( cellID2 == cellID4 ) {
area = ( Math.abs( bounds[2] - ( result.getCellXDouble( cellID2 ) - ( resultCellsize / 2.0d ) ) ) * cellsize );
} else {
area = ( Math.abs( bounds[3] - ( result.getCellYDouble( cellID2 ) - ( resultCellsize / 2.0d ) ) ) * Math.abs( bounds[2] - ( result.getCellXDouble( cellID2 ) - ( resultCellsize / 2.0d ) ) ) );
}
tempGrid1.addToCell( cellID2, area );
}
}
if ( cellID3 != Integer.MIN_VALUE ) {
if ( cellID3 != cellID1 ) {
if ( cellID3 == cellID4 ) {
area = ( Math.abs( ( result.getCellYDouble( cellID3 ) + ( resultCellsize / 2.0d ) ) - bounds[1] ) * cellsize );
} else {
area = ( Math.abs( ( result.getCellYDouble( cellID3 ) + ( resultCellsize / 2.0d ) ) - bounds[1] ) * Math.abs( ( result.getCellXDouble( cellID3 ) + ( resultCellsize / 2.0d ) ) - bounds[0] ) );
}
tempGrid1.addToCell( cellID3, area );
}
}
if ( cellID4 != Integer.MIN_VALUE ) {
if ( cellID4 != cellID2 && cellID4 != cellID3 ) {
area = ( Math.abs( ( result.getCellYDouble( cellID4 ) + ( resultCellsize / 2.0d ) ) - bounds[1] ) * Math.abs( bounds[2] - ( result.getCellXDouble( cellID4 ) - ( resultCellsize / 2.0d ) ) ) );
tempGrid1.addToCell( cellID4, area );
}
}
}
}
}
for ( int i = 0; i < nrows * ncols; i ++ ) {
double areaIntersect;
d1 = grid.getCell( i );
if ( d1 != noDataValue ) {
x = grid.getCellXDouble( i );
y = grid.getCellYDouble( i );
bounds = grid.getCellBounds( i );
cellID1 = result.getCellID( bounds[0], bounds[3] );
cellID2 = result.getCellID( bounds[2], bounds[3] );
cellID3 = result.getCellID( bounds[0], bounds[1] );
cellID4 = result.getCellID( bounds[2], bounds[1] );
if ( cellID1 == cellID2 && cellID2 == cellID3 ) {
if ( cellID1 != Integer.MIN_VALUE ) {
area = tempGrid1.getCell( x, y );
result.addToCell( x, y, d1 * ( cellsize * cellsize ) / area );
}
} else {
if ( cellID1 != Integer.MIN_VALUE ) {
if ( cellID1 == cellID2 || cellID1 == cellID3 ) {
if ( cellID1 == cellID2 ) {
areaIntersect = ( Math.abs( bounds[3] - ( result.getCellYDouble( cellID1 ) - ( resultCellsize / 2.0d ) ) ) * cellsize );
} else {
areaIntersect = ( Math.abs( ( result.getCellXDouble( cellID1 ) + ( resultCellsize / 2.0d ) ) - bounds[0] ) * cellsize );
}
} else {
areaIntersect = ( Math.abs( bounds[3] - ( result.getCellYDouble( cellID1 ) - ( resultCellsize / 2.0d ) ) ) * Math.abs( ( result.getCellXDouble( cellID1 ) + ( resultCellsize / 2.0d ) ) - bounds[0] ) );
}
area = tempGrid1.getCell( cellID1 );
result.addToCell( cellID1, d1 * areaIntersect / area );
}
if ( cellID2 != Integer.MIN_VALUE ) {
if ( cellID2 != cellID1 ) {
if ( cellID2 == cellID4 ) {
areaIntersect = ( Math.abs( bounds[2] - ( result.getCellXDouble( cellID2 ) - ( resultCellsize / 2.0d ) ) ) * cellsize );
} else {
areaIntersect = ( Math.abs( bounds[3] - ( result.getCellYDouble( cellID2 ) - ( resultCellsize / 2.0d ) ) ) * Math.abs( bounds[2] - ( result.getCellXDouble( cellID2 ) - ( resultCellsize / 2.0d ) ) ) );
}
area = tempGrid1.getCell( cellID2 );
result.addToCell( cellID2, d1 * areaIntersect / area );
}
}
if ( cellID3 != Integer.MIN_VALUE ) {
if ( cellID3 != cellID1 ) {
if ( cellID3 == cellID4 ) {
areaIntersect = ( Math.abs( ( result.getCellYDouble( cellID3 ) + ( resultCellsize / 2.0d ) ) - bounds[1] ) * cellsize );
} else {
areaIntersect = ( Math.abs( ( result.getCellYDouble( cellID3 ) + ( resultCellsize / 2.0d ) ) - bounds[1] ) * Math.abs( ( result.getCellXDouble( cellID3 ) + ( resultCellsize / 2.0d ) ) - bounds[0] ) );
}
area = tempGrid1.getCell( cellID3 );
result.addToCell( cellID3, d1 * areaIntersect / area );
}
}
if ( cellID4 != Integer.MIN_VALUE ) {
if ( cellID4 != cellID2 && cellID4 != cellID3 ) {
areaIntersect = ( Math.abs( ( result.getCellYDouble( cellID4 ) + ( resultCellsize / 2.0d ) ) - bounds[1] ) * Math.abs( bounds[2] - ( result.getCellXDouble( cellID4 ) - ( resultCellsize / 2.0d ) ) ) );
area = tempGrid1.getCell( cellID4 );
result.addToCell( cellID4, d1 * areaIntersect / area );
}
}
}
}
}
tempGrid1.clear();
}
// max
if ( statistic.equalsIgnoreCase( "max" ) ) {
double x;
double y;
double d1;
double d2;
double[] bounds = new double[4];
for ( int i = 0; i < nrows * ncols; i ++ ) {
d1 = grid.getCell( i );
if ( d1 != noDataValue ) {
x = grid.getCellXDouble( i );
y = grid.getCellYDouble( i );
bounds = grid.getCellBounds( i );
d2 = result.getCell( bounds[0], bounds[3] );
if ( d2 != noDataValue ) {
result.setCell( bounds[0], bounds[3], Math.max( d2, d1 ) );
} else {
result.setCell( bounds[0], bounds[3], d1 );
}
d2 = result.getCell( bounds[2], bounds[3] );
if ( d2 != noDataValue ) {
result.setCell( bounds[2], bounds[3], Math.max( d2, d1 ) );
} else {
result.setCell( bounds[2], bounds[3], d1 );
}
d2 = result.getCell( bounds[0], bounds[1] );
if ( d2 != noDataValue ) {
result.setCell( bounds[0], bounds[1], Math.max( d2, d1 ) );
} else {
result.setCell( bounds[0], bounds[1], d1 );
}
d2 = result.getCell( bounds[2], bounds[1] );
if ( d2 != noDataValue ) {
result.setCell( bounds[2], bounds[1], Math.max( d2, d1 ) );
} else {
result.setCell( bounds[2], bounds[1], d1 );
}
}
}
}
// min
if ( statistic.equalsIgnoreCase( "min" ) ) {
double x;
double y;
double d1;
double d2;
double[] bounds = new double[4];
for ( int i = 0; i < nrows * ncols; i ++ ) {
d1 = grid.getCell( i );
if ( d1 != noDataValue ) {
x = grid.getCellXDouble( i );
y = grid.getCellYDouble( i );
bounds = grid.getCellBounds( i );
d2 = result.getCell( bounds[0], bounds[3] );
if ( d2 != noDataValue ) {
result.setCell( bounds[0], bounds[3], Math.min( d2, d1 ) );
} else {
result.setCell( bounds[0], bounds[3], d1 );
}
d2 = result.getCell( bounds[2], bounds[3] );
if ( d2 != noDataValue ) {
result.setCell( bounds[2], bounds[3], Math.min( d2, d1 ) );
} else {
result.setCell( bounds[2], bounds[3], d1 );
}
d2 = result.getCell( bounds[0], bounds[1] );
if ( d2 != noDataValue ) {
result.setCell( bounds[0], bounds[1], Math.min( d2, d1 ) );
} else {
result.setCell( bounds[0], bounds[1], d1 );
}
d2 = result.getCell( bounds[2], bounds[1] );
if ( d2 != noDataValue ) {
result.setCell( bounds[2], bounds[1], Math.min( d2, d1 ) );
} else {
result.setCell( bounds[2], bounds[1], d1 );
}
}
}
}
*/
env.checkAndMaybeFreeMemory();
return r;
}
/**
* Returns a double[][] of grid values
*
* @param g The grid.
* @param row The row.
* @param cellDistance The cell distance.
* @return A double[][] of all cells within cellDistance.
* @throws java.lang.Exception If encountered.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
protected double[][] getRowProcessInitialData(Grids_GridDouble g,
int cellDistance, long row) throws IOException, Exception,
ClassNotFoundException {
int l = (cellDistance * 2) + 1;
double[][] r = new double[l][l];
for (long r2 = -cellDistance; r2 <= cellDistance; r2++) {
for (long c = -cellDistance; c <= cellDistance; c++) {
r[(int) r2 + cellDistance][(int) c + cellDistance]
= g.getCell(row + r2, c);
}
}
return r;
}
/**
* Returns a double[][] based on {@code previous} which has had the left
* most column removed and a new column added at the right.
*
* @param g The grid.
* @param col The column.
* @param previous The previous data.
* @param cellDistance The cell distance.
* @param row The row.
* @return A double[][] based on {@code previous} which has had the left
* most column removed and a new column added at the right.
*
* @throws java.lang.Exception If encountered.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
protected double[][] getRowProcessData(Grids_GridDouble g,
double[][] previous, int cellDistance, long row, long col)
throws IOException, Exception, ClassNotFoundException {
double[][] r = previous;
if (col == 0) {
return getRowProcessInitialData(g, cellDistance, row);
} else {
// shift columns one left
for (int i = 0; i <= cellDistance * 2; i++) {
for (int j = 0; j <= (cellDistance * 2) - 1; j++) {
r[i][j] = previous[i][j + 1];
}
}
// getLastColumn
for (int i = -cellDistance; i <= cellDistance; i++) {
r[i + cellDistance][cellDistance * 2]
= g.getCell((long) i + row, (long) col + cellDistance);
}
}
return r;
}
/**
* For outputting g in various formats.
*
* @param g The grid to output.
* @param outDir The output directory.
* @param ie The image exporter.
* @param imageTypes The image types.
* @param eage The ESRI AsciiGrid exporter.
* @throws java.lang.Exception If encountered.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
public void output(Grids_GridNumber g, Path outDir,
Grids_ImageExporter ie, String[] imageTypes,
Grids_ESRIAsciiGridExporter eage)
throws IOException, ClassNotFoundException, Exception {
System.out.println("Output " + g.toString());
if (ie == null) {
ie = new Grids_ImageExporter(env);
}
if (imageTypes == null) {
imageTypes = new String[1];
imageTypes[0] = "PNG";
}
if (eage == null) {
eage = new Grids_ESRIAsciiGridExporter(env);
}
//int _StringLength = 1000;
String dotASC = ".asc";
String noDataValue = "-9999.0";
String s;
Path file;
int i;
int l = imageTypes.length;
for (i = 0; i < l; i++) {
s = g.getName() + "." + imageTypes[i];
file = new Generic_Path(Paths.get(outDir.toString(), s));
ie.toGreyScaleImage(g, this, file, imageTypes[i]);
}
s = g.getName() + dotASC;
file = Paths.get(outDir.toString(), s);
eage.toAsciiFile(g, file, noDataValue);
}
/**
* @param g The grid to output.
* @param outDir The output directory.
* @param ie The image exporter.
* @param imageTypes The image types.
* @param hoome If {@code true} then an attempt to handle OutOfMemory Errors
* is made.
* @throws java.lang.Exception If encountered.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
public void outputImage(Grids_GridNumber g, Generic_Path outDir,
Grids_ImageExporter ie, String[] imageTypes, boolean hoome)
throws IOException, ClassNotFoundException, Exception {
try {
System.out.println("Output " + g.toString());
if (ie == null) {
ie = new Grids_ImageExporter(env);
}
if (imageTypes == null) {
imageTypes = new String[1];
imageTypes[0] = "PNG";
}
String string;
String string_DOT = ".";
Path file;
int i;
int l = imageTypes.length;
for (i = 0; i < l; i++) {
string = g.getName() + string_DOT + imageTypes[i];
file = Paths.get(outDir.toString(), string);
ie.toGreyScaleImage(g, this, file, imageTypes[i]);
}
} catch (OutOfMemoryError e) {
if (hoome) {
env.clearMemoryReserve(env.env);
if (env.swapChunksExcept_Account(g, hoome).detail < 1) {
throw e;
}
env.initMemoryReserve(env.env);
outputImage(g, outDir, ie, imageTypes, hoome);
} else {
throw e;
}
}
}
/**
* For outputting grid {@code g} in ESRIAsciiGrid format. NoDataValues is
* set to -9999.0,
*
* @param g The grid to output
* @param outDir The directory to output to.
* @param eage The exporter.
* @throws java.lang.Exception If encountered.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
public void outputESRIAsciiGrid(Grids_GridNumber g, Path outDir,
Grids_ESRIAsciiGridExporter eage) throws IOException,
ClassNotFoundException, Exception {
if (eage == null) {
eage = new Grids_ESRIAsciiGridExporter(env);
}
String ndv = "-9999.0";
String fn = g.getName() + ".asc";
Path file = Paths.get(outDir.toString(), fn);
eage.toAsciiFile(g, file, ndv);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy