forked from upstream-mirrors/OpenTracks
Cleanup: SegmentStatisticUpdater is always initialized.
This commit is contained in:
@@ -166,14 +166,14 @@ public class TrackStatisticsUpdaterTest {
|
|||||||
assertEquals(Speed.of(2), subject.getTrackStatistics().maxSpeed());
|
assertEquals(Speed.of(2), subject.getTrackStatistics().maxSpeed());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
subject.addTrackPoints(List.of(
|
List.of(
|
||||||
new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochSecond(5)),
|
new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochSecond(5)),
|
||||||
createTrackPoint(0, 0, Altitude.WGS84.of(0), Instant.ofEpochSecond(6))
|
createTrackPoint(0, 0, Altitude.WGS84.of(0), Instant.ofEpochSecond(6))
|
||||||
.setSpeed(Speed.of(1f)),
|
.setSpeed(Speed.of(1f)),
|
||||||
createTrackPoint(0, 0, Altitude.WGS84.of(0), Instant.ofEpochSecond(7))
|
createTrackPoint(0, 0, Altitude.WGS84.of(0), Instant.ofEpochSecond(7))
|
||||||
.setSpeed(Speed.of(1f)),
|
.setSpeed(Speed.of(1f)),
|
||||||
new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.ofEpochSecond(8))
|
new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.ofEpochSecond(8))
|
||||||
));
|
).forEach(subject::addTrackPoint);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertEquals(Speed.of(2f), subject.getTrackStatistics().maxSpeed());
|
assertEquals(Speed.of(2f), subject.getTrackStatistics().maxSpeed());
|
||||||
|
|||||||
@@ -7,15 +7,20 @@ import java.time.Duration;
|
|||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
//TODO Add @NonNull to attributes
|
|
||||||
public record Statistics(
|
public record Statistics(
|
||||||
|
@NonNull
|
||||||
Instant startTime,
|
Instant startTime,
|
||||||
|
@NonNull
|
||||||
Instant stopTime,
|
Instant stopTime,
|
||||||
|
@NonNull
|
||||||
Duration totalDuration,
|
Duration totalDuration,
|
||||||
|
@NonNull
|
||||||
Duration movingDuration, // Based on when we believe the user is traveling
|
Duration movingDuration, // Based on when we believe the user is traveling
|
||||||
|
|
||||||
|
@NonNull
|
||||||
Distance totalDistance,
|
Distance totalDistance,
|
||||||
|
|
||||||
|
@NonNull
|
||||||
Speed maxSpeed,
|
Speed maxSpeed,
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -31,6 +36,22 @@ public record Statistics(
|
|||||||
Power avgPower
|
Power avgPower
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
//TODO: Should not be necessary; refactor and remove.
|
||||||
|
@Deprecated
|
||||||
|
public static final Statistics DEFAULT =
|
||||||
|
new Statistics(
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
Duration.ZERO,
|
||||||
|
Duration.ZERO,
|
||||||
|
Distance.ZERO,
|
||||||
|
Speed.ZERO,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
public Duration getStoppedTime() {
|
public Duration getStoppedTime() {
|
||||||
return totalDuration.minus(movingDuration);
|
return totalDuration.minus(movingDuration);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.time.OffsetDateTime;
|
import java.time.OffsetDateTime;
|
||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -67,7 +68,7 @@ public class Track {
|
|||||||
|
|
||||||
@Deprecated //TODO Remove
|
@Deprecated //TODO Remove
|
||||||
public Track(@NonNull ZoneOffset zoneOffset) {
|
public Track(@NonNull ZoneOffset zoneOffset) {
|
||||||
this(zoneOffset, new SegmentStatisticUpdater().getStatistics());
|
this(zoneOffset, Statistics.DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Track(@NonNull ZoneOffset zoneOffset, @NonNull Statistics trackStatistics) {
|
public Track(@NonNull ZoneOffset zoneOffset, @NonNull Statistics trackStatistics) {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public record RecordingData(Track track, TrackPoint latestTrackPoint, SensorData
|
|||||||
@NonNull
|
@NonNull
|
||||||
public Statistics getStatisticsTrack() {
|
public Statistics getStatisticsTrack() {
|
||||||
if (track == null) {
|
if (track == null) {
|
||||||
return new SegmentStatisticUpdater().getStatistics();
|
return Statistics.DEFAULT; //TODO Refactor code that this is not necessary.
|
||||||
}
|
}
|
||||||
|
|
||||||
return track.getStatistics();
|
return track.getStatistics();
|
||||||
|
|||||||
@@ -46,9 +46,11 @@ public class SegmentStatisticUpdater {
|
|||||||
private final ExtremityMonitor altitudeExtremities = new ExtremityMonitor();
|
private final ExtremityMonitor altitudeExtremities = new ExtremityMonitor();
|
||||||
|
|
||||||
// The track start time.
|
// The track start time.
|
||||||
private Instant startTime; //TODO Should never be null!
|
@NonNull
|
||||||
|
private final Instant startTime;
|
||||||
// The track stop time.
|
// The track stop time.
|
||||||
private Instant stopTime; //TODO Should never be null!
|
@NonNull
|
||||||
|
private Instant stopTime;
|
||||||
|
|
||||||
private Distance totalDistance;
|
private Distance totalDistance;
|
||||||
/**
|
/**
|
||||||
@@ -67,12 +69,14 @@ public class SegmentStatisticUpdater {
|
|||||||
private HeartRate avgHeartRate = null;
|
private HeartRate avgHeartRate = null;
|
||||||
private Power avgPower = null;
|
private Power avgPower = null;
|
||||||
|
|
||||||
public SegmentStatisticUpdater() {
|
public SegmentStatisticUpdater(@NonNull Instant startTime) {
|
||||||
reset();
|
this.startTime = this.stopTime = startTime;
|
||||||
}
|
totalDuration = Duration.ZERO;
|
||||||
|
movingDuration = Duration.ZERO;
|
||||||
public SegmentStatisticUpdater(Instant startTime) {
|
totalDistance = Distance.ZERO;
|
||||||
reset(startTime);
|
maxSpeed = Speed.ZERO;
|
||||||
|
totalAltitudeGain_m = null;
|
||||||
|
totalAltitudeLoss_m = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -106,27 +110,6 @@ public class SegmentStatisticUpdater {
|
|||||||
return statistics.merge(getStatistics());
|
return statistics.merge(getStatistics());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInitialized() {
|
|
||||||
return startTime != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reset() {
|
|
||||||
startTime = null;
|
|
||||||
stopTime = null;
|
|
||||||
|
|
||||||
totalDuration = Duration.ZERO;
|
|
||||||
movingDuration = Duration.ZERO;
|
|
||||||
totalDistance = Distance.ZERO;
|
|
||||||
maxSpeed = Speed.ZERO;
|
|
||||||
totalAltitudeGain_m = null;
|
|
||||||
totalAltitudeLoss_m = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reset(Instant startTime) {
|
|
||||||
reset();
|
|
||||||
setStartTime(startTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Statistics getStatistics() {
|
public Statistics getStatistics() {
|
||||||
// Times may not be live (i.e., updated automatically).
|
// Times may not be live (i.e., updated automatically).
|
||||||
return new Statistics(
|
return new Statistics(
|
||||||
@@ -146,14 +129,6 @@ public class SegmentStatisticUpdater {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Should only be called on start.
|
|
||||||
*/
|
|
||||||
public void setStartTime(Instant startTime) {
|
|
||||||
this.startTime = startTime;
|
|
||||||
setStopTime(startTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStopTime(Instant stopTime) {
|
public void setStopTime(Instant stopTime) {
|
||||||
if (stopTime.isBefore(startTime)) {
|
if (stopTime.isBefore(startTime)) {
|
||||||
// Time must be monotonically increasing, but we might have events at the same point in time (BLE and GPS)
|
// Time must be monotonically increasing, but we might have events at the same point in time (BLE and GPS)
|
||||||
|
|||||||
@@ -32,8 +32,7 @@ import de.dennisguse.opentracks.settings.PreferencesUtils;
|
|||||||
/**
|
/**
|
||||||
* Updater for {@link SegmentStatisticUpdater}.
|
* Updater for {@link SegmentStatisticUpdater}.
|
||||||
* For updating track {@link SegmentStatisticUpdater} as new {@link TrackPoint}s are added.
|
* For updating track {@link SegmentStatisticUpdater} as new {@link TrackPoint}s are added.
|
||||||
* NOTE: Some of the locations represent pause/resume separator.
|
* NOTE: {@link TrackPoint} represent pause/resume separator.
|
||||||
* NOTE: Has still support for segments (at the moment unused).
|
|
||||||
*
|
*
|
||||||
* @author Sandor Dornbush
|
* @author Sandor Dornbush
|
||||||
* @author Rodrigo Damazio
|
* @author Rodrigo Damazio
|
||||||
@@ -51,7 +50,7 @@ public class TrackStatisticsUpdater {
|
|||||||
private Duration totalPowerDuration = Duration.ZERO;
|
private Duration totalPowerDuration = Duration.ZERO;
|
||||||
|
|
||||||
// The current segment's statistics
|
// The current segment's statistics
|
||||||
private final SegmentStatisticUpdater currentSegment;
|
private SegmentStatisticUpdater currentSegment;
|
||||||
// Current segment's last trackPoint
|
// Current segment's last trackPoint
|
||||||
private TrackPoint lastTrackPoint;
|
private TrackPoint lastTrackPoint;
|
||||||
|
|
||||||
@@ -59,7 +58,7 @@ public class TrackStatisticsUpdater {
|
|||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public TrackStatisticsUpdater() {
|
public TrackStatisticsUpdater() {
|
||||||
this(new SegmentStatisticUpdater().getStatistics());
|
this(Statistics.DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TrackStatisticsUpdater(@NonNull TrackPoint trackPoint) {
|
public TrackStatisticsUpdater(@NonNull TrackPoint trackPoint) {
|
||||||
@@ -71,12 +70,12 @@ public class TrackStatisticsUpdater {
|
|||||||
this();
|
this();
|
||||||
assert !trackPoints.isEmpty(); //TODO Enforce that this is always true (e.g., import)
|
assert !trackPoints.isEmpty(); //TODO Enforce that this is always true (e.g., import)
|
||||||
|
|
||||||
addTrackPoints(trackPoints);
|
trackPoints.forEach(this::addTrackPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TrackStatisticsUpdater(@NonNull Statistics statistics) {
|
public TrackStatisticsUpdater(@NonNull Statistics statistics) {
|
||||||
this.statisticsWithoutCurrentSegment = statistics;
|
this.statisticsWithoutCurrentSegment = statistics;
|
||||||
this.currentSegment = new SegmentStatisticUpdater();
|
this.currentSegment = null;
|
||||||
|
|
||||||
resetAverageHeartRate();
|
resetAverageHeartRate();
|
||||||
}
|
}
|
||||||
@@ -105,17 +104,12 @@ public class TrackStatisticsUpdater {
|
|||||||
return currentSegment.getStatistics();
|
return currentSegment.getStatistics();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTrackPoints(List<TrackPoint> trackPoints) {
|
|
||||||
trackPoints.forEach(this::addTrackPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addTrackPoint(TrackPoint trackPoint) {
|
public void addTrackPoint(TrackPoint trackPoint) {
|
||||||
if (trackPoint.isSegmentManualStart()) {
|
if (trackPoint.isSegmentManualStart()) {
|
||||||
reset(trackPoint);
|
reset(trackPoint);
|
||||||
}
|
}
|
||||||
|
if (currentSegment == null) {
|
||||||
if (!currentSegment.isInitialized()) {
|
currentSegment = new SegmentStatisticUpdater(trackPoint.getTime());
|
||||||
currentSegment.setStartTime(trackPoint.getTime());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always update time
|
// Always update time
|
||||||
@@ -199,10 +193,10 @@ public class TrackStatisticsUpdater {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void reset(TrackPoint trackPoint) {
|
private void reset(TrackPoint trackPoint) {
|
||||||
if (currentSegment.isInitialized()) {
|
if (currentSegment != null) {
|
||||||
statisticsWithoutCurrentSegment = currentSegment.merge(statisticsWithoutCurrentSegment);
|
statisticsWithoutCurrentSegment = currentSegment.merge(statisticsWithoutCurrentSegment);
|
||||||
}
|
}
|
||||||
currentSegment.reset(trackPoint.getTime());
|
currentSegment = new SegmentStatisticUpdater(trackPoint.getTime());
|
||||||
|
|
||||||
lastTrackPoint = null;
|
lastTrackPoint = null;
|
||||||
resetAverageHeartRate();
|
resetAverageHeartRate();
|
||||||
|
|||||||
Reference in New Issue
Block a user