]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/data/Altitude.java
06a32911197fc3e0560e81c45ac042bb5a080ed3
[GpsPrune.git] / 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 Format _format = Format.NO_FORMAT;
11         private String _stringValue = null;
12
13         /** Altitude formats */
14         public enum Format {
15                 /** No format */
16                 NO_FORMAT,
17                 /** Metres */
18                 METRES,
19                 /** Feet */
20                 FEET
21         }
22
23         /** Constants for conversion */
24         private static final double CONVERT_FEET_TO_METRES = 0.3048;
25         private static final double CONVERT_METRES_TO_FEET = 3.28084;
26
27         /** Constant for no altitude value */
28         public static final Altitude NONE = new Altitude(null, Format.NO_FORMAT);
29
30
31         /**
32          * Constructor using String
33          * @param inString string to parse
34          * @param inFormat format of altitude, either metres or feet
35          */
36         public Altitude(String inString, Format inFormat)
37         {
38                 if (inString != null && !inString.equals(""))
39                 {
40                         try
41                         {
42                                 _stringValue = inString;
43                                 _value = (int) Double.parseDouble(inString.trim());
44                                 _format = inFormat;
45                                 _valid = true;
46                         }
47                         catch (NumberFormatException nfe) {}
48                 }
49         }
50
51
52         /**
53          * Constructor with int value
54          * @param inValue int value of altitude
55          * @param inFormat format of altitude, either metres or feet
56          */
57         public Altitude(int inValue, Format inFormat)
58         {
59                 _value = inValue;
60                 _format = inFormat;
61                 _valid = true;
62         }
63
64         /**
65          * @return an exact copy of this Altitude object
66          */
67         public Altitude clone()
68         {
69                 return new Altitude(_stringValue, _format);
70         }
71
72         /**
73          * Reset the altitude parameters to the same as the given object
74          * @param inClone clone object to copy
75          */
76         public void reset(Altitude inClone)
77         {
78                 _value = inClone._value;
79                 _format = inClone._format;
80                 _valid = inClone._valid;
81         }
82
83         /**
84          * @return true if the value could be parsed
85          */
86         public boolean isValid()
87         {
88                 return _valid;
89         }
90
91
92         /**
93          * @return raw value as int
94          */
95         public int getValue()
96         {
97                 return _value;
98         }
99
100
101         /**
102          * @return format of number
103          */
104         public Format getFormat()
105         {
106                 return _format;
107         }
108
109
110         /**
111          * Get the altitude value in the specified format
112          * @param inFormat desired format, either FORMAT_METRES or FORMAT_FEET
113          * @return value as an int
114          */
115         public int getValue(Format inFormat)
116         {
117                 // Note possible rounding errors here if converting to/from units
118                 if (inFormat == _format)
119                         return _value;
120                 if (inFormat == Format.METRES)
121                         return (int) (_value * CONVERT_FEET_TO_METRES);
122                 if (inFormat == Format.FEET)
123                         return (int) (_value * CONVERT_METRES_TO_FEET);
124                 return _value;
125         }
126
127         /**
128          * Get a string version of the value
129          * @param inFormat specified format
130          * @return string value, if possible the original one
131          */
132         public String getStringValue(Format inFormat)
133         {
134                 if (!_valid) {return "";}
135                 // Return string value if the same format or "no format" was requested
136                 if ((inFormat == _format || inFormat == Format.NO_FORMAT)
137                  && _stringValue != null && !_stringValue.equals("")) {
138                         return _stringValue;
139                 }
140                 return "" + getValue(inFormat);
141         }
142
143
144         /**
145          * Interpolate a new Altitude object between the given ones
146          * @param inStart start altitude
147          * @param inEnd end altitude
148          * @param inIndex index of interpolated point
149          * @param inNumSteps number of steps to interpolate
150          * @return Interpolated Altitude object
151          */
152         public static Altitude interpolate(Altitude inStart, Altitude inEnd, int inIndex, int inNumSteps)
153         {
154                 return interpolate(inStart, inEnd, 1.0 * (inIndex + 1) / (inNumSteps + 1));
155         }
156
157
158         /**
159          * Interpolate a new Altitude object between the given ones
160          * @param inStart start altitude
161          * @param inEnd end altitude
162          * @param inFrac fraction of distance from first point
163          * @return Interpolated Altitude object
164          */
165         public static Altitude interpolate(Altitude inStart, Altitude inEnd, double inFrac)
166         {
167                 // Check if altitudes are valid
168                 if (inStart == null || inEnd == null || !inStart.isValid() || !inEnd.isValid())
169                         return Altitude.NONE;
170                 // Use altitude format of first point
171                 Format altFormat = inStart.getFormat();
172                 int startValue = inStart.getValue();
173                 int endValue = inEnd.getValue(altFormat);
174                 // interpolate between start and end
175                 int newValue = startValue + (int) ((endValue - startValue) * inFrac);
176                 return new Altitude(newValue, altFormat);
177         }
178
179         /**
180          * Add the given offset to the current altitude
181          * @param inOffset offset as double
182          * @param inFormat format of offset, feet or metres
183          * @param inDecimals number of decimal places
184          */
185         public void addOffset(double inOffset, Format inFormat, int inDecimals)
186         {
187                 // Use the maximum number of decimal places from current value and offset
188                 int numDecimals = NumberUtils.getDecimalPlaces(_stringValue);
189                 if (numDecimals < inDecimals) {numDecimals = inDecimals;}
190                 // Convert offset to correct units
191                 double offset = inOffset;
192                 if (inFormat != _format)
193                 {
194                         if (inFormat == Format.FEET)
195                                 offset = inOffset * CONVERT_FEET_TO_METRES;
196                         else
197                                 offset = inOffset * CONVERT_METRES_TO_FEET;
198                 }
199                 // Add the offset
200                 double newValue = Double.parseDouble(_stringValue.trim()) + offset;
201                 _value = (int) newValue;
202                 _stringValue = NumberUtils.formatNumber(newValue, numDecimals);
203         }
204 }