/*
* * Copyright (C) 2011-2012 Dr. John Lindsay <jlindsay@uoguelph.ca>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package whitebox.geospatialfiles;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.nio.channels.FileChannel;
import whitebox.interfaces.MapLayer;
import whitebox.structures.BoundingBox;
/**
*
* @author Dr. John Lindsay <jlindsay@uoguelph.ca>
*/
public class RasterLayerInfo implements MapLayer {
private WhiteboxRasterInfo source = null;
private WhiteboxRasterInfo hillshadeSource = null;
private String paletteDirectory = null;
private double noDataValue = 0;
private int overlayNumber = 0;
private int rows, cols;
public boolean increasesEastward = false;
public boolean increasesNorthward = false;
private boolean dirty = true;
private String[] defaultPalettes;
private double[] data = null;
private boolean visibleInLegend = true;
/* Constructors*/
public RasterLayerInfo() {
}
public RasterLayerInfo(String headerFile, String paletteDirectory, String[] defaultPalettes, int alpha, int overlayNum) throws Exception {
// check to see that the file exists.
File file = new File(headerFile);
if (!file.exists()) {
System.out.println("File not found.");
}
this.headerFile = headerFile;
this.layerTitle = file.getName().replace(".dep", "");
source = new WhiteboxRasterInfo(headerFile);
this.paletteDirectory = paletteDirectory;
this.defaultPalettes = defaultPalettes.clone();
if (!source.getPreferredPalette().toLowerCase().equals("not specified")) {
this.paletteFile = paletteDirectory + source.getPreferredPalette();
// see if the palette exists. if not, give it one that does.
file = new File(this.paletteFile);
if (!file.exists()) {
if (null == source.getDataScale()) {
this.paletteFile = paletteDirectory + defaultPalettes[2];
} else {
switch (source.getDataScale()) {
case CONTINUOUS:
this.paletteFile = paletteDirectory + defaultPalettes[0];
break;
case CATEGORICAL:
case BOOLEAN:
this.paletteFile = paletteDirectory + defaultPalettes[1];
break;
default:
this.paletteFile = paletteDirectory + defaultPalettes[2];
break;
}
}
}
} else {
if (null == source.getDataScale()) {
this.paletteFile = paletteDirectory + defaultPalettes[2];
} else {
switch (source.getDataScale()) {
case CONTINUOUS:
this.paletteFile = paletteDirectory + defaultPalettes[0];
break;
case CATEGORICAL:
case BOOLEAN:
this.paletteFile = paletteDirectory + defaultPalettes[1];
break;
default:
this.paletteFile = paletteDirectory + defaultPalettes[2];
break;
}
}
}
this.imageWidth = source.getNumberColumns();
this.imageHeight = source.getNumberRows();
this.alpha = alpha;
this.noDataValue = source.getNoDataValue();
this.overlayNumber = overlayNum;
this.rows = source.getNumberRows();
this.cols = source.getNumberColumns();
this.setDataScale(source.getDataScale());
this.gamma = source.getNonlinearity();
minVal = source.getDisplayMinimum();
maxVal = source.getDisplayMaximum();
if (source.getEast() > source.getWest()) {
increasesEastward = true;
} else {
increasesEastward = false;
}
if (source.getNorth() > source.getSouth()) {
increasesNorthward = true;
} else {
increasesNorthward = false;
}
currentExtent = new BoundingBox(source.getWest(), source.getSouth(),
source.getEast(), source.getNorth());
fullExtent = currentExtent.clone();
}
public RasterLayerInfo(String headerFile, String paletteFile, int alpha,
int overlayNum) {
// check to see that the file exists.
File file = new File(headerFile);
if (!file.exists()) {
System.out.println("File not found.");
}
this.headerFile = headerFile;
this.layerTitle = file.getName().replace(".dep", "");
source = new WhiteboxRasterInfo(headerFile);
// see if the paletteDirectory has been set.
if ((null != paletteDirectory) && (paletteDirectory.length() == 0)) {
// do nothing
} else {
int a = paletteFile.lastIndexOf(File.separator);
paletteDirectory = paletteFile.substring(0, a + 1);
}
// if (paletteDirectory.isEmpty()) {
// int a = paletteFile.lastIndexOf(File.separator);
// paletteDirectory = paletteFile.substring(a);
// }
// see if the palette file exists
if (!(new File(paletteFile).exists())) {
paletteFile = paletteDirectory + "spectrum.pal";
}
this.paletteFile = paletteFile;
this.imageWidth = source.getNumberColumns();
this.imageHeight = source.getNumberRows();
this.alpha = alpha;
this.noDataValue = source.getNoDataValue();
this.overlayNumber = overlayNum;
this.rows = source.getNumberRows();
this.cols = source.getNumberColumns();
this.setDataScale(source.getDataScale());
minVal = source.getDisplayMinimum();
maxVal = source.getDisplayMaximum();
this.gamma = source.getNonlinearity();
if (source.getEast() > source.getWest()) {
increasesEastward = true;
} else {
increasesEastward = false;
}
if (source.getNorth() > source.getSouth()) {
increasesNorthward = true;
} else {
increasesNorthward = false;
}
currentExtent = new BoundingBox(source.getWest(), source.getSouth(),
source.getEast(), source.getNorth());
fullExtent = currentExtent.clone();
}
/* Property getters and setters */
private String headerFile = "";
public String getHeaderFile() {
return headerFile;
}
public int getRowFromYCoordinate(double y) {
return source.getRowFromYCoordinate(y);
}
public int getColFromXCoordinate(double x) {
return source.getRowFromYCoordinate(x);
}
public double getXCoordinateFromColumn(int col) {
return source.getXCoordinateFromColumn(col);
}
public double getYCoordinateFromRow(int row) {
return source.getYCoordinateFromRow(row);
}
public double getCellSizeX() {
return source.getCellSizeX();
}
public double getCellSizeY() {
return source.getCellSizeY();
}
private int alpha = 255;
public int getAlpha() {
return alpha;
}
public void setAlpha(int value) {
if (value < 0) {
value = 0;
}
if (value > 255) {
value = 255;
}
alpha = value;
}
private double gamma = 1.0;
public double getNonlinearity() {
return gamma;
}
public void setNonlinearity(double value) {
if (gamma != value) {
gamma = value;
source.setNonlinearity(value);
source.writeHeaderFile();
}
}
public String getHillshadeSource() {
if (this.hillshadeSource != null) {
return this.hillshadeSource.headerFile;
} else {
return "";
}
}
public void setHillshadeSource(String value) {
if (!value.isEmpty()) {
this.hillshadeSource = new WhiteboxRasterInfo(value);
} else {
this.hillshadeSource = null;
}
}
private String paletteFile = "";
public String getPaletteFile() {
return paletteFile;
}
public void setPaletteFile(String fileName) {
if (!paletteFile.equals(fileName)) {
paletteFile = fileName;
paletteData = null;
// update the header file
source.setPreferredPalette(fileName.replace(paletteDirectory, ""));
source.writeHeaderFile();
}
}
private int[] paletteData = null;
private int numPaletteEntries = 0;
public int[] getPaletteData() {
return paletteData;
}
public int getNumPaletteEntries() {
if (numPaletteEntries <= 0) {
readPalette();
}
return numPaletteEntries;
}
private int[] pixelData = null;
public int[] getPixelData() {
if (pixelData == null || pixelData.length == 0 || dirty) {
createPixelData();
}
return pixelData;
}
private int imageWidth = 0;
public int getImageWidth() {
return imageWidth;
}
private int imageHeight = 0;
public int getImageHeight() {
return imageHeight;
}
public int getNumberColumns() {
return cols;
}
public int getNumberRows() {
return rows;
}
public double getNoDataValue() {
return source.getNoDataValue();
}
private String XYUnits = "metres";
public String getXYUnits() {
return source.getXYUnits();
}
private String layerTitle = "";
@Override
public String getLayerTitle() {
return layerTitle;
}
@Override
public void setLayerTitle(String title) {
layerTitle = title;
}
@Override
public int getOverlayNumber() {
return overlayNumber;
}
@Override
public void setOverlayNumber(int num) {
overlayNumber = num;
}
private double minVal = 0;
public double getDisplayMinVal() {
return minVal;
}
public void setDisplayMinVal(double value) {
minVal = value;
source.setDisplayMinimum(value);
source.writeHeaderFile();
}
public double getMinVal() {
return source.getMinimumValue();
}
private double maxVal = 0;
public double getDisplayMaxVal() {
return maxVal;
}
public void setDisplayMaxVal(double value) {
maxVal = value;
source.setDisplayMaximum(value);
source.writeHeaderFile();
}
public double getMaxVal() {
return source.getMaximumValue();
}
private WhiteboxRaster.DataScale dataScale = WhiteboxRaster.DataScale.CONTINUOUS;
/**
* Retrieves the data scale for this Whitebox grid. Data scale may be
* <b><i>DATA_SCALE_CONTINUOUS</i></b> (0),
* <i><b>DATA_SCALE_CATEGORICAL</i></b> (1),
* <i><b>DATA_SCALE_BOOLEAN</i></b> (2), or <i><b>DATA_SCALE_RGB</i></b>
* (3).
*
* @return int Data scale.
*/
public WhiteboxRaster.DataScale getDataScale() {
return dataScale;
}
/**
* Sets the data scale for this Whitebox grid. Data scale may be
* <b><i>DATA_SCALE_CONTINUOUS</i></b> (0),
* <i><b>DATA_SCALE_CATEGORICAL</i></b> (1),
* <i><b>DATA_SCALE_BOOLEAN</i></b> (2), or <i><b>DATA_SCALE_RGB</i></b>
* (3).
*
* @param DataScale The specified data type.
*/
public final void setDataScale(WhiteboxRaster.DataScale DataScale) {
dataScale = DataScale;
source.setDataScale(dataScale);
source.writeHeaderFile();
}
public long getDataFileSize() {
return source.getDataFileSize();
}
private boolean paletteReversed = false;
public boolean isPaletteReversed() {
return paletteReversed;
}
public void setPaletteReversed(boolean value) {
if (value != paletteReversed) {
paletteReversed = value;
dirty = true;
if (paletteData == null) {
readPalette();
}
int[] copyPalette = new int[numPaletteEntries];
for (int i = 0; i < numPaletteEntries; i++) {
copyPalette[i] = paletteData[numPaletteEntries - i - 1];
}
paletteData = copyPalette.clone();
}
}
public BoundingBox fullExtent = null;
@Override
public BoundingBox getFullExtent() {
return fullExtent.clone();
}
BoundingBox currentExtent = null;
@Override
public BoundingBox getCurrentExtent() {
return currentExtent.clone();
}
@Override
public void setCurrentExtent(BoundingBox bb) {
if (!bb.equals(currentExtent) || generalizationLevelDirty) {
currentExtent = bb.clone();
dirty = true;
}
generalizationLevelDirty = false;
}
private int resolutionFactor = 1;
public void setResolutionFactor(int value) {
if (value < 1) {
value = 1;
}
if (value != resolutionFactor) {
resolutionFactor = value;
dirty = true;
}
}
private double cartographicGeneralizationLevel = 10;
public double getCartographicGeneralizationLevel() {
return cartographicGeneralizationLevel;
}
boolean generalizationLevelDirty = false;
public void setCartographicGeneralizationLevel(double generalizeLevel) {
cartographicGeneralizationLevel = generalizeLevel;
if (cartographicGeneralizationLevel < 1) {
cartographicGeneralizationLevel = 1;
}
generalizationLevelDirty = true;
}
public double getDataValue(int row, int col) {
int r = (int) (((double) row - startRow) / (endRow - startRow) * (imageHeight - 1) + 0.5);
int c = (int) (((double) col - startCol) / (endCol - startCol) * (imageWidth - 1) + 0.5);
int cellNum = (int) (r * imageWidth + c);
if (cellNum > data.length) {
return Double.NaN;
}
return data[cellNum];
}
/**
* Accesses WhiteboxRasterBase's setPixelValue method. This is a lightweight
* method of setting individual pixel values. It writes values directly to
* the file without the use of a buffer. As such it is only useful for
* setting small numbers of pixels. The setValue method of the
* WhiteboxRaster class offers a buffered means of setting individual pixel
* values and is far better suited to setting larger numbers of pixels. This
* method should only be used for existing files.
*
* @param row Pixel zero-based row number.
* @param column Pixel zero-based column number.
* @param value Pixel value to set.
*/
public void setDataValue(int row, int column, double value) {
source.setPixelValue(row, column, value);
}
public boolean isDirty() {
return dirty;
}
public void setDirty(boolean dirty) {
this.dirty = dirty;
}
public WhiteboxRasterInfo getWhiteboxRasterInfo() {
return source;
}
public void resyncWithRasterFile() {
source = new WhiteboxRasterInfo(headerFile);
this.imageWidth = source.getNumberColumns();
this.imageHeight = source.getNumberRows();
this.noDataValue = source.getNoDataValue();
this.rows = source.getNumberRows();
this.cols = source.getNumberColumns();
this.setDataScale(source.getDataScale());
minVal = source.getDisplayMinimum();
maxVal = source.getDisplayMaximum();
if (source.getEast() > source.getWest()) {
increasesEastward = true;
} else {
increasesEastward = false;
}
if (source.getNorth() > source.getSouth()) {
increasesNorthward = true;
} else {
increasesNorthward = false;
}
fullExtent = currentExtent.clone();
update();
}
int startRow;
int endRow;
int startCol;
int endCol;
public void createPixelData() {
try {
if ((paletteData == null) && (dataScale != WhiteboxRaster.DataScale.RGB)) {
readPalette();
}
startRow = (int) (Math.abs(fullExtent.getMaxY() - currentExtent.getMaxY()) / source.getCellSizeY());
endRow = (int) (rows - (Math.abs(fullExtent.getMinY() - currentExtent.getMinY()) / source.getCellSizeY())) - 1;
startCol = (int) (Math.abs(fullExtent.getMinX() - currentExtent.getMinX()) / source.getCellSizeX());
endCol = (int) (cols - (Math.abs(fullExtent.getMaxX() - currentExtent.getMaxX()) / source.getCellSizeX())) - 1;
int row, col;
double range = maxVal - minVal;
double value = 0;
int entryNum = 0;
// check the numCells
imageHeight = 0;
imageWidth = 0;
for (row = startRow; row <= endRow; row += resolutionFactor) {
imageHeight++;
}
for (col = startCol; col <= endCol; col += resolutionFactor) {
imageWidth++;
}
int numCells = imageHeight * imageWidth;
// WhiteboxRasterInfo sourceData = new WhiteboxRasterInfo(source.getHeaderFile());
int backgroundColour = 0; // transparent black
pixelData = new int[numCells];
data = new double[numCells];
//data = new double[1];
int numPaletteEntriesLessOne = numPaletteEntries - 1;
//long startTime = System.currentTimeMillis();
double[] rawData;
int i = 0;
if (null != dataScale) {
switch (dataScale) {
case CONTINUOUS:
if (hillshadeSource == null) {
for (row = startRow; row <= endRow; row += resolutionFactor) {
rawData = source.getRowValues(row); //sourceData.getRowValues(row);
for (col = startCol; col <= endCol; col += resolutionFactor) {
value = rawData[col]; //sourceData.getValue(row, col);
if (value != noDataValue) {
if (gamma == 1) {
entryNum = (int) ((value - minVal) / range * numPaletteEntriesLessOne);
} else {
entryNum = (int) (Math.pow(((value - minVal) / range), gamma) * numPaletteEntriesLessOne);
}
if (entryNum < 0) {
entryNum = 0;
}
if (entryNum > numPaletteEntriesLessOne) {
entryNum = numPaletteEntriesLessOne;
}
pixelData[i] = paletteData[entryNum];
} else {
pixelData[i] = backgroundColour;
}
data[i] = value;
i++;
}
}
} else { // render with hillshade
double[] hsData;
double hsMin = hillshadeSource.getDisplayMinimum();
double hsRange = hillshadeSource.getDisplayMaximum() - hsMin;
double hsNodata = hillshadeSource.getNoDataValue();
double hsValue;
int r, g, b, a, val;
for (row = startRow; row <= endRow; row += resolutionFactor) {
rawData = source.getRowValues(row); //sourceData.getRowValues(row);
hsData = hillshadeSource.getRowValues(row);
for (col = startCol; col <= endCol; col += resolutionFactor) {
value = rawData[col]; //sourceData.getValue(row, col);
hsValue = (hsData[col] - hsMin) / hsRange + 0.33;
if (hsValue < 0d) {
hsValue = 0d;
}
if (hsValue > 1d) {
hsValue = 1d;
}
if (value != noDataValue && hsData[col] != hsNodata) {
if (gamma == 1) {
entryNum = (int) ((value - minVal) / range * numPaletteEntriesLessOne);
} else {
entryNum = (int) (Math.pow(((value - minVal) / range), gamma) * numPaletteEntriesLessOne);
}
if (entryNum < 0) {
entryNum = 0;
}
if (entryNum > numPaletteEntriesLessOne) {
entryNum = numPaletteEntriesLessOne;
}
val = paletteData[entryNum];
a = ((val >> 24) & 0xFF);
r = (int) (((val >> 16) & 0xFF) * hsValue);
g = (int) (((val >> 8) & 0xFF) * hsValue);
b = (int) ((val & 0xFF) * hsValue);
pixelData[i] = (a << 24) | (r << 16) | (g << 8) | b;
} else {
pixelData[i] = backgroundColour;
}
data[i] = value;
i++;
}
}
}
break;
case CATEGORICAL:
if (hillshadeSource == null) {
for (row = startRow; row <= endRow; row += resolutionFactor) {
rawData = source.getRowValues(row); //sourceData.getRowValues(row);
for (col = startCol; col <= endCol; col += resolutionFactor) {
value = rawData[col]; //sourceData.getValue(row, col);
if (value != noDataValue) {
entryNum = (int) (value - minVal) % numPaletteEntries;
if (entryNum < 0) {
entryNum = 0;
}
if (entryNum > numPaletteEntriesLessOne) {
entryNum = numPaletteEntriesLessOne;
}
pixelData[i] = paletteData[entryNum];
} else {
pixelData[i] = backgroundColour;
}
data[i] = value;
i++;
}
}
} else { // render with hillshade
double[] hsData;
double hsMin = hillshadeSource.getDisplayMinimum();
double hsRange = hillshadeSource.getDisplayMaximum() - hsMin;
double hsValue;
double hsNodata = hillshadeSource.getNoDataValue();
int r, g, b, a, val;
for (row = startRow; row <= endRow; row += resolutionFactor) {
rawData = source.getRowValues(row); //sourceData.getRowValues(row);
hsData = hillshadeSource.getRowValues(row);
for (col = startCol; col <= endCol; col += resolutionFactor) {
value = rawData[col]; //sourceData.getValue(row, col);
hsValue = (hsData[col] - hsMin) / hsRange + 0.33;
if (hsValue < 0.25) {
hsValue = 0.25;
}
if (hsValue > 1.0) {
hsValue = 1.0;
}
if (value != noDataValue && hsData[col] != hsNodata) {
entryNum = (int) (value - minVal) % numPaletteEntries;
if (entryNum < 0) {
entryNum = 0;
}
if (entryNum > numPaletteEntriesLessOne) {
entryNum = numPaletteEntriesLessOne;
}
val = paletteData[entryNum];
a = ((val >> 24) & 0xFF);
r = (int) (((val >> 16) & 0xFF) * hsValue);
g = (int) (((val >> 8) & 0xFF) * hsValue);
b = (int) ((val & 0xFF) * hsValue);
pixelData[i] = (a << 24) | (r << 16) | (g << 8) | b;
} else {
pixelData[i] = backgroundColour;
}
data[i] = value;
i++;
}
}
}
break;
case BOOLEAN:
if (hillshadeSource == null) {
for (row = startRow; row <= endRow; row += resolutionFactor) {
rawData = source.getRowValues(row); //sourceData.getRowValues(row);
for (col = startCol; col <= endCol; col += resolutionFactor) {
value = rawData[col]; //sourceData.getValue(row, col);
if (value != noDataValue) {
if (value > 0) {
entryNum = numPaletteEntriesLessOne;
} else {
entryNum = 0;
}
pixelData[i] = paletteData[entryNum];
} else {
pixelData[i] = backgroundColour;
}
data[i] = value;
i++;
}
}
} else { // render with hillshade
double[] hsData;
double hsMin = hillshadeSource.getDisplayMinimum();
double hsRange = hillshadeSource.getDisplayMaximum() - hsMin;
double hsNodata = hillshadeSource.getNoDataValue();
double hsValue;
int r, g, b, a, val;
for (row = startRow; row <= endRow; row += resolutionFactor) {
rawData = source.getRowValues(row); //sourceData.getRowValues(row);
hsData = hillshadeSource.getRowValues(row);
for (col = startCol; col <= endCol; col += resolutionFactor) {
value = rawData[col]; //sourceData.getValue(row, col);
hsValue = (hsData[col] - hsMin) / hsRange + 0.33;
if (hsValue < 0.25) {
hsValue = 0.25;
}
if (hsValue > 1.0) {
hsValue = 1.0;
}
if (value != noDataValue && hsData[col] != hsNodata) {
if (value > 0) {
entryNum = numPaletteEntriesLessOne;
} else {
entryNum = 0;
}
val = paletteData[entryNum];
a = ((val >> 24) & 0xFF);
r = (int) (((val >> 16) & 0xFF) * hsValue);
g = (int) (((val >> 8) & 0xFF) * hsValue);
b = (int) ((val & 0xFF) * hsValue);
pixelData[i] = (a << 24) | (r << 16) | (g << 8) | b;
} else {
pixelData[i] = backgroundColour;
}
data[i] = value;
i++;
}
}
}
break;
case RGB:
int r,
g,
b,
a,
val;
for (row = startRow; row <= endRow; row += resolutionFactor) {
rawData = source.getRowValues(row); //sourceData.getRowValues(row);
for (col = startCol; col <= endCol; col += resolutionFactor) {
value = rawData[col]; //sourceData.getValue(row, col);
if (value != noDataValue) {
val = (int) value;
a = (val >> 24) & 0xFF;
a = (int) (a * alpha / 255d);
b = (val >> 16) & 0xFF;
g = (val >> 8) & 0xFF;
r = val & 0xFF;
pixelData[i] = (a << 24) | (r << 16) | (g << 8) | b;
} else {
pixelData[i] = backgroundColour;
}
data[i] = value;
i++;
}
}
break;
default:
break;
}
}
// sourceData.close();
// sourceData = null;
dirty = false;
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
private void readPalette() {
RandomAccessFile rIn = null;
ByteBuffer buf = null;
int i;
try {
// see if the file exists, if not, set it to the default palette.
File file = new File(paletteFile);
if (!file.exists()) {
if (null == source.getDataScale()) {
this.paletteFile = paletteDirectory + defaultPalettes[3];
} else {
switch (source.getDataScale()) {
case CONTINUOUS:
this.paletteFile = paletteDirectory + defaultPalettes[0];
break;
case CATEGORICAL:
case BOOLEAN:
this.paletteFile = paletteDirectory + defaultPalettes[1];
break;
default:
this.paletteFile = paletteDirectory + defaultPalettes[3];
break;
}
}
}
numPaletteEntries = (int) (file.length() / 4);
buf = ByteBuffer.allocate(numPaletteEntries * 4);
rIn = new RandomAccessFile(paletteFile, "r");
FileChannel inChannel = rIn.getChannel();
inChannel.position(0);
inChannel.read(buf);
// Check the byte order.
buf.order(ByteOrder.LITTLE_ENDIAN);
// Read the data.
buf.rewind();
IntBuffer ib = buf.asIntBuffer();
paletteData = new int[numPaletteEntries];
ib.get(paletteData);
ib = null;
// Update the palette for the alpha value.
if (alpha < 255) {
int r, g, b, val;
for (i = 0; i < numPaletteEntries; i++) {
val = paletteData[i];
r = (val >> 16) & 0xFF;
g = (val >> 8) & 0xFF;
b = val & 0xFF;
paletteData[i] = (alpha << 24) | (r << 16) | (g << 8) | b;
}
}
if (paletteReversed) {
int[] copyPalette = new int[numPaletteEntries];
for (i = 0; i < numPaletteEntries; i++) {
copyPalette[i] = paletteData[numPaletteEntries - i - 1];
}
paletteData = copyPalette.clone();
}
} catch (Exception e) {
System.err.println("Caught exception: " + e.toString());
System.err.println(e.getStackTrace());
} finally {
if (rIn != null) {
try {
rIn.close();
} catch (Exception e) {
}
}
}
}
public double clipLowerTail(double percent) {
return source.getPercentileValue(percent);
}
public double clipUpperTail(double percent) {
return source.getPercentileValue(100 - percent);
}
public void update() {
readPalette();
createPixelData();
}
public void clipLayerToExtent(BoundingBox extent, String outputFileName) {
String str1 = null;
FileWriter fw = null;
BufferedWriter bw = null;
PrintWriter out = null;
try {
// Do the two extents overlap?
boolean cond1, cond2, cond3, cond4;
if (fullExtent.getMinY() < fullExtent.getMaxY()) { // y-axis increases upwards
cond1 = (extent.getMaxY() < fullExtent.getMinY());
cond2 = (extent.getMinY() > fullExtent.getMaxY());
} else { // y-axis increases downwards
cond1 = (extent.getMaxY() > fullExtent.getMinY());
cond2 = (extent.getMinY() < fullExtent.getMaxY());
}
if (fullExtent.getMinX() < fullExtent.getMaxX()) { // x-axis increases to right
cond3 = (extent.getMinX() > fullExtent.getMaxX());
cond4 = (extent.getMaxX() < fullExtent.getMinX());
} else { // x-axis increases to left
cond3 = (extent.getMinX() < fullExtent.getMaxX());
cond4 = (extent.getMaxX() > fullExtent.getMinX());
}
if (!cond1 && !cond2 && !cond3 && !cond4) {
// Find the box of intersection between extent and fullExtent.
// And, what is the range of rows and columns in the source image to read?
double top, bottom, left, right;
int fromRow, toRow, fromCol, toCol;
if (fullExtent.getMinY() < fullExtent.getMaxY()) {
top = Math.min(extent.getMaxY(), fullExtent.getMaxY());
bottom = Math.max(extent.getMinY(), fullExtent.getMinY());
} else {
top = Math.max(extent.getMaxY(), fullExtent.getMaxY());
bottom = Math.min(extent.getMinY(), fullExtent.getMinY());
}
if (fullExtent.getMinX() < fullExtent.getMaxX()) {
left = Math.max(extent.getMinX(), fullExtent.getMinX());
right = Math.min(extent.getMaxX(), fullExtent.getMaxX());
} else {
left = Math.min(extent.getMinX(), fullExtent.getMinX());
right = Math.max(extent.getMaxX(), fullExtent.getMaxX());
}
fromRow = (int) ((fullExtent.getMaxY() - top) / (fullExtent.getMaxY() - fullExtent.getMinY()) * (rows - 0.5));
toRow = (int) ((fullExtent.getMaxY() - bottom) / (fullExtent.getMaxY() - fullExtent.getMinY()) * (rows - 0.5));
fromCol = (int) ((left - fullExtent.getMinX()) / (fullExtent.getMaxX() - fullExtent.getMinX()) * (cols - 0.5));
toCol = (int) ((right - fullExtent.getMinX()) / (fullExtent.getMaxX() - fullExtent.getMinX()) * (cols - 0.5));
if (fromRow > toRow) {
int i = fromRow;
fromRow = toRow;
toRow = i;
}
if (fromCol > toCol) {
int i = fromCol;
fromCol = toCol;
toCol = i;
}
// recalculate top, bottom, left and right to align with the row/col coordinates
double gridResY = source.getCellSizeY();
double gridResX = source.getCellSizeX();
top = fullExtent.getMaxY() - fromRow * gridResY;
bottom = fullExtent.getMaxY() - (toRow + 1) * gridResY;
left = fullExtent.getMinX() + fromCol * gridResX;
right = fullExtent.getMinX() + (toCol + 1) * gridResX;
int nRows = toRow - fromRow + 1;
int nCols = toCol - fromCol + 1;
// see if the outputFileName already exists, and if so delete it
if (new File(outputFileName).exists()) {
new File(outputFileName).delete();
new File(outputFileName.replace(".dep", ".tas")).delete();
}
String dataType = "float";
switch (source.getDataType()) {
case DOUBLE:
dataType = "double";
break;
case FLOAT:
dataType = "float";
break;
case INTEGER:
dataType = "integer";
break;
case BYTE:
dataType = "byte";
break;
}
String dataScale = "continuous";
switch (source.getDataScale()) {
case CONTINUOUS:
dataScale = "continuous";
break;
case CATEGORICAL:
dataScale = "categorical";
break;
case BOOLEAN:
dataScale = "boolean";
break;
case RGB:
dataScale = "rgb";
break;
}
// write the header file for the new raster
fw = new FileWriter(outputFileName, false);
bw = new BufferedWriter(fw);
out = new PrintWriter(bw, true);
str1 = "Min:\t" + Double.toString(Integer.MAX_VALUE);
out.println(str1);
str1 = "Max:\t" + Double.toString(Integer.MIN_VALUE);
out.println(str1);
str1 = "North:\t" + Double.toString(top);
out.println(str1);
str1 = "South:\t" + Double.toString(bottom);
out.println(str1);
str1 = "East:\t" + Double.toString(right);
out.println(str1);
str1 = "West:\t" + Double.toString(left);
out.println(str1);
str1 = "Cols:\t" + Integer.toString(nCols);
out.println(str1);
str1 = "Rows:\t" + Integer.toString(nRows);
out.println(str1);
str1 = "Data Type:\t" + dataType;
out.println(str1);
str1 = "Z Units:\t" + source.getZUnits();
out.println(str1);
str1 = "XY Units:\t" + source.getXYUnits();
out.println(str1);
str1 = "Projection:\t" + source.getProjection();
out.println(str1);
str1 = "Data Scale:\t" + dataScale;
out.println(str1);
str1 = "Preferred Palette:\t" + source.getPreferredPalette();
out.println(str1);
str1 = "NoData:\t" + source.getNoDataValue();
out.println(str1);
if (java.nio.ByteOrder.nativeOrder() == java.nio.ByteOrder.LITTLE_ENDIAN) {
str1 = "Byte Order:\t" + "LITTLE_ENDIAN";
} else {
str1 = "Byte Order:\t" + "BIG_ENDIAN";
}
out.println(str1);
// Create the whitebox raster object.
WhiteboxRaster wbr = new WhiteboxRaster(outputFileName, "rw");
double[] rowData = null;
int row, col;
for (row = fromRow; row <= toRow; row++) {
if (row >= 0 && row < rows) {
rowData = source.getRowValues(row);
for (col = fromCol; col <= toCol; col++) {
wbr.setValue(row - fromRow, col - fromCol, rowData[col]);
}
}
}
wbr.findMinAndMaxVals();
wbr.close();
//
} else {
// the two extents don't overlap.
}
} catch (java.io.IOException e) {
System.err.println("Error: " + e.getMessage());
return;
} catch (Exception e) {
} finally {
if (out != null || bw != null) {
out.flush();
out.close();
}
}
}
@Override
public MapLayer.MapLayerType getLayerType() {
return MapLayer.MapLayerType.RASTER;
}
private boolean visible = true;
@Override
public boolean isVisible() {
return visible;
}
@Override
public void setVisible(boolean value) {
visible = value;
}
@Override
public boolean isVisibleInLegend() {
return visibleInLegend;
}
@Override
public void setVisibleInLegend(boolean value) {
this.visibleInLegend = value;
}
// private boolean importGeoTiff(String fileName) {
// try {
// final GeoTiff gt = new GeoTiff(fileName);
//
// gt.read();
// int compressionType = gt.getCompressionType();
// if (compressionType != 1) {
// if (host != null) {
// host.showFeedback("GeoTiff import does not currently support compressed file types.");
// return false;
// }
// }
// final int nRows = gt.getNumberRows();
// final int nCols = gt.getNumberColumns();
// boolean hasNoDataValue = gt.hasNoDataTag();
// double nodata; // = -32768.0;
// if (hasNoDataValue) {
// nodata = gt.getNoData();
// } else {
// nodata = -32768;
// }
//
// String whiteboxHeaderFile = fileName.replace(".tif", ".dep");
// String whiteboxDataFile = fileName.replace(".tif", ".tas");
//
// File file = new File(whiteboxHeaderFile);
// // see if the file exists already, and if so, should it be overwritten?
// if (file.exists() && host != null) {
// int n = host.showFeedback("You are importing a GeoTIFF file by converting it to "
// + "a Whitebox Raster format. \nThe Whitebox Raster file already exists. "
// + "Would you like to overwrite it?", JOptionPane.YES_NO_OPTION,
// JOptionPane.QUESTION_MESSAGE);
//
// if (n == JOptionPane.YES_OPTION) {
// file.delete();
// new File(whiteboxDataFile).delete();
// } else if (n == JOptionPane.NO_OPTION) {
// return false;
// }
// } else if (file.exists()) {
// host.showFeedback("You are importing a GeoTIFF file by converting it to \n"
// + "a Whitebox Raster format. The newly created Whitebox \n"
// + "Raster will be added to the map.");
// file.delete();
// new File(whiteboxDataFile).delete();
// } else {
// host.showFeedback("You are importing a GeoTIFF file by converting it to \n"
// + "a Whitebox Raster format. The newly created Whitebox \n"
// + "Raster will be added to the map.");
// }
//
// ByteOrder byteOrder = gt.getByteOrder();
//
// WhiteboxRasterBase.DataScale myDataScale = WhiteboxRasterBase.DataScale.CONTINUOUS;
// if (gt.getPhotometricInterpretation() == 2) {
// myDataScale = WhiteboxRasterBase.DataScale.RGB;
// }
// final WhiteboxRaster wbr = new WhiteboxRaster(whiteboxHeaderFile, gt.getNorth(), gt.getSouth(), gt.getEast(),
// gt.getWest(), nRows, nCols, myDataScale,
// WhiteboxRasterBase.DataType.FLOAT, nodata, nodata);
//
// wbr.setByteOrder(byteOrder.toString());
//
// double z;
//// int oldProgress = -1;
//// int progress;
// for (int row = 0; row < nRows; row++) {
// for (int col = 0; col < nCols; col++) {
// z = gt.getValue(row, col);
// if (!hasNoDataValue && (z == -32768 || z == -Float.MAX_VALUE)) {
// nodata = z;
// hasNoDataValue = true;
// wbr.setNoDataValue(nodata);
// }
// //if (z != nodata) {
// wbr.setValue(row, col, z);
// //}
// }
//// progress = (int)(100f * row / (nRows - 1));
//// if (progress != oldProgress) {
//// oldProgress = progress;
//// if (host != null) {
//// host.updateProgress("Importing file...", progress);
//// }
//// }
// }
// wbr.close();
//
// return true;
// } catch (Exception e) {
// if (host != null) {
// host.showFeedback("There was an error import the GeoTiff file.");
// host.logException("Error in RasterLayerInfo.importGeoTiff:", e);
// }
// return false;
// }
// }
}