]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - tim/prune/data/SpeedCalculator.java
Version 19.1, August 2018
[GpsPrune.git] / tim / prune / data / SpeedCalculator.java
index d83a7bd306ff9f72aa480f2ce0619ce0f5239dbb..6f81d5a32187d60b43d0a686deb6e8a3e59571ba 100644 (file)
@@ -9,18 +9,22 @@ import tim.prune.config.Config;
 public abstract class SpeedCalculator
 {
        /**
-        * Calculate the speed value of the track at the specified index
+        * Calculate the horizontal speed value of the track at the specified index
         * @param inTrack track object
         * @param inIndex index of point to calculate speed for
         * @param inValue object in which to place result of calculation
         */
        public static void calculateSpeed(Track inTrack, int inIndex, SpeedValue inValue)
        {
-               if (inTrack == null || inIndex < 0 || inValue == null) {
+               if (inValue != null)
+               {
+                       inValue.setInvalid();
+               }
+               if (inTrack == null || inIndex < 0 || inValue == null)
+               {
                        System.err.println("Cannot calculate speed for index " + inIndex);
                        return;
                }
-               inValue.setInvalid();
 
                DataPoint point = inTrack.getPoint(inIndex);
                if (point == null) {return;}
@@ -28,13 +32,10 @@ public abstract class SpeedCalculator
                double  speedValue = 0.0;
 
                // First, see if point has a speed value already
-               // FIXME: How do we know what units this speed is in?  m/s or mph or km/h or what?
-               String speedStr = point.getFieldValue(Field.SPEED);
-               try {
-                       speedValue = Double.parseDouble(speedStr);
+               if (point.hasHSpeed()) {
+                       speedValue = point.getHSpeed().getValue(Config.getUnitSet().getSpeedUnit());
                        pointHasSpeed = true;
                }
-               catch (Exception e) {} // ignore, leave pointHasSpeed false
 
                // otherwise, see if we can calculate it from the timestamps
                if (!pointHasSpeed && point.hasTimestamp() && !point.isWaypoint())
@@ -52,14 +53,14 @@ public abstract class SpeedCalculator
                                do
                                {
                                        p = inTrack.getPoint(index);
-                                       boolean timeOk = p != null && p.hasTimestamp() && !p.getTimestamp().isAfter(point.getTimestamp());
+                                       boolean timeOk = p != null && p.hasTimestamp() && p.getTimestamp().isBefore(point.getTimestamp());
                                        boolean pValid = timeOk && !p.isWaypoint();
                                        if (pValid) {
                                                totalRadians += DataPoint.calculateRadiansBetween(p, q);
                                                earlyStamp = p.getTimestamp();
                                        }
-                                       stop = (p == null) || (p.hasTimestamp() && !p.getTimestamp().isEqual(point.getTimestamp())
-                                               || p.getSegmentStart());
+
+                                       stop = (p == null) || p.getSegmentStart() || hasSufficientTimeDifference(p, point);
                                        index--;
                                        if (p != null && !p.isWaypoint()) {
                                                q = p;
@@ -80,8 +81,8 @@ public abstract class SpeedCalculator
                                        totalRadians += DataPoint.calculateRadiansBetween(p, q);
                                        lateStamp = p.getTimestamp();
                                }
-                               stop = (p == null) || (p.hasTimestamp() && !p.getTimestamp().isEqual(point.getTimestamp())
-                                       || p.getSegmentStart());
+
+                               stop = (p == null) || p.getSegmentStart() || hasSufficientTimeDifference(point, p);
                                index++;
                                if (p != null && !p.isWaypoint()) {
                                        q = p;
@@ -127,15 +128,10 @@ public abstract class SpeedCalculator
                double  speedValue = 0.0;
 
                // First, see if point has a speed value already
-               if (point != null)
+               if (point != null && point.hasVSpeed())
                {
-                       // FIXME: Can we assume m/s or ft/s?
-                       String speedStr = point.getFieldValue(Field.VERTICAL_SPEED);
-                       try {
-                               speedValue = Double.parseDouble(speedStr);
-                               pointHasSpeed = true;
-                       }
-                       catch (Exception e) {} // ignore, leave pointHasSpeed false
+                       speedValue = point.getVSpeed().getValue(Config.getUnitSet().getVerticalSpeedUnit());
+                       pointHasSpeed = true;
                }
                // otherwise, see if we can calculate it from the heights and timestamps
                if (!pointHasSpeed
@@ -153,14 +149,14 @@ public abstract class SpeedCalculator
                                do
                                {
                                        p = inTrack.getPoint(index);
-                                       boolean timeOk = p != null && p.hasTimestamp() && !p.getTimestamp().isAfter(point.getTimestamp());
+                                       boolean timeOk = p != null && p.hasTimestamp() && p.getTimestamp().isBefore(point.getTimestamp());
                                        boolean pValid = timeOk && !p.isWaypoint();
                                        if (pValid) {
                                                earlyStamp = p.getTimestamp();
                                                if (p.hasAltitude()) firstAlt = p.getAltitude();
                                        }
-                                       stop = (p == null) || (p.hasTimestamp() && !p.getTimestamp().isEqual(point.getTimestamp())
-                                               || p.getSegmentStart());
+
+                                       stop = (p == null) || p.getSegmentStart() || hasSufficientTimeDifference(p, point);
                                        index--;
                                }
                                while (!stop);
@@ -179,8 +175,8 @@ public abstract class SpeedCalculator
                                        lateStamp = p.getTimestamp();
                                        if (p.hasAltitude()) lastAlt = p.getAltitude();
                                }
-                               stop = (p == null) || (p.hasTimestamp() && !p.getTimestamp().isEqual(point.getTimestamp())
-                                       || p.getSegmentStart());
+
+                               stop = (p == null) || p.getSegmentStart() || hasSufficientTimeDifference(point, p);
                                index++;
                        }
                        while (!stop);
@@ -201,4 +197,20 @@ public abstract class SpeedCalculator
                        inValue.setValue(speedValue);
                }
        }
+
+       /**
+        * Check whether the time difference between P1 and P2 is sufficiently large
+        * @param inP1 earlier point
+        * @param inP2 later point
+        * @return true if we can stop looking now, found a point early/late enough
+        */
+       private static boolean hasSufficientTimeDifference(DataPoint inP1, DataPoint inP2)
+       {
+               if (inP1 == null || inP2 == null)
+                       return true; // we have to give up now
+               if (!inP1.hasTimestamp() || !inP2.hasTimestamp())
+                       return false; // keep looking
+               final long MIN_TIME_DIFFERENCE_MS = 1000L;
+               return inP2.getTimestamp().getMillisecondsSince(inP1.getTimestamp()) >= MIN_TIME_DIFFERENCE_MS;
+       }
 }