altoslib: Fix parsing of old TM log GPS sat data
[fw/altos] / altoslib / AltosTimeSeries.java
index 64fb399e8a23974797f01f94e2327840be4e8bcd..b3c432fcf565e1b481d63e0025024334a8d90061 100644 (file)
  * General Public License for more details.
  */
 
-package org.altusmetrum.altoslib_11;
+package org.altusmetrum.altoslib_12;
 
 import java.util.*;
 
-public class AltosTimeSeries implements Iterable<AltosTimeValue> {
+public class AltosTimeSeries implements Iterable<AltosTimeValue>, Comparable<AltosTimeSeries> {
        public String                   label;
        public AltosUnits               units;
        ArrayList<AltosTimeValue>       values;
 
+       public int compareTo(AltosTimeSeries other) {
+               return label.compareTo(other.label);
+       }
+
        public void add(AltosTimeValue tv) {
                values.add(tv);
        }
@@ -109,68 +113,84 @@ public class AltosTimeSeries implements Iterable<AltosTimeValue> {
                return values.iterator();
        }
 
-       public double max() {
-               double max = AltosLib.MISSING;
-               for (AltosTimeValue tv : values) {
-                       if (max == AltosLib.MISSING || tv.value > max)
-                               max = tv.value;
-               }
+       public AltosTimeValue max() {
+               AltosTimeValue max = null;
+               for (AltosTimeValue tv : values)
+                       if (max == null || tv.value > max.value)
+                               max = tv;
                return max;
        }
 
-       public double max(double start_time, double end_time) {
-               double max = AltosLib.MISSING;
+       public AltosTimeValue max(double start_time, double end_time) {
+               AltosTimeValue max = null;
                for (AltosTimeValue tv : values) {
                        if (start_time <= tv.time && tv.time <= end_time)
-                               if (max == AltosLib.MISSING || tv.value > max)
-                                       max = tv.value;
+                               if (max == null || tv.value > max.value)
+                                       max = tv;
                }
                return max;
        }
 
-       public double min() {
-               double min = AltosLib.MISSING;
+       public AltosTimeValue min() {
+               AltosTimeValue min = null;
                for (AltosTimeValue tv : values) {
-                       if (min == AltosLib.MISSING || tv.value < min)
-                               min = tv.value;
+                       if (min == null || tv.value < min.value)
+                               min = tv;
                }
                return min;
        }
 
-       public double min(double start_time, double end_time) {
-               double min = AltosLib.MISSING;
+       public AltosTimeValue min(double start_time, double end_time) {
+               AltosTimeValue min = null;
                for (AltosTimeValue tv : values) {
                        if (start_time <= tv.time && tv.time <= end_time)
-                               if (min == AltosLib.MISSING || tv.value < min)
-                                       min = tv.value;
+                               if (min == null || tv.value < min.value)
+                                       min = tv;
                }
                return min;
        }
 
+       public AltosTimeValue first() {
+               return values.get(0);
+       }
+
+       public AltosTimeValue last() {
+               return values.get(values.size() - 1);
+       }
+
        public double average() {
-               double total = 0;
-               int count = 0;
+               double total_value = 0;
+               double total_time = 0;
+               AltosTimeValue prev = null;
                for (AltosTimeValue tv : values) {
-                       total += tv.value;
-                       count++;
+                       if (prev != null) {
+                               total_value += (tv.value + prev.value) / 2 * (tv.time - prev.time);
+                               total_time += (tv.time - prev.time);
+                       }
+                       prev = tv;
                }
-               if (count == 0)
+               if (total_time == 0)
                        return AltosLib.MISSING;
-               return total / count;
+               return total_value / total_time;
        }
 
        public double average(double start_time, double end_time) {
-               double total = 0;
-               int count = 0;
+               double total_value = 0;
+               double total_time = 0;
+               AltosTimeValue prev = null;
                for (AltosTimeValue tv : values) {
                        if (start_time <= tv.time && tv.time <= end_time) {
-                               total += tv.value;
-                               count++;
+                               if (prev != null) {
+                                       total_value += (tv.value + prev.value) / 2 * (tv.time - start_time);
+                                       total_time += (tv.time - start_time);
+                               }
+                               start_time = tv.time;
                        }
+                       prev = tv;
                }
-               if (count == 0)
+               if (total_time == 0)
                        return AltosLib.MISSING;
-               return total / count;
+               return total_value / total_time;
        }
 
        public AltosTimeSeries integrate(AltosTimeSeries integral) {
@@ -266,9 +286,11 @@ public class AltosTimeSeries implements Iterable<AltosTimeValue> {
                                        double  j_right = j == right ? right_time : values.get(j+1).time;
                                        double  interval = (j_right - j_left) / 2.0;
                                        double  coeff = filter_coeff(j_time - center_time, width) * interval;
+                                       double  value = values.get(j).value;
+                                       double  partial = value * coeff;
 
                                        total_coeff += coeff;
-                                       total_value += coeff * values.get(j).value;
+                                       total_value += partial;
                                }
                        }
                        if (total_coeff != 0.0)