X-Git-Url: http://gitweb.fperrin.net/?p=GpsPrune.git;a=blobdiff_plain;f=src%2Ftim%2Fprune%2Fdata%2FAltitude.java;fp=src%2Ftim%2Fprune%2Fdata%2FAltitude.java;h=7d9c21cb6c414a5f4d16503e1f6bce0dbf215a73;hp=0000000000000000000000000000000000000000;hb=ce6f2161b8596f7018d6a76bff79bc9e571f35fd;hpb=2d8cb72e84d5cc1089ce77baf1e34ea3ea2f8465 diff --git a/src/tim/prune/data/Altitude.java b/src/tim/prune/data/Altitude.java new file mode 100644 index 0000000..7d9c21c --- /dev/null +++ b/src/tim/prune/data/Altitude.java @@ -0,0 +1,194 @@ +package tim.prune.data; + +/** + * Class to hold an altitude and provide conversion functions + */ +public class Altitude +{ + private boolean _valid = false; + private int _value = 0; + private Unit _unit = null; + private String _stringValue = null; + + /** Constant to use for a lack of altitude */ + public static final Altitude NONE = new Altitude(null, null); + + /** + * Constructor using String + * @param inString string to parse + * @param inUnit of altitude, either metres or feet + */ + public Altitude(String inString, Unit inUnit) + { + _unit = inUnit; + if (inString != null && !inString.equals("")) + { + try + { + _stringValue = inString; + _value = (int) Double.parseDouble(inString.trim()); + _valid = true; + } + catch (NumberFormatException nfe) {} + } + } + + + /** + * Constructor with int value + * @param inValue int value of altitude + * @param inUnit unit of altitude, either metres or feet + */ + public Altitude(int inValue, Unit inUnit) + { + _value = inValue; + _unit = inUnit; + _valid = true; + _stringValue = "" + inValue; + } + + /** + * @return an exact copy of this Altitude object + */ + public Altitude clone() + { + return new Altitude(_stringValue, _unit); + } + + /** + * Reset the altitude parameters to the same as the given object + * @param inClone clone object to copy + */ + public void reset(Altitude inClone) + { + _stringValue = inClone._stringValue; + _value = inClone._value; + _unit = inClone._unit; + _valid = inClone._valid; + } + + /** + * @return true if the value could be parsed + */ + public boolean isValid() + { + return _valid; + } + + + /** + * @return raw value as int + */ + public int getValue() + { + return _value; + } + + /** + * @param inAltUnit altitude units to use + * @return rounded value in specified units + */ + public int getValue(Unit inAltUnit) + { + if (inAltUnit == null) { + return getValue(); + } + return (int) (getMetricValue() * inAltUnit.getMultFactorFromStd()); + } + + /** + * @return unit of number + */ + public Unit getUnit() + { + return _unit; + } + + /** + * @return value of altitude in metres, used for calculations and charts + */ + public double getMetricValue() + { + if (_unit == UnitSetLibrary.UNITS_METRES || _unit == null) { + return _value; + } + return _value / _unit.getMultFactorFromStd(); + } + + /** + * Get a string version of the value + * @param inUnit specified unit + * @return string value, if possible the original one + */ + public String getStringValue(Unit inUnit) + { + if (!_valid) {return "";} + // Return string value if the same format or "no format" was requested + if ((inUnit == _unit || inUnit == null) + && _stringValue != null && !_stringValue.equals("")) { + return _stringValue; + } + return "" + getValue(inUnit); + } + + + /** + * Interpolate a new Altitude object between the given ones + * @param inStart start altitude + * @param inEnd end altitude + * @param inIndex index of interpolated point + * @param inNumSteps number of steps to interpolate + * @return Interpolated Altitude object + */ + public static Altitude interpolate(Altitude inStart, Altitude inEnd, int inIndex, int inNumSteps) + { + return interpolate(inStart, inEnd, 1.0 * (inIndex + 1) / (inNumSteps + 1)); + } + + + /** + * Interpolate a new Altitude object between the given ones + * @param inStart start altitude + * @param inEnd end altitude + * @param inFrac fraction of distance from first point + * @return Interpolated Altitude object + */ + public static Altitude interpolate(Altitude inStart, Altitude inEnd, double inFrac) + { + // Check if altitudes are valid + if (inStart == null || inEnd == null || !inStart.isValid() || !inEnd.isValid()) + return Altitude.NONE; + // Use altitude format of first point + Unit altUnit = inStart.getUnit(); + int startValue = inStart.getValue(); + int endValue = inEnd.getValue(altUnit); + // interpolate between start and end + int newValue = startValue + (int) ((endValue - startValue) * inFrac); + return new Altitude(newValue, altUnit); + } + + /** + * Add the given offset to the current altitude + * @param inOffset offset as double + * @param inUnit unit of offset, feet or metres + * @param inDecimals number of decimal places + */ + public void addOffset(double inOffset, Unit inUnit, int inDecimals) + { + // Use the maximum number of decimal places from current value and offset + int numDecimals = NumberUtils.getDecimalPlaces(_stringValue); + if (numDecimals < inDecimals) {numDecimals = inDecimals;} + // Convert offset to correct units + double offset = inOffset; + if (inUnit != _unit && inUnit != null) + { + offset = inOffset / inUnit.getMultFactorFromStd() * _unit.getMultFactorFromStd(); + } + // FIXME: The following will fail if _stringValue is null - not sure how it can get in that state! + if (_stringValue == null) System.err.println("*** Altitude.addOffset - how did the string value get to be null?"); + // Add the offset + double newValue = Double.parseDouble(_stringValue.trim()) + offset; + _value = (int) newValue; + _stringValue = NumberUtils.formatNumberUk(newValue, numDecimals); + } +}