Bugfix: moving time was not computed.

Introduced in 6be9d2477c (first released in v4.9.0)

Fixes #1756.
This commit is contained in:
Dennis Guse
2024-05-04 20:11:19 +02:00
parent c96635c46b
commit 1ed807054b
4 changed files with 78 additions and 14 deletions
@@ -1,7 +1,9 @@
package de.dennisguse.opentracks.stats; package de.dennisguse.opentracks.stats;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -231,7 +233,7 @@ public class TrackStatisticsUpdaterTest {
)); ));
// then // then
assertEquals(Duration.ofSeconds(40), subject.getTrackStatistics().getMovingTime()); assertEquals(Duration.ofSeconds(35), subject.getTrackStatistics().getMovingTime());
} }
@Test @Test
@@ -261,10 +263,67 @@ public class TrackStatisticsUpdaterTest {
)); ));
// then // then
assertEquals(Duration.ofSeconds(45), subject.getTrackStatistics().getMovingTime()); assertEquals(Duration.ofSeconds(40), subject.getTrackStatistics().getMovingTime());
assertEquals(Distance.of(1040), subject.getTrackStatistics().getTotalDistance()); assertEquals(Distance.of(1040), subject.getTrackStatistics().getTotalDistance());
} }
@Test
public void addTrackPoint_idle_remain_idle() {
TrackStatisticsUpdater subject = new TrackStatisticsUpdater();
// when
subject.addTrackPoint(new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochSecond(0)));
subject.addTrackPoint(
new TrackPoint(0, 0, Altitude.WGS84.of(0), Instant.ofEpochSecond(10))
.setSensorDistance(Distance.of(10)));
subject.addTrackPoint(new TrackPoint(TrackPoint.Type.IDLE, Instant.ofEpochSecond(30)));
// then
assertTrue(subject.getTrackStatistics().isIdle());
assertEquals(Duration.ofSeconds(30), subject.getTrackStatistics().getMovingTime());
assertEquals(Duration.ofSeconds(30), subject.getTrackStatistics().getTotalTime());
assertEquals(Distance.of(10), subject.getTrackStatistics().getTotalDistance());
// when
subject.addTrackPoint(
new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.ofEpochSecond(40))
.setSensorDistance(Distance.of(0)));
// then
assertTrue(subject.getTrackStatistics().isIdle());
assertEquals(Duration.ofSeconds(30), subject.getTrackStatistics().getMovingTime());
assertEquals(Duration.ofSeconds(40), subject.getTrackStatistics().getTotalTime());
assertEquals(Distance.of(10), subject.getTrackStatistics().getTotalDistance());
// when
subject.addTrackPoint(
new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.ofEpochSecond(45))
.setSensorDistance(Distance.of(1)));
// then
assertTrue(subject.getTrackStatistics().isIdle());
assertEquals(Duration.ofSeconds(30), subject.getTrackStatistics().getMovingTime());
assertEquals(Duration.ofSeconds(45), subject.getTrackStatistics().getTotalTime());
assertEquals(Distance.of(11), subject.getTrackStatistics().getTotalDistance());
// when
subject.addTrackPoint(
new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.ofEpochSecond(50))
.setSensorDistance(Distance.of(10)));
// then
assertFalse(subject.getTrackStatistics().isIdle());
assertEquals(Duration.ofSeconds(30), subject.getTrackStatistics().getMovingTime());
assertEquals(Duration.ofSeconds(50), subject.getTrackStatistics().getTotalTime());
assertEquals(Distance.of(21), subject.getTrackStatistics().getTotalDistance());
// when
subject.addTrackPoint(new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.ofEpochSecond(60)));
// then
assertFalse(subject.getTrackStatistics().isIdle());
assertEquals(Duration.ofSeconds(40), subject.getTrackStatistics().getMovingTime());
assertEquals(Duration.ofSeconds(60), subject.getTrackStatistics().getTotalTime());
assertEquals(Distance.of(21), subject.getTrackStatistics().getTotalDistance());
}
@Test @Test
public void copy_constructor() { public void copy_constructor() {
// given // given
@@ -135,6 +135,10 @@ public class TrackPoint {
return this; return this;
} }
public boolean isIdleTriggered() {
return type == Type.IDLE;
}
public boolean isSegmentManualStart() { public boolean isSegmentManualStart() {
return type == Type.SEGMENT_START_MANUAL; return type == Type.SEGMENT_START_MANUAL;
} }
@@ -107,6 +107,7 @@ public class TrackStatistics {
* *
* @param other another statistics data object * @param other another statistics data object
*/ */
//TODO Should be refactored to append only [mainly due to isIdle] (NOTE: This requires to use a custom value object for AggregatedStatistics; this is anyhow recommended).
public void merge(TrackStatistics other) { public void merge(TrackStatistics other) {
if (startTime == null) { if (startTime == null) {
startTime = other.startTime; startTime = other.startTime;
@@ -119,6 +120,8 @@ public class TrackStatistics {
stopTime = stopTime.isAfter(other.stopTime) ? stopTime : other.stopTime; stopTime = stopTime.isAfter(other.stopTime) ? stopTime : other.stopTime;
} }
isIdle = other.isIdle; //TODO This implicitly assumes append mode.
if (avgHeartRate == null) { if (avgHeartRate == null) {
avgHeartRate = other.avgHeartRate; avgHeartRate = other.avgHeartRate;
} else { } else {
@@ -26,6 +26,7 @@ import de.dennisguse.opentracks.data.models.HeartRate;
import de.dennisguse.opentracks.data.models.Power; import de.dennisguse.opentracks.data.models.Power;
import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.Speed;
import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.data.models.TrackPoint;
import de.dennisguse.opentracks.settings.PreferencesUtils;
/** /**
* Updater for {@link TrackStatistics}. * Updater for {@link TrackStatistics}.
@@ -56,11 +57,6 @@ public class TrackStatisticsUpdater {
this(new TrackStatistics()); this(new TrackStatistics());
} }
/**
* Creates a new{@link TrackStatisticsUpdater} with a {@link TrackStatisticsUpdater} already existed.
*
* @param trackStatistics a {@link TrackStatisticsUpdater}
*/
public TrackStatisticsUpdater(TrackStatistics trackStatistics) { public TrackStatisticsUpdater(TrackStatistics trackStatistics) {
this.trackStatistics = trackStatistics; this.trackStatistics = trackStatistics;
this.currentSegment = new TrackStatistics(); this.currentSegment = new TrackStatistics();
@@ -87,9 +83,6 @@ public class TrackStatisticsUpdater {
trackPoints.stream().forEachOrdered(this::addTrackPoint); trackPoints.stream().forEachOrdered(this::addTrackPoint);
} }
/**
*
*/
public void addTrackPoint(TrackPoint trackPoint) { public void addTrackPoint(TrackPoint trackPoint) {
if (trackPoint.isSegmentManualStart()) { if (trackPoint.isSegmentManualStart()) {
reset(trackPoint); reset(trackPoint);
@@ -151,18 +144,23 @@ public class TrackStatisticsUpdater {
movingDistance = trackPoint.distanceToPrevious(lastTrackPoint); movingDistance = trackPoint.distanceToPrevious(lastTrackPoint);
} }
if (movingDistance != null) { if (movingDistance != null) {
currentSegment.setIdle(false);
currentSegment.addTotalDistance(movingDistance); currentSegment.addTotalDistance(movingDistance);
} }
if (!currentSegment.isIdle() && !trackPoint.isSegmentManualStart()) { if (!currentSegment.isIdle()) {
if (lastTrackPoint != null) { if (!trackPoint.isSegmentManualStart() && lastTrackPoint != null) {
currentSegment.addMovingTime(trackPoint, lastTrackPoint); currentSegment.addMovingTime(trackPoint, lastTrackPoint);
} }
} }
if (trackPoint.getType() == TrackPoint.Type.IDLE) { if (trackPoint.isIdleTriggered()) {
currentSegment.setIdle(true); currentSegment.setIdle(true);
} else if (currentSegment.isIdle()) {
// Shall we switch to non-idle?
if (movingDistance != null
&& movingDistance.greaterOrEqualThan(PreferencesUtils.getRecordingDistanceInterval())) {
currentSegment.setIdle(false);
}
} }
if (trackPoint.hasSpeed()) { if (trackPoint.hasSpeed()) {