]> gitweb.fperrin.net Git - GpsPrune.git/blob - src/tim/prune/data/Altitude.java
7d9c21cb6c414a5f4d16503e1f6bce0dbf215a73
[GpsPrune.git] / src / tim / prune / data / Altitude.java
1 package tim.prune.data;
2
3 /**
4  * Class to hold an altitude and provide conversion functions
5  */
6 public class Altitude
7 {
8         private boolean _valid = false;
9         private int _value = 0;
10         private Unit _unit = null;
11         private String _stringValue = null;
12
13         /** Constant to use for a lack of altitude */
14         public static final Altitude NONE = new Altitude(null, null);
15
16         /**
17          * Constructor using String
18          * @param inString string to parse
19          * @param inUnit of altitude, either metres or feet
20          */
21         public Altitude(String inString, Unit inUnit)
22         {
23                 _unit = inUnit;
24                 if (inString != null && !inString.equals(""))
25                 {
26                         try
27                         {
28                                 _stringValue = inString;
29                                 _value = (int) Double.parseDouble(inString.trim());
30                                 _valid = true;
31                         }
32                         catch (NumberFormatException nfe) {}
33                 }
34         }
35
36
37         /**
38          * Constructor with int value
39          * @param inValue int value of altitude
40          * @param inUnit unit of altitude, either metres or feet
41          */
42         public Altitude(int inValue, Unit inUnit)
43         {
44                 _value = inValue;
45                 _unit = inUnit;
46                 _valid = true;
47                 _stringValue = "" + inValue;
48         }
49
50         /**
51          * @return an exact copy of this Altitude object
52          */
53         public Altitude clone()
54         {
55                 return new Altitude(_stringValue, _unit);
56         }
57
58         /**
59          * Reset the altitude parameters to the same as the given object
60          * @param inClone clone object to copy
61          */
62         public void reset(Altitude inClone)
63         {
64                 _stringValue = inClone._stringValue;
65                 _value = inClone._value;
66                 _unit = inClone._unit;
67                 _valid = inClone._valid;
68         }
69
70         /**
71          * @return true if the value could be parsed
72          */
73         public boolean isValid()
74         {
75                 return _valid;
76         }
77
78
79         /**
80          * @return raw value as int
81          */
82         public int getValue()
83         {
84                 return _value;
85         }
86
87         /**
88          * @param inAltUnit altitude units to use
89          * @return rounded value in specified units
90          */
91         public int getValue(Unit inAltUnit)
92         {
93                 if (inAltUnit == null) {
94                         return getValue();
95                 }
96                 return (int) (getMetricValue() * inAltUnit.getMultFactorFromStd());
97         }
98
99         /**
100          * @return unit of number
101          */
102         public Unit getUnit()
103         {
104                 return _unit;
105         }
106
107         /**
108          * @return value of altitude in metres, used for calculations and charts
109          */
110         public double getMetricValue()
111         {
112                 if (_unit == UnitSetLibrary.UNITS_METRES || _unit == null) {
113                         return _value;
114                 }
115                 return _value / _unit.getMultFactorFromStd();
116         }
117
118         /**
119          * Get a string version of the value
120          * @param inUnit specified unit
121          * @return string value, if possible the original one
122          */
123         public String getStringValue(Unit inUnit)
124         {
125                 if (!_valid) {return "";}
126                 // Return string value if the same format or "no format" was requested
127                 if ((inUnit == _unit || inUnit == null)
128                  && _stringValue != null && !_stringValue.equals("")) {
129                         return _stringValue;
130                 }
131                 return "" + getValue(inUnit);
132         }
133
134
135         /**
136          * Interpolate a new Altitude object between the given ones
137          * @param inStart start altitude
138          * @param inEnd end altitude
139          * @param inIndex index of interpolated point
140          * @param inNumSteps number of steps to interpolate
141          * @return Interpolated Altitude object
142          */
143         public static Altitude interpolate(Altitude inStart, Altitude inEnd, int inIndex, int inNumSteps)
144         {
145                 return interpolate(inStart, inEnd, 1.0 * (inIndex + 1) / (inNumSteps + 1));
146         }
147
148
149         /**
150          * Interpolate a new Altitude object between the given ones
151          * @param inStart start altitude
152          * @param inEnd end altitude
153          * @param inFrac fraction of distance from first point
154          * @return Interpolated Altitude object
155          */
156         public static Altitude interpolate(Altitude inStart, Altitude inEnd, double inFrac)
157         {
158                 // Check if altitudes are valid
159                 if (inStart == null || inEnd == null || !inStart.isValid() || !inEnd.isValid())
160                         return Altitude.NONE;
161                 // Use altitude format of first point
162                 Unit altUnit = inStart.getUnit();
163                 int startValue = inStart.getValue();
164                 int endValue = inEnd.getValue(altUnit);
165                 // interpolate between start and end
166                 int newValue = startValue + (int) ((endValue - startValue) * inFrac);
167                 return new Altitude(newValue, altUnit);
168         }
169
170         /**
171          * Add the given offset to the current altitude
172          * @param inOffset offset as double
173          * @param inUnit unit of offset, feet or metres
174          * @param inDecimals number of decimal places
175          */
176         public void addOffset(double inOffset, Unit inUnit, int inDecimals)
177         {
178                 // Use the maximum number of decimal places from current value and offset
179                 int numDecimals = NumberUtils.getDecimalPlaces(_stringValue);
180                 if (numDecimals < inDecimals) {numDecimals = inDecimals;}
181                 // Convert offset to correct units
182                 double offset = inOffset;
183                 if (inUnit != _unit && inUnit != null)
184                 {
185                         offset = inOffset / inUnit.getMultFactorFromStd() * _unit.getMultFactorFromStd();
186                 }
187                 // FIXME: The following will fail if _stringValue is null - not sure how it can get in that state!
188                 if (_stringValue == null) System.err.println("*** Altitude.addOffset - how did the string value get to be null?");
189                 // Add the offset
190                 double newValue = Double.parseDouble(_stringValue.trim()) + offset;
191                 _value = (int) newValue;
192                 _stringValue = NumberUtils.formatNumberUk(newValue, numDecimals);
193         }
194 }