package mil.nga.giat.geowave.core.geotime.index.dimension;
import mil.nga.giat.geowave.core.index.FloatCompareUtils;
import mil.nga.giat.geowave.core.index.dimension.BasicDimensionDefinition;
import mil.nga.giat.geowave.core.index.dimension.bin.BinRange;
import mil.nga.giat.geowave.core.index.sfc.data.NumericData;
/**
* The Longitude Definition class is a convenience class used to define a
* dimension which is associated with the X axis on a Cartesian plane.
*
* Minimum bounds = -180 and maximum bounds = 180
*
*/
public class LongitudeDefinition extends
BasicDimensionDefinition
{
/**
* Convenience constructor used to construct a longitude dimension object
* which sits on a Cartesian plane.
*
*/
public LongitudeDefinition() {
super(
-180,
180);
}
/**
* Method is used to normalize the ranges on a Cartesian plane. If the
* values are outside of the bounds [ -180, 180 ], two Bin ranges might be
* created to account for the possible date line crossing.
*
* @param range
* the numeric range of our data set
* @return new BinRange[] object
*/
@Override
public BinRange[] getNormalizedRanges(
final NumericData range ) {
// if the range is a single value, clamp at -180, 180
if (FloatCompareUtils.checkDoublesEqual(
range.getMin(),
range.getMax())) {
return super.getNormalizedRanges(range);
}
// if its a range, treat values outside of (-180,180) as possible date
// line crossing
final double normalizedMin = getNormalizedLongitude(range.getMin());
final double normalizedMax = getNormalizedLongitude(range.getMax());
// If the normalized max is less than normalized min, the range
// crosses the date line
if (normalizedMax < normalizedMin) {
return new BinRange[] {
new BinRange(
-180,
normalizedMax),
new BinRange(
normalizedMin,
180)
};
}
return new BinRange[] {
new BinRange(
normalizedMin,
normalizedMax)
};
}
/**
* Normalizes a longitude value
*
* @param lon
* value to normalize
* @return a normalized longitude value
*/
static public double getNormalizedLongitude(
final double lon ) {
if ((lon <= 180) && (lon >= -180)) {
return lon;
}
// the sign of the mod should be the sign of the dividend, but just in
// case guarantee a mod on a positive dividend and subtract 180
final double offsetLon = lon + 180;
return (((Math.ceil(Math.abs(offsetLon) / 360) * 360) + offsetLon) % 360) - 180;
}
@Override
public byte[] toBinary() {
// essentially all that is needed is the class name for reflection
return new byte[] {};
}
@Override
public void fromBinary(
final byte[] bytes ) {}
}