package mil.nga.giat.geowave.core.index.dimension;
import java.nio.ByteBuffer;
import mil.nga.giat.geowave.core.index.dimension.bin.BinRange;
import mil.nga.giat.geowave.core.index.sfc.data.NumericData;
import mil.nga.giat.geowave.core.index.sfc.data.NumericRange;
/**
* The Basic Dimension Definition class defines a Space Filling Curve dimension
* as a minimum and maximum range with values linearly interpolated within the
* range. Values outside of the range will be clamped within the range.
*
*/
public class BasicDimensionDefinition implements
NumericDimensionDefinition
{
protected double min;
protected double max;
protected BasicDimensionDefinition() {}
/**
* Constructor which defines and enforces the bounds of a numeric dimension
* definition.
*
* @param min
* the minimum bounds of the dimension
* @param max
* the maximum bounds of the dimension
*/
public BasicDimensionDefinition(
final double min,
final double max ) {
this.min = min;
this.max = max;
}
@Override
public double normalize(
double value ) {
value = clamp(value);
return ((value - min) / (max - min));
}
@Override
public BinRange[] getNormalizedRanges(
final NumericData range ) {
return new BinRange[] {
new BinRange(
// by default clamp to the min and max
clamp(range.getMin()),
clamp(range.getMax()))
};
}
@Override
public NumericData getFullRange() {
return new NumericRange(
min,
max);
}
protected double clamp(
final double x ) {
return clamp(
x,
min,
max);
}
protected static double clamp(
final double x,
final double min,
final double max ) {
if (x < min) {
return min;
}
if (x > max) {
return max;
}
return x;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
final String className = getClass().getName();
result = (prime * result) + ((className == null) ? 0 : className.hashCode());
long temp;
temp = Double.doubleToLongBits(max);
result = (prime * result) + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(min);
result = (prime * result) + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(
final Object obj ) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final BasicDimensionDefinition other = (BasicDimensionDefinition) obj;
if (Double.doubleToLongBits(max) != Double.doubleToLongBits(other.max)) {
return false;
}
if (Double.doubleToLongBits(min) != Double.doubleToLongBits(other.min)) {
return false;
}
return true;
}
@Override
public byte[] toBinary() {
final ByteBuffer buf = ByteBuffer.allocate(16);
buf.putDouble(min);
buf.putDouble(max);
return buf.array();
}
@Override
public void fromBinary(
final byte[] bytes ) {
final ByteBuffer buf = ByteBuffer.wrap(bytes);
min = buf.getDouble();
max = buf.getDouble();
}
@Override
public double denormalize(
double value ) {
if ((value < 0) || (value > 1)) {
value = clamp(
value,
0,
1);
}
return (value * (max - min)) + min;
}
@Override
public NumericRange getDenormalizedRange(
final BinRange range ) {
return new NumericRange(
range.getNormalizedMin(),
range.getNormalizedMax());
}
@Override
public int getFixedBinIdSize() {
return 0;
}
@Override
public double getRange() {
return max - min;
}
@Override
public NumericRange getBounds() {
return new NumericRange(
min,
max);
}
}