X-Git-Url: http://gitweb.fperrin.net/?a=blobdiff_plain;f=tim%2Fprune%2Fdata%2FSpeedCalculator.java;h=49fd05665a90e8788e3806e5f740d773f7c4cc0f;hb=ff33ebba6b7c62834f6dae16ce33eb2c710b160e;hp=d83a7bd306ff9f72aa480f2ce0619ce0f5239dbb;hpb=4d5796d02a15808311c09448d79e6e7d1de9d636;p=GpsPrune.git diff --git a/tim/prune/data/SpeedCalculator.java b/tim/prune/data/SpeedCalculator.java index d83a7bd..49fd056 100644 --- a/tim/prune/data/SpeedCalculator.java +++ b/tim/prune/data/SpeedCalculator.java @@ -9,18 +9,19 @@ 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) { + 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 +29,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 +50,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 +78,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 +125,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 +146,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 +172,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 +194,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; + } }