forked from upstream-mirrors/OpenTracks
Introduced Statistics as a value object.
This commit is contained in:
@@ -30,6 +30,7 @@ import java.util.Objects;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.stats.SegmentStatisticUpdater;
|
import de.dennisguse.opentracks.stats.SegmentStatisticUpdater;
|
||||||
|
import de.dennisguse.opentracks.stats.Statistics;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A track.
|
* A track.
|
||||||
@@ -51,6 +52,7 @@ public class Track {
|
|||||||
|
|
||||||
private ZoneOffset zoneOffset;
|
private ZoneOffset zoneOffset;
|
||||||
|
|
||||||
|
@Deprecated // TODO Replace with Statistic
|
||||||
private SegmentStatisticUpdater trackStatistics = new SegmentStatisticUpdater();
|
private SegmentStatisticUpdater trackStatistics = new SegmentStatisticUpdater();
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -137,15 +139,26 @@ public class Track {
|
|||||||
.getStopTime().atOffset(zoneOffset);
|
.getStopTime().atOffset(zoneOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Statistics getStatistics() {
|
||||||
|
return trackStatistics.getStatistics();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Statistics setStatistics() {
|
||||||
|
throw new RuntimeException("TODO");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
@NonNull
|
@NonNull
|
||||||
public SegmentStatisticUpdater getTrackStatistics() {
|
public SegmentStatisticUpdater getTrackStatistics() {
|
||||||
return trackStatistics;
|
return trackStatistics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public void setTrackStatistics(@NonNull SegmentStatisticUpdater trackStatistics) {
|
public void setTrackStatistics(@NonNull SegmentStatisticUpdater trackStatistics) {
|
||||||
this.trackStatistics = trackStatistics;
|
this.trackStatistics = trackStatistics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Track{" +
|
return "Track{" +
|
||||||
@@ -156,6 +169,7 @@ public class Track {
|
|||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated //TODO Remove: should not be used.
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
@@ -164,6 +178,7 @@ public class Track {
|
|||||||
return id.equals(track.id);
|
return id.equals(track.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated //TODO Remove: should not be used.
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(id);
|
return Objects.hash(id);
|
||||||
|
|||||||
@@ -6,11 +6,13 @@ import de.dennisguse.opentracks.data.models.Track;
|
|||||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||||
import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet;
|
import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet;
|
||||||
import de.dennisguse.opentracks.stats.SegmentStatisticUpdater;
|
import de.dennisguse.opentracks.stats.SegmentStatisticUpdater;
|
||||||
|
import de.dennisguse.opentracks.stats.Statistics;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Track} and {@link TrackPoint} must be immutable (i.e., their content does not change).
|
* {@link Track} and {@link TrackPoint} must be immutable (i.e., their content does not change).
|
||||||
*/
|
*/
|
||||||
public record RecordingData(Track track, TrackPoint latestTrackPoint, SensorDataSet sensorDataSet, SegmentStatisticUpdater currentSegment) {
|
public record RecordingData(Track track, TrackPoint latestTrackPoint, SensorDataSet sensorDataSet,
|
||||||
|
Statistics currentSegment) {
|
||||||
public String getTrackCategory() {
|
public String getTrackCategory() {
|
||||||
if (track == null) {
|
if (track == null) {
|
||||||
return "";
|
return "";
|
||||||
@@ -26,14 +28,4 @@ public record RecordingData(Track track, TrackPoint latestTrackPoint, SensorData
|
|||||||
|
|
||||||
return track.getTrackStatistics();
|
return track.getTrackStatistics();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public SegmentStatisticUpdater getStatisticsCurrentSegment() {
|
|
||||||
if (currentSegment == null) {
|
|
||||||
return new SegmentStatisticUpdater();
|
|
||||||
}
|
|
||||||
|
|
||||||
return currentSegment;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,9 +131,8 @@ public class TrackRecordingManager implements SharedPreferences.OnSharedPreferen
|
|||||||
}
|
}
|
||||||
|
|
||||||
track.setTrackStatistics(tmpTrackStatisticsUpdater.getTrackStatistics());
|
track.setTrackStatistics(tmpTrackStatisticsUpdater.getTrackStatistics());
|
||||||
SegmentStatisticUpdater currentSegment = tmpTrackStatisticsUpdater.getCurrentSegment();
|
|
||||||
|
|
||||||
return new RecordingData(track, current.first, current.second, currentSegment);
|
return new RecordingData(track, current.first, current.second, tmpTrackStatisticsUpdater.getCurrentSegment());
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
|
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import java.time.Duration;
|
|||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.data.models.Altitude;
|
import de.dennisguse.opentracks.data.models.Altitude;
|
||||||
|
import de.dennisguse.opentracks.data.models.AltitudeGainLoss;
|
||||||
import de.dennisguse.opentracks.data.models.Distance;
|
import de.dennisguse.opentracks.data.models.Distance;
|
||||||
import de.dennisguse.opentracks.data.models.HeartRate;
|
import de.dennisguse.opentracks.data.models.HeartRate;
|
||||||
import de.dennisguse.opentracks.data.models.Power;
|
import de.dennisguse.opentracks.data.models.Power;
|
||||||
@@ -198,6 +199,24 @@ public class SegmentStatisticUpdater {
|
|||||||
setStartTime(startTime);
|
setStartTime(startTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Statistics getStatistics() {
|
||||||
|
return new Statistics(
|
||||||
|
startTime,
|
||||||
|
stopTime,
|
||||||
|
totalTime,
|
||||||
|
movingTime,
|
||||||
|
|
||||||
|
totalDistance,
|
||||||
|
isIdle,
|
||||||
|
getMaxSpeed(),
|
||||||
|
altitudeExtremities.hasData() ? altitudeExtremities.getMin() : null,
|
||||||
|
altitudeExtremities.hasData() ? altitudeExtremities.getMax() : null,
|
||||||
|
totalAltitudeGain_m != null && totalAltitudeLoss_m != null ? new AltitudeGainLoss(totalAltitudeGain_m, totalAltitudeLoss_m) : null,
|
||||||
|
avgHeartRate,
|
||||||
|
avgPower
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public Instant getStartTime() {
|
public Instant getStartTime() {
|
||||||
return startTime;
|
return startTime;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package de.dennisguse.opentracks.stats;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
import de.dennisguse.opentracks.data.models.AltitudeGainLoss;
|
||||||
|
import de.dennisguse.opentracks.data.models.Distance;
|
||||||
|
import de.dennisguse.opentracks.data.models.HeartRate;
|
||||||
|
import de.dennisguse.opentracks.data.models.Power;
|
||||||
|
import de.dennisguse.opentracks.data.models.Speed;
|
||||||
|
|
||||||
|
public record Statistics(
|
||||||
|
Instant startTime,
|
||||||
|
Instant stopTime,
|
||||||
|
//TODO Rename to totalDuration
|
||||||
|
Duration totalTime,
|
||||||
|
//TODO Rename to movingDuration
|
||||||
|
Duration movingTime, // Based on when we believe the user is traveling
|
||||||
|
|
||||||
|
Distance totalDistance,
|
||||||
|
boolean isIdle, //TODO Check if this is persisted; if not: remove
|
||||||
|
Speed maxSpeed,
|
||||||
|
|
||||||
|
//TODO Create record for min/max altitude
|
||||||
|
@Nullable
|
||||||
|
Double altitudeMin_m,
|
||||||
|
@Nullable
|
||||||
|
Double altitudeMax_m,
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
AltitudeGainLoss altitudeGainLoss,
|
||||||
|
@Nullable
|
||||||
|
HeartRate avgHeartRate,
|
||||||
|
@Nullable
|
||||||
|
Power avgPower
|
||||||
|
) {
|
||||||
|
|
||||||
|
public Speed getAverageMovingSpeed() {
|
||||||
|
return Speed.of(totalDistance, movingTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -78,9 +78,9 @@ public class TrackStatisticsUpdater {
|
|||||||
stats.merge(currentSegment);
|
stats.merge(currentSegment);
|
||||||
return stats;
|
return stats;
|
||||||
}
|
}
|
||||||
public SegmentStatisticUpdater getCurrentSegment() {
|
|
||||||
// Take a snapshot - we don't want anyone messing with our currentSegment
|
public Statistics getCurrentSegment() {
|
||||||
return new SegmentStatisticUpdater(currentSegment);
|
return currentSegment.getStatistics();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTrackPoints(List<TrackPoint> trackPoints) {
|
public void addTrackPoints(List<TrackPoint> trackPoints) {
|
||||||
|
|||||||
+19
-11
@@ -19,6 +19,7 @@ import java.util.concurrent.Callable;
|
|||||||
|
|
||||||
import de.dennisguse.opentracks.R;
|
import de.dennisguse.opentracks.R;
|
||||||
import de.dennisguse.opentracks.data.models.Altitude;
|
import de.dennisguse.opentracks.data.models.Altitude;
|
||||||
|
import de.dennisguse.opentracks.data.models.AltitudeGainLoss;
|
||||||
import de.dennisguse.opentracks.data.models.Distance;
|
import de.dennisguse.opentracks.data.models.Distance;
|
||||||
import de.dennisguse.opentracks.data.models.Position;
|
import de.dennisguse.opentracks.data.models.Position;
|
||||||
import de.dennisguse.opentracks.data.models.Speed;
|
import de.dennisguse.opentracks.data.models.Speed;
|
||||||
@@ -27,7 +28,7 @@ import de.dennisguse.opentracks.data.models.TrackPoint;
|
|||||||
import de.dennisguse.opentracks.databinding.CustomStatsItemBinding;
|
import de.dennisguse.opentracks.databinding.CustomStatsItemBinding;
|
||||||
import de.dennisguse.opentracks.services.RecordingData;
|
import de.dennisguse.opentracks.services.RecordingData;
|
||||||
import de.dennisguse.opentracks.settings.UnitSystem;
|
import de.dennisguse.opentracks.settings.UnitSystem;
|
||||||
import de.dennisguse.opentracks.stats.SegmentStatisticUpdater;
|
import de.dennisguse.opentracks.stats.Statistics;
|
||||||
import de.dennisguse.opentracks.viewmodels.Mapping;
|
import de.dennisguse.opentracks.viewmodels.Mapping;
|
||||||
import de.dennisguse.opentracks.viewmodels.StatisticViewHolder;
|
import de.dennisguse.opentracks.viewmodels.StatisticViewHolder;
|
||||||
|
|
||||||
@@ -38,17 +39,24 @@ public class SettingsCustomLayoutEditAdapter extends RecyclerView.Adapter<Recycl
|
|||||||
private static final RecordingData demoData;
|
private static final RecordingData demoData;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
SegmentStatisticUpdater trackStatistics = new SegmentStatisticUpdater();
|
Statistics statistics = new Statistics(
|
||||||
trackStatistics.setStartTime(Instant.ofEpochMilli(0));
|
Instant.ofEpochMilli(0),
|
||||||
trackStatistics.setMovingTime(Duration.ofMinutes(0));
|
Instant.ofEpochMilli(0),
|
||||||
trackStatistics.setTotalTime(Duration.ofMinutes(0));
|
Duration.ofMinutes(0),
|
||||||
|
Duration.ofMinutes(0),
|
||||||
|
|
||||||
trackStatistics.setTotalDistance(Distance.of(0));
|
Distance.of(0),
|
||||||
|
false,
|
||||||
|
Speed.of(0),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
|
||||||
trackStatistics.setTotalAltitudeGain(0f);
|
new AltitudeGainLoss(0f, 0f),
|
||||||
trackStatistics.setTotalAltitudeLoss(0f);
|
|
||||||
Track track = new Track(ZoneOffset.UTC);
|
null,
|
||||||
track.setTrackStatistics(trackStatistics);
|
null
|
||||||
|
);
|
||||||
|
Track track = new Track(ZoneOffset.UTC); //TODO Pass statistics as well
|
||||||
|
|
||||||
Position position = new Position(
|
Position position = new Position(
|
||||||
Instant.ofEpochMilli(0),
|
Instant.ofEpochMilli(0),
|
||||||
@@ -61,7 +69,7 @@ public class SettingsCustomLayoutEditAdapter extends RecyclerView.Adapter<Recycl
|
|||||||
Speed.zero()
|
Speed.zero()
|
||||||
);
|
);
|
||||||
|
|
||||||
demoData = new RecordingData(track, new TrackPoint(TrackPoint.Type.TRACKPOINT, position), null, trackStatistics) ;
|
demoData = new RecordingData(track, new TrackPoint(TrackPoint.Type.TRACKPOINT, position), null, statistics);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RecordingLayout recordingLayout;
|
private RecordingLayout recordingLayout;
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ public abstract class GenericStatisticsViewHolder extends StatisticViewHolder<St
|
|||||||
.setReportSpeedOrPace(false)
|
.setReportSpeedOrPace(false)
|
||||||
.build(getContext());
|
.build(getContext());
|
||||||
|
|
||||||
Pair<String, String> valueAndUnit = speedFormatterSpeed.getSpeedParts(data.getStatisticsCurrentSegment().getAverageMovingSpeed());
|
Pair<String, String> valueAndUnit = speedFormatterSpeed.getSpeedParts(data.currentSegment().getAverageMovingSpeed());
|
||||||
|
|
||||||
getBinding().statsValue.setText(valueAndUnit.first);
|
getBinding().statsValue.setText(valueAndUnit.first);
|
||||||
getBinding().statsUnit.setText(valueAndUnit.second);
|
getBinding().statsUnit.setText(valueAndUnit.second);
|
||||||
@@ -220,7 +220,7 @@ public abstract class GenericStatisticsViewHolder extends StatisticViewHolder<St
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChanged(UnitSystem unitSystem, RecordingData data) {
|
public void onChanged(UnitSystem unitSystem, RecordingData data) {
|
||||||
String value = StringUtils.formatElapsedTime(data.getStatisticsCurrentSegment().getTotalTime());
|
String value = StringUtils.formatElapsedTime(data.currentSegment().totalTime());
|
||||||
|
|
||||||
getBinding().statsValue.setText(value);
|
getBinding().statsValue.setText(value);
|
||||||
getBinding().statsDescriptionMain.setText(getContext().getString(R.string.stats_elapsed_segment_time));
|
getBinding().statsDescriptionMain.setText(getContext().getString(R.string.stats_elapsed_segment_time));
|
||||||
|
|||||||
Reference in New Issue
Block a user