forked from upstream-mirrors/OpenTracks
IntervalStatisticsUpdater exposes Statistics (instead of Interval).
This commit is contained in:
+8
-8
@@ -165,7 +165,7 @@ public class VoiceAnnouncementUtilsTest {
|
|||||||
@Test
|
@Test
|
||||||
public void getAnnouncement_withInterval_metric_speed() {
|
public void getAnnouncement_withInterval_metric_speed() {
|
||||||
// given
|
// given
|
||||||
Pair<Track, IntervalStatisticsUpdater.Interval> data = buildTrackWithTrackPoints();
|
Pair<Track, Statistics> data = buildTrackWithTrackPoints();
|
||||||
|
|
||||||
SensorDataSet dataSet = Mockito.mock(SensorDataSet.class);
|
SensorDataSet dataSet = Mockito.mock(SensorDataSet.class);
|
||||||
Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused"));
|
Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused"));
|
||||||
@@ -205,7 +205,7 @@ public class VoiceAnnouncementUtilsTest {
|
|||||||
@Test
|
@Test
|
||||||
public void getAnnouncement_withInterval_metric_pace() {
|
public void getAnnouncement_withInterval_metric_pace() {
|
||||||
// given
|
// given
|
||||||
Pair<Track, IntervalStatisticsUpdater.Interval> data = buildTrackWithTrackPoints();
|
Pair<Track, Statistics> data = buildTrackWithTrackPoints();
|
||||||
|
|
||||||
SensorDataSet dataSet = Mockito.mock(SensorDataSet.class);
|
SensorDataSet dataSet = Mockito.mock(SensorDataSet.class);
|
||||||
Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused"));
|
Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused"));
|
||||||
@@ -320,7 +320,7 @@ public class VoiceAnnouncementUtilsTest {
|
|||||||
@Test
|
@Test
|
||||||
public void getAnnouncement_withInterval_imperial_speed() {
|
public void getAnnouncement_withInterval_imperial_speed() {
|
||||||
// given
|
// given
|
||||||
Pair<Track, IntervalStatisticsUpdater.Interval> data = buildTrackWithTrackPoints();
|
Pair<Track, Statistics> data = buildTrackWithTrackPoints();
|
||||||
|
|
||||||
SensorDataSet dataSet = Mockito.mock(SensorDataSet.class);
|
SensorDataSet dataSet = Mockito.mock(SensorDataSet.class);
|
||||||
Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused"));
|
Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused"));
|
||||||
@@ -360,7 +360,7 @@ public class VoiceAnnouncementUtilsTest {
|
|||||||
@Test
|
@Test
|
||||||
public void getAnnouncement_withInterval_imperial_pace() {
|
public void getAnnouncement_withInterval_imperial_pace() {
|
||||||
// given
|
// given
|
||||||
Pair<Track, IntervalStatisticsUpdater.Interval> data = buildTrackWithTrackPoints();
|
Pair<Track, Statistics> data = buildTrackWithTrackPoints();
|
||||||
|
|
||||||
SensorDataSet dataSet = Mockito.mock(SensorDataSet.class);
|
SensorDataSet dataSet = Mockito.mock(SensorDataSet.class);
|
||||||
Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused"));
|
Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused"));
|
||||||
@@ -378,7 +378,7 @@ public class VoiceAnnouncementUtilsTest {
|
|||||||
PreferencesUtils.setVoiceAnnounceAverageHeartRate(true);
|
PreferencesUtils.setVoiceAnnounceAverageHeartRate(true);
|
||||||
PreferencesUtils.setVoiceAnnounceLapHeartRate(true);
|
PreferencesUtils.setVoiceAnnounceLapHeartRate(true);
|
||||||
|
|
||||||
Pair<Track, IntervalStatisticsUpdater.Interval> data = buildTrackWithTrackPoints();
|
Pair<Track, Statistics> data = buildTrackWithTrackPoints();
|
||||||
|
|
||||||
SensorStatistics sensorStatistics = new SensorStatistics(HeartRate.of(180f), HeartRate.of(180f), null, null, null, null);
|
SensorStatistics sensorStatistics = new SensorStatistics(HeartRate.of(180f), HeartRate.of(180f), null, null, null, null);
|
||||||
|
|
||||||
@@ -404,7 +404,7 @@ public class VoiceAnnouncementUtilsTest {
|
|||||||
PreferencesUtils.setVoiceAnnounceAverageSpeedPace(false);
|
PreferencesUtils.setVoiceAnnounceAverageSpeedPace(false);
|
||||||
PreferencesUtils.setVoiceAnnounceLapSpeedPace(false);
|
PreferencesUtils.setVoiceAnnounceLapSpeedPace(false);
|
||||||
|
|
||||||
Pair<Track, IntervalStatisticsUpdater.Interval> data = buildTrackWithTrackPoints();
|
Pair<Track, Statistics> data = buildTrackWithTrackPoints();
|
||||||
|
|
||||||
SensorStatistics sensorStatistics = new SensorStatistics(HeartRate.of(180f), HeartRate.of(180f), null, null, null, null);
|
SensorStatistics sensorStatistics = new SensorStatistics(HeartRate.of(180f), HeartRate.of(180f), null, null, null, null);
|
||||||
|
|
||||||
@@ -433,7 +433,7 @@ public class VoiceAnnouncementUtilsTest {
|
|||||||
assertEquals("1.2 miles", MessageFormat.format(template, Map.of("n", 1.18)));
|
assertEquals("1.2 miles", MessageFormat.format(template, Map.of("n", 1.18)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Pair<Track, IntervalStatisticsUpdater.Interval> buildTrackWithTrackPoints() {
|
private static Pair<Track, Statistics> buildTrackWithTrackPoints() {
|
||||||
int numberOfPoints = 1000;
|
int numberOfPoints = 1000;
|
||||||
|
|
||||||
ArrayList<TrackPoint> trackPoints = new ArrayList<>();
|
ArrayList<TrackPoint> trackPoints = new ArrayList<>();
|
||||||
@@ -443,7 +443,7 @@ public class VoiceAnnouncementUtilsTest {
|
|||||||
|
|
||||||
IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000));
|
IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000));
|
||||||
intervalStatistics.addTrackPoints(trackPoints.iterator());
|
intervalStatistics.addTrackPoints(trackPoints.iterator());
|
||||||
IntervalStatisticsUpdater.Interval lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1);
|
Statistics lastInterval = intervalStatistics.getLastInterval();
|
||||||
|
|
||||||
Track track = new Track(new Statistics(
|
Track track = new Track(new Statistics(
|
||||||
Instant.EPOCH,
|
Instant.EPOCH,
|
||||||
|
|||||||
+17
-19
@@ -14,6 +14,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import de.dennisguse.opentracks.content.data.TestDataUtil;
|
import de.dennisguse.opentracks.content.data.TestDataUtil;
|
||||||
import de.dennisguse.opentracks.data.models.Distance;
|
import de.dennisguse.opentracks.data.models.Distance;
|
||||||
|
import de.dennisguse.opentracks.data.models.Statistics;
|
||||||
import de.dennisguse.opentracks.data.models.Track;
|
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.stats.TrackStatisticsUpdater;
|
import de.dennisguse.opentracks.stats.TrackStatisticsUpdater;
|
||||||
@@ -126,25 +127,25 @@ public class IntervalStatisticsUpdaterTest {
|
|||||||
|
|
||||||
intervalStatistics.addTrackPoints(trackPoints.iterator());
|
intervalStatistics.addTrackPoints(trackPoints.iterator());
|
||||||
|
|
||||||
List<IntervalStatisticsUpdater.Interval> intervalList = intervalStatistics.getIntervalList();
|
List<Statistics> intervalList = intervalStatistics.getIntervalList();
|
||||||
Distance totalDistance = Distance.of(0);
|
Distance totalDistance = Distance.of(0);
|
||||||
float totalTime = 0L;
|
float totalTime = 0L;
|
||||||
Float totalGain = null;
|
Float totalGain = null;
|
||||||
Float totalLoss = null;
|
Float totalLoss = null;
|
||||||
for (IntervalStatisticsUpdater.Interval i : intervalList) {
|
for (Statistics i : intervalList) {
|
||||||
totalDistance = totalDistance.plus(i.getDistance());
|
totalDistance = totalDistance.plus(i.totalDistance());
|
||||||
totalTime += i.getDistance().toM() / i.getSpeed().toMPS();
|
totalTime += i.totalDistance().toM() / i.getAverageSpeed().toMPS();
|
||||||
|
|
||||||
if (totalGain == null) {
|
if (totalGain == null) {
|
||||||
totalGain = i.getGain_m();
|
totalGain = i.altitudeGainLoss() != null ? i.altitudeGainLoss().gain_m() : null;
|
||||||
} else if (i.getGain_m() != null) {
|
} else if (i.altitudeGainLoss() != null) {
|
||||||
totalGain += i.getGain_m();
|
totalGain += i.altitudeGainLoss().gain_m();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (totalLoss == null) {
|
if (totalLoss == null) {
|
||||||
totalLoss = i.getLoss_m();
|
totalLoss = i.altitudeGainLoss() != null ? i.altitudeGainLoss().loss_m() : null;
|
||||||
} else if (i.getLoss_m() != null) {
|
} else if (i.altitudeGainLoss() != null) {
|
||||||
totalLoss += i.getLoss_m();
|
totalLoss += i.altitudeGainLoss().loss_m();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,22 +153,19 @@ public class IntervalStatisticsUpdaterTest {
|
|||||||
assertEquals(track.getStatistics().totalTime().toSeconds(), totalTime, 0.01);
|
assertEquals(track.getStatistics().totalTime().toSeconds(), totalTime, 0.01);
|
||||||
assertEquals(track.getStatistics().totalDistance().toM(), totalDistance.toM(), 0.01);
|
assertEquals(track.getStatistics().totalDistance().toM(), totalDistance.toM(), 0.01);
|
||||||
assertEquals(intervalList.size(), (int) Math.ceil(track.getStatistics().totalDistance().toM() / distanceInterval));
|
assertEquals(intervalList.size(), (int) Math.ceil(track.getStatistics().totalDistance().toM() / distanceInterval));
|
||||||
if (totalGain != null) {
|
if (totalGain != null && totalLoss != null) {
|
||||||
assertEquals(totalGain, numberOfPoints * TestDataUtil.ALTITUDE_GAIN, 0.1);
|
assertEquals(totalGain, numberOfPoints * TestDataUtil.ALTITUDE_GAIN, 0.1);
|
||||||
} else {
|
|
||||||
assertTrue(intervalStatistics.getIntervalList().stream().noneMatch(IntervalStatisticsUpdater.Interval::hasGain));
|
|
||||||
}
|
|
||||||
if (totalLoss != null) {
|
|
||||||
assertEquals(totalLoss, numberOfPoints * TestDataUtil.ALTITUDE_LOSS, 0.1);
|
assertEquals(totalLoss, numberOfPoints * TestDataUtil.ALTITUDE_LOSS, 0.1);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
assertTrue(intervalStatistics.getIntervalList().stream().noneMatch(IntervalStatisticsUpdater.Interval::hasLoss));
|
assertTrue(intervalStatistics.getIntervalList().stream().noneMatch(i -> i.altitudeGainLoss() != null));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < intervalList.size() - 1; i++) {
|
for (int i = 0; i < intervalList.size() - 1; i++) {
|
||||||
assertEquals(intervalList.get(i).getDistance().toM(), distanceInterval, 0.001);
|
assertEquals(intervalList.get(i).totalDistance().toM(), distanceInterval, 0.001);
|
||||||
totalDistance = totalDistance.minus(intervalList.get(i).getDistance());
|
totalDistance = totalDistance.minus(intervalList.get(i).totalDistance());
|
||||||
}
|
}
|
||||||
assertEquals(intervalList.get(intervalList.size() - 1).getDistance().toM(), totalDistance.toM(), 0.01);
|
assertEquals(intervalList.get(intervalList.size() - 1).totalDistance().toM(), totalDistance.toM(), 0.01);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Pair<Track, List<TrackPoint>> buildTrackWithTrackPoints(int numberOfPoints) {
|
private static Pair<Track, List<TrackPoint>> buildTrackWithTrackPoints(int numberOfPoints) {
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ import de.dennisguse.opentracks.stats.SegmentStatisticUpdater;
|
|||||||
/**
|
/**
|
||||||
* {@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,
|
public record RecordingData(Track track, TrackPoint latestTrackPoint, SensorDataSet sensorDataSet, Statistics currentSegment) {
|
||||||
Statistics currentSegment) {
|
|
||||||
public String getTrackCategory() {
|
public String getTrackCategory() {
|
||||||
if (track == null) {
|
if (track == null) {
|
||||||
return "";
|
return "";
|
||||||
|
|||||||
+2
-1
@@ -149,9 +149,10 @@ public class VoiceAnnouncementManager implements SharedPreferences.OnSharedPrefe
|
|||||||
startTrackPointId = null;
|
startTrackPointId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO Avoid reloading (some) TrackPoints just to announce the last interval.
|
||||||
try (AutoCloseableIterator<TrackPoint> trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), startTrackPointId)) {
|
try (AutoCloseableIterator<TrackPoint> trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), startTrackPointId)) {
|
||||||
startTrackPointId = intervalStatistics.addTrackPoints(trackPointIterator);
|
startTrackPointId = intervalStatistics.addTrackPoints(trackPointIterator);
|
||||||
IntervalStatisticsUpdater.Interval lastInterval = intervalStatistics.getLastInterval();
|
Statistics lastInterval = intervalStatistics.getLastInterval();
|
||||||
SensorStatistics sensorStatistics = null;
|
SensorStatistics sensorStatistics = null;
|
||||||
if (track.getId() != null) {
|
if (track.getId() != null) {
|
||||||
sensorStatistics = contentProviderUtils.getSensorStats(track.getId());
|
sensorStatistics = contentProviderUtils.getSensorStats(track.getId());
|
||||||
|
|||||||
+6
-7
@@ -38,7 +38,6 @@ import de.dennisguse.opentracks.data.models.Track;
|
|||||||
import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet;
|
import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet;
|
||||||
import de.dennisguse.opentracks.settings.UnitSystem;
|
import de.dennisguse.opentracks.settings.UnitSystem;
|
||||||
import de.dennisguse.opentracks.stats.SensorStatistics;
|
import de.dennisguse.opentracks.stats.SensorStatistics;
|
||||||
import de.dennisguse.opentracks.ui.intervals.IntervalStatisticsUpdater;
|
|
||||||
import de.dennisguse.opentracks.util.StringUtils;
|
import de.dennisguse.opentracks.util.StringUtils;
|
||||||
|
|
||||||
class VoiceAnnouncementUtils {
|
class VoiceAnnouncementUtils {
|
||||||
@@ -51,7 +50,7 @@ class VoiceAnnouncementUtils {
|
|||||||
.append(context.getString(R.string.voiceIdle));
|
.append(context.getString(R.string.voiceIdle));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Spannable createStatistics(Context context, Track track, SensorDataSet sensorDataSet, UnitSystem unitSystem, boolean isReportSpeed, @Nullable IntervalStatisticsUpdater.Interval currentInterval, @Nullable SensorStatistics sensorStatistics) {
|
static Spannable createStatistics(Context context, Track track, SensorDataSet sensorDataSet, UnitSystem unitSystem, boolean isReportSpeed, @Nullable Statistics currentInterval, @Nullable SensorStatistics sensorStatistics) {
|
||||||
Statistics trackStatistics = track.getStatistics();
|
Statistics trackStatistics = track.getStatistics();
|
||||||
|
|
||||||
SpannableStringBuilder builder = new SpannableStringBuilder();
|
SpannableStringBuilder builder = new SpannableStringBuilder();
|
||||||
@@ -62,7 +61,7 @@ class VoiceAnnouncementUtils {
|
|||||||
|
|
||||||
Distance totalDistance = trackStatistics.totalDistance();
|
Distance totalDistance = trackStatistics.totalDistance();
|
||||||
Speed averageMovingSpeed = trackStatistics.getAverageMovingSpeed();
|
Speed averageMovingSpeed = trackStatistics.getAverageMovingSpeed();
|
||||||
Speed currentDistancePerTime = currentInterval != null ? currentInterval.getSpeed() : null;
|
Speed currentDistancePerTime = currentInterval != null ? currentInterval.getAverageSpeed() : null;
|
||||||
|
|
||||||
int perUnitStringId = R.string.empty;
|
int perUnitStringId = R.string.empty;
|
||||||
int distanceId = R.string.voiceDistance;
|
int distanceId = R.string.voiceDistance;
|
||||||
@@ -179,8 +178,8 @@ class VoiceAnnouncementUtils {
|
|||||||
appendCardinal(builder, context.getString(R.string.sensor_state_heart_rate_value, averageHeartRate), averageHeartRate);
|
appendCardinal(builder, context.getString(R.string.sensor_state_heart_rate_value, averageHeartRate), averageHeartRate);
|
||||||
builder.append(".");
|
builder.append(".");
|
||||||
}
|
}
|
||||||
if (shouldVoiceAnnounceLapHeartRate() && currentInterval != null && currentInterval.hasAverageHeartRate()) {
|
if (shouldVoiceAnnounceLapHeartRate() && currentInterval != null && currentInterval.avgHeartRate() != null) {
|
||||||
int currentHeartRate = Math.round(currentInterval.getAverageHeartRate().getBPM());
|
int currentHeartRate = Math.round(currentInterval.avgHeartRate().getBPM());
|
||||||
|
|
||||||
builder.append(" ")
|
builder.append(" ")
|
||||||
.append(context.getString(R.string.lap_heart_rate));
|
.append(context.getString(R.string.lap_heart_rate));
|
||||||
@@ -188,8 +187,8 @@ class VoiceAnnouncementUtils {
|
|||||||
builder.append(".");
|
builder.append(".");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldVoiceAnnounceLapPower() && currentInterval != null && currentInterval.hasAveragePower()) {
|
if (shouldVoiceAnnounceLapPower() && currentInterval != null && currentInterval.avgPower() != null) {
|
||||||
int currentPower = Math.round(currentInterval.getAveragePower().getW());
|
int currentPower = Math.round(currentInterval.avgPower().getW());
|
||||||
if (shouldVoiceAnnounceUnit()) {
|
if (shouldVoiceAnnounceUnit()) {
|
||||||
String template = context.getResources().getString(R.string.power_x_watt);
|
String template = context.getResources().getString(R.string.power_x_watt);
|
||||||
builder.append(" ")
|
builder.append(" ")
|
||||||
|
|||||||
+12
-17
@@ -7,18 +7,20 @@ import android.view.ViewGroup;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.data.models.Distance;
|
import de.dennisguse.opentracks.data.models.Distance;
|
||||||
import de.dennisguse.opentracks.data.models.DistanceFormatter;
|
import de.dennisguse.opentracks.data.models.DistanceFormatter;
|
||||||
import de.dennisguse.opentracks.data.models.SpeedFormatter;
|
import de.dennisguse.opentracks.data.models.SpeedFormatter;
|
||||||
|
import de.dennisguse.opentracks.data.models.Statistics;
|
||||||
import de.dennisguse.opentracks.databinding.IntervalStatsListItemBinding;
|
import de.dennisguse.opentracks.databinding.IntervalStatsListItemBinding;
|
||||||
import de.dennisguse.opentracks.settings.UnitSystem;
|
import de.dennisguse.opentracks.settings.UnitSystem;
|
||||||
import de.dennisguse.opentracks.util.StringUtils;
|
import de.dennisguse.opentracks.util.StringUtils;
|
||||||
|
|
||||||
public class IntervalStatisticsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
public class IntervalStatisticsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||||
|
|
||||||
private List<IntervalStatisticsUpdater.Interval> intervalList;
|
private List<Statistics> intervalList = new ArrayList<>();
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final StackMode stackMode;
|
private final StackMode stackMode;
|
||||||
private UnitSystem unitSystem;
|
private UnitSystem unitSystem;
|
||||||
@@ -43,46 +45,39 @@ public class IntervalStatisticsAdapter extends RecyclerView.Adapter<RecyclerView
|
|||||||
int nextPosition = actualPosition + 1;
|
int nextPosition = actualPosition + 1;
|
||||||
boolean isLast = actualPosition == getItemCount() - 1;
|
boolean isLast = actualPosition == getItemCount() - 1;
|
||||||
IntervalStatisticsAdapter.ViewHolder viewHolder = (IntervalStatisticsAdapter.ViewHolder) holder;
|
IntervalStatisticsAdapter.ViewHolder viewHolder = (IntervalStatisticsAdapter.ViewHolder) holder;
|
||||||
IntervalStatisticsUpdater.Interval interval = intervalList.get(actualPosition);
|
Statistics interval = intervalList.get(actualPosition);
|
||||||
viewHolder.itemView.setTag(actualPosition);
|
viewHolder.itemView.setTag(actualPosition);
|
||||||
|
|
||||||
Distance sumDistance;
|
Distance sumDistance;
|
||||||
if (isLast && actualPosition > 0) {
|
if (isLast && actualPosition > 0) {
|
||||||
sumDistance = intervalList.get(actualPosition - 1).getDistance()
|
sumDistance = intervalList.get(actualPosition - 1).totalDistance()
|
||||||
.multipliedBy(actualPosition)
|
.multipliedBy(actualPosition)
|
||||||
.plus(interval.getDistance());
|
.plus(interval.totalDistance());
|
||||||
} else {
|
} else {
|
||||||
sumDistance = interval.getDistance().multipliedBy(nextPosition);
|
sumDistance = interval.totalDistance().multipliedBy(nextPosition);
|
||||||
}
|
}
|
||||||
viewHolder.viewBinding.intervalItemDistance.setText(DistanceFormatter.Builder()
|
viewHolder.viewBinding.intervalItemDistance.setText(DistanceFormatter.Builder()
|
||||||
.setUnit(unitSystem)
|
.setUnit(unitSystem)
|
||||||
.build(context).formatDistance(sumDistance));
|
.build(context).formatDistance(sumDistance));
|
||||||
|
|
||||||
SpeedFormatter formatter = SpeedFormatter.Builder().setUnit(unitSystem).setReportSpeedOrPace(isReportSpeed).build(context);
|
SpeedFormatter formatter = SpeedFormatter.Builder().setUnit(unitSystem).setReportSpeedOrPace(isReportSpeed).build(context);
|
||||||
viewHolder.viewBinding.intervalItemRate.setText(formatter.formatSpeed(interval.getSpeed()));
|
viewHolder.viewBinding.intervalItemRate.setText(formatter.formatSpeed(interval.getAverageSpeed()));
|
||||||
|
|
||||||
viewHolder.viewBinding.intervalItemGain.setText(StringUtils.formatAltitude(context, interval.getGain_m(), unitSystem));
|
viewHolder.viewBinding.intervalItemGain.setText(StringUtils.formatAltitude(context, interval.altitudeGainLoss() != null ? interval.altitudeGainLoss().gain_m() : null, unitSystem));
|
||||||
viewHolder.viewBinding.intervalItemLoss.setText(StringUtils.formatAltitude(context, interval.getLoss_m(), unitSystem));
|
viewHolder.viewBinding.intervalItemLoss.setText(StringUtils.formatAltitude(context, interval.altitudeGainLoss() != null ? interval.altitudeGainLoss().loss_m() : null, unitSystem));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
if (intervalList == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return intervalList.size();
|
return intervalList.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<IntervalStatisticsUpdater.Interval> swapData(List<IntervalStatisticsUpdater.Interval> data, UnitSystem unitSystem, boolean isReportSpeed) {
|
public void swapData(@NonNull List<Statistics> data, UnitSystem unitSystem, boolean isReportSpeed) {
|
||||||
this.unitSystem = unitSystem;
|
this.unitSystem = unitSystem;
|
||||||
this.isReportSpeed = isReportSpeed;
|
this.isReportSpeed = isReportSpeed;
|
||||||
intervalList = data;
|
intervalList = data;
|
||||||
|
|
||||||
if (data != null) {
|
this.notifyDataSetChanged();
|
||||||
this.notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import java.util.concurrent.Executors;
|
|||||||
|
|
||||||
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
||||||
import de.dennisguse.opentracks.data.models.Distance;
|
import de.dennisguse.opentracks.data.models.Distance;
|
||||||
|
import de.dennisguse.opentracks.data.models.Statistics;
|
||||||
import de.dennisguse.opentracks.data.models.Track;
|
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.data.tables.TrackPointsColumns;
|
import de.dennisguse.opentracks.data.tables.TrackPointsColumns;
|
||||||
@@ -32,7 +33,7 @@ public class IntervalStatisticsModel extends AndroidViewModel {
|
|||||||
|
|
||||||
private static final String TAG = IntervalStatisticsModel.class.getSimpleName();
|
private static final String TAG = IntervalStatisticsModel.class.getSimpleName();
|
||||||
|
|
||||||
private MutableLiveData<List<IntervalStatisticsUpdater.Interval>> intervalsLiveData;
|
private MutableLiveData<List<Statistics>> intervalsLiveData;
|
||||||
private IntervalStatisticsUpdater intervalStatistics;
|
private IntervalStatisticsUpdater intervalStatistics;
|
||||||
private Distance distanceInterval;
|
private Distance distanceInterval;
|
||||||
private final ContentResolver contentResolver;
|
private final ContentResolver contentResolver;
|
||||||
@@ -65,7 +66,7 @@ public class IntervalStatisticsModel extends AndroidViewModel {
|
|||||||
handler = null;
|
handler = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MutableLiveData<List<IntervalStatisticsUpdater.Interval>> getIntervalStats(Track.Id trackId, UnitSystem unitSystem, @Nullable IntervalOption interval) {
|
public MutableLiveData<List<Statistics>> getIntervalStats(Track.Id trackId, UnitSystem unitSystem, @Nullable IntervalOption interval) {
|
||||||
if (intervalsLiveData == null) {
|
if (intervalsLiveData == null) {
|
||||||
if (interval == null) {
|
if (interval == null) {
|
||||||
interval = IntervalOption.OPTION_1;
|
interval = IntervalOption.OPTION_1;
|
||||||
|
|||||||
+23
-17
@@ -7,6 +7,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
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;
|
||||||
@@ -74,8 +75,8 @@ public class IntervalStatisticsUpdater {
|
|||||||
return trackPoint != null ? trackPoint.getId() : null;
|
return trackPoint != null ? trackPoint.getId() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Interval> getIntervalList() {
|
public List<Statistics> getIntervalList() {
|
||||||
return intervalList;
|
return intervalList.stream().map(Interval::toStatistics).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,14 +85,15 @@ public class IntervalStatisticsUpdater {
|
|||||||
*
|
*
|
||||||
* @return the interval object or null if any interval is completed.
|
* @return the interval object or null if any interval is completed.
|
||||||
*/
|
*/
|
||||||
public Interval getLastInterval() {
|
@Nullable
|
||||||
|
public Statistics getLastInterval() {
|
||||||
if (intervalList.size() == 1 && intervalList.get(0).getDistance().lessThan(distanceInterval)) {
|
if (intervalList.size() == 1 && intervalList.get(0).getDistance().lessThan(distanceInterval)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = intervalList.size() - 1; i >= 0; i--) {
|
for (int i = intervalList.size() - 1; i >= 0; i--) {
|
||||||
if (intervalList.get(i).getDistance().greaterOrEqualThan(distanceInterval)) {
|
if (intervalList.get(i).getDistance().greaterOrEqualThan(distanceInterval)) {
|
||||||
return this.intervalList.get(i);
|
return this.intervalList.get(i).toStatistics();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +101,8 @@ public class IntervalStatisticsUpdater {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO Could be replaced with Statistics?
|
//TODO Could be replaced with Statistics?
|
||||||
public static class Interval {
|
@Deprecated
|
||||||
|
private static class Interval {
|
||||||
private Distance distance = Distance.of(0);
|
private Distance distance = Distance.of(0);
|
||||||
private Duration time = Duration.ofSeconds(0);
|
private Duration time = Duration.ofSeconds(0);
|
||||||
private Float gain_m;
|
private Float gain_m;
|
||||||
@@ -145,18 +148,6 @@ public class IntervalStatisticsUpdater {
|
|||||||
return gain_m != null;
|
return gain_m != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Float getGain_m() {
|
|
||||||
return gain_m;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasLoss() {
|
|
||||||
return loss_m != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Float getLoss_m() {
|
|
||||||
return loss_m;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasAverageHeartRate() {
|
public boolean hasAverageHeartRate() {
|
||||||
return avgHeartRate != null;
|
return avgHeartRate != null;
|
||||||
}
|
}
|
||||||
@@ -201,5 +192,20 @@ public class IntervalStatisticsUpdater {
|
|||||||
avgHeartRate = trackStatistics.avgHeartRate();
|
avgHeartRate = trackStatistics.avgHeartRate();
|
||||||
avgPower = trackStatistics.avgPower();
|
avgPower = trackStatistics.avgPower();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Statistics toStatistics() {
|
||||||
|
return new Statistics(
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
time,
|
||||||
|
null,
|
||||||
|
distance,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
gain_m != null ? new AltitudeGainLoss(gain_m, loss_m) : null,
|
||||||
|
avgHeartRate,
|
||||||
|
avgPower
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import java.util.Objects;
|
|||||||
import de.dennisguse.opentracks.R;
|
import de.dennisguse.opentracks.R;
|
||||||
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
||||||
import de.dennisguse.opentracks.data.models.DistanceFormatter;
|
import de.dennisguse.opentracks.data.models.DistanceFormatter;
|
||||||
|
import de.dennisguse.opentracks.data.models.Statistics;
|
||||||
import de.dennisguse.opentracks.data.models.Track;
|
import de.dennisguse.opentracks.data.models.Track;
|
||||||
import de.dennisguse.opentracks.databinding.IntervalListViewBinding;
|
import de.dennisguse.opentracks.databinding.IntervalListViewBinding;
|
||||||
import de.dennisguse.opentracks.settings.PreferencesUtils;
|
import de.dennisguse.opentracks.settings.PreferencesUtils;
|
||||||
@@ -192,7 +193,7 @@ public class IntervalsFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
viewBinding.intervalRate.setText(isReportSpeed ? getString(R.string.stats_speed) : getString(R.string.stats_pace));
|
viewBinding.intervalRate.setText(isReportSpeed ? getString(R.string.stats_speed) : getString(R.string.stats_pace));
|
||||||
LiveData<List<IntervalStatisticsUpdater.Interval>> liveData = viewModel.getIntervalStats(trackId, unitSystem, selectedInterval);
|
LiveData<List<Statistics>> liveData = viewModel.getIntervalStats(trackId, unitSystem, selectedInterval);
|
||||||
liveData.observe(getActivity(), intervalList -> adapter.swapData(intervalList, unitSystem, isReportSpeed));
|
liveData.observe(getActivity(), intervalList -> adapter.swapData(intervalList, unitSystem, isReportSpeed));
|
||||||
|
|
||||||
setIntervalsDropdownText();
|
setIntervalsDropdownText();
|
||||||
|
|||||||
Reference in New Issue
Block a user