diff --git a/src/androidTest/java/de/dennisguse/opentracks/util/AnnouncementUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/util/AnnouncementUtilsTest.java index 9abd2369a..003f2d86f 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/util/AnnouncementUtilsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/util/AnnouncementUtilsTest.java @@ -52,7 +52,7 @@ public class AnnouncementUtilsTest { stats.setTotalAltitudeGain(6000f); List trackPoints = TestDataUtil.createTrack(new Track.Id(System.currentTimeMillis()), 10).second; - IntervalStatistics intervalStatistics = new IntervalStatistics(trackPoints, Distance.of(1000)); + IntervalStatistics intervalStatistics = new IntervalStatistics(trackPoints, Distance.of(1000), Distance.of(0)); IntervalStatistics.Interval lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); // when diff --git a/src/androidTest/java/de/dennisguse/opentracks/viewmodels/IntervalStatisticsTest.java b/src/androidTest/java/de/dennisguse/opentracks/viewmodels/IntervalStatisticsTest.java index aed2bffb7..a0d558a1e 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/viewmodels/IntervalStatisticsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/viewmodels/IntervalStatisticsTest.java @@ -114,7 +114,7 @@ public class IntervalStatisticsTest { } private void whenAndThen(List trackPoints, TrackStatistics trackStatistics, float distanceInterval) { - IntervalStatistics intervalStatistics = new IntervalStatistics(trackPoints, Distance.of(distanceInterval)); + IntervalStatistics intervalStatistics = new IntervalStatistics(trackPoints, Distance.of(distanceInterval), Distance.of(0)); List intervalList = intervalStatistics.getIntervalList(); Distance totalDistance = Distance.of(0); float totalTime = 0L; diff --git a/src/main/java/de/dennisguse/opentracks/fragments/IntervalsFragment.java b/src/main/java/de/dennisguse/opentracks/fragments/IntervalsFragment.java index e2ae77d4b..8830cbdae 100644 --- a/src/main/java/de/dennisguse/opentracks/fragments/IntervalsFragment.java +++ b/src/main/java/de/dennisguse/opentracks/fragments/IntervalsFragment.java @@ -140,11 +140,14 @@ public class IntervalsFragment extends Fragment implements TrackDataListener { @Override public void onResume() { super.onResume(); + + resumeTrackDataHub(); + sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener); sharedPreferenceChangeListener.onSharedPreferenceChanged(sharedPreferences, null); + viewModel = new ViewModelProvider(getActivity()).get(IntervalStatisticsModel.class); loadIntervals(); - resumeTrackDataHub(); } @Override @@ -224,28 +227,28 @@ public class IntervalsFragment extends Fragment implements TrackDataListener { @Override public void clearTrackPoints() { - if (isResumed()) { + if (isResumed() && viewModel != null) { viewModel.clear(); } } @Override public void onSampledInTrackPoint(@NonNull TrackPoint trackPoint, @NonNull TrackStatistics unused, Speed unused2, double unused3) { - if (isResumed()) { + if (isResumed() && viewModel != null) { viewModel.add(trackPoint); } } @Override public void onSampledOutTrackPoint(@NonNull TrackPoint trackPoint, @NonNull TrackStatistics unused) { - if (isResumed()) { + if (isResumed() && viewModel != null) { viewModel.add(trackPoint); } } @Override public void onNewTrackPointsDone() { - if (isResumed()) { + if (isResumed() && viewModel != null) { runOnUiThread(viewModel::onNewTrackPoints); } } diff --git a/src/main/java/de/dennisguse/opentracks/services/tasks/AnnouncementPeriodicTask.java b/src/main/java/de/dennisguse/opentracks/services/tasks/AnnouncementPeriodicTask.java index 2d5503629..722a5974c 100644 --- a/src/main/java/de/dennisguse/opentracks/services/tasks/AnnouncementPeriodicTask.java +++ b/src/main/java/de/dennisguse/opentracks/services/tasks/AnnouncementPeriodicTask.java @@ -187,8 +187,9 @@ public class AnnouncementPeriodicTask implements PeriodicTask { boolean isMetricUnits = PreferencesUtils.isMetricUnits(sharedPreferences, context); boolean isReportSpeed = PreferencesUtils.isReportSpeed(sharedPreferences, context, category); + Distance minGPSDistance = PreferencesUtils.getRecordingDistanceInterval(sharedPreferences, context); - IntervalStatistics intervalStatistics = new IntervalStatistics(trackPoints, Distance.one(isMetricUnits)); + IntervalStatistics intervalStatistics = new IntervalStatistics(trackPoints, Distance.one(isMetricUnits), minGPSDistance); IntervalStatistics.Interval lastInterval = intervalStatistics.getLastInterval(); String announcement = AnnouncementUtils.getAnnouncement(context, trackStatistics, isMetricUnits, isReportSpeed, lastInterval); diff --git a/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatistics.java b/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatistics.java index 307899305..4650a36c2 100644 --- a/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatistics.java +++ b/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatistics.java @@ -1,6 +1,7 @@ package de.dennisguse.opentracks.viewmodels; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import java.time.Duration; import java.util.ArrayList; @@ -9,12 +10,19 @@ import java.util.List; import de.dennisguse.opentracks.content.data.Distance; import de.dennisguse.opentracks.content.data.Speed; import de.dennisguse.opentracks.content.data.TrackPoint; +import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.TrackStatisticsUpdater; public class IntervalStatistics { private final List intervalList = new ArrayList<>(); private final Distance distanceInterval; - public IntervalStatistics(@NonNull List trackPoints, Distance distanceInterval) { + /** + * @param trackPoints the list of TrackPoint. + * @param distanceInterval distance of every interval. + * @param minGPSDistance the setting value for GPS distance. + */ + public IntervalStatistics(@NonNull List trackPoints, Distance distanceInterval, Distance minGPSDistance) { intervalList.clear(); this.distanceInterval = distanceInterval; @@ -22,30 +30,29 @@ public class IntervalStatistics { return; } + TrackStatisticsUpdater trackStatisticsUpdater = new TrackStatisticsUpdater(); Interval interval = new Interval(); - interval.gain_m += trackPoints.get(0).hasAltitudeGain() ? trackPoints.get(0).getAltitudeGain() : 0; - interval.loss_m += trackPoints.get(0).hasAltitudeLoss() ? trackPoints.get(0).getAltitudeLoss() : 0; - for (int i = 1; i < trackPoints.size(); i++) { - TrackPoint prevTrackPoint = trackPoints.get(i - 1); - TrackPoint trackPoint = trackPoints.get(i); - if (trackPoint.hasLocation() && prevTrackPoint.hasLocation()) { - interval.distance = interval.distance.plus(prevTrackPoint.distanceToPrevious(trackPoint)); - interval.time = interval.time.plus(Duration.between(prevTrackPoint.getTime(), trackPoint.getTime())); - interval.gain_m += trackPoint.hasAltitudeGain() ? trackPoint.getAltitudeGain() : 0; - interval.loss_m += trackPoint.hasAltitudeLoss() ? trackPoint.getAltitudeLoss() : 0; + for (TrackPoint trackPoint : trackPoints) { + trackStatisticsUpdater.addTrackPoint(trackPoint, minGPSDistance); - if (interval.distance.greaterThan(distanceInterval)) { - Interval adjustedInterval = new Interval(interval, distanceInterval.dividedBy(interval.distance)); + if (trackStatisticsUpdater.getTrackStatistics().getTotalDistance().plus(interval.distance).greaterOrEqualThan(distanceInterval)) { + interval.update(trackStatisticsUpdater.getTrackStatistics(), trackPoint); - intervalList.add(adjustedInterval); + double adjustFactor = distanceInterval.dividedBy(interval.distance); + Interval adjustedInterval = new Interval(interval); + adjustedInterval.adjust(adjustFactor); - interval = new Interval(interval.distance.minus(adjustedInterval.distance), interval.time.minus(adjustedInterval.time)); - } + intervalList.add(adjustedInterval); + + interval = new Interval(interval.distance.minus(adjustedInterval.distance), interval.time.minus(adjustedInterval.time)); + trackStatisticsUpdater = new TrackStatisticsUpdater(); + trackStatisticsUpdater.addTrackPoint(trackPoint, minGPSDistance); } } - if (interval.distance.greaterThan(Distance.of(1))) { + if (trackStatisticsUpdater.getTrackStatistics().getTotalDistance().toM() >= 1d) { + interval.update(trackStatisticsUpdater.getTrackStatistics(), null); intervalList.add(interval); } } @@ -77,8 +84,8 @@ public class IntervalStatistics { public static class Interval { private Distance distance = Distance.of(0); private Duration time = Duration.ofSeconds(0); - private float gain_m = 0f; - private float loss_m = 0f; + private float gain_m; + private float loss_m; public Interval() { } @@ -96,6 +103,18 @@ public class IntervalStatistics { loss_m = i.loss_m; } + public Interval(Interval i) { + distance = i.distance; + time = i.time; + gain_m = i.gain_m; + loss_m = i.loss_m; + } + + public void adjust(double adjustFactor) { + distance = distance.multipliedBy(adjustFactor); + time = Duration.ofMillis((long) (time.toMillis() * adjustFactor)); + } + public Distance getDistance() { return distance; } @@ -111,5 +130,16 @@ public class IntervalStatistics { public float getLoss_m() { return loss_m; } + + public void update(TrackStatistics trackStatistics, @Nullable TrackPoint lastTrackPoint) { + distance = distance.plus(trackStatistics.getTotalDistance()); + time = time.plus(trackStatistics.getTotalTime()); + gain_m = trackStatistics.hasTotalAltitudeGain() ? trackStatistics.getTotalAltitudeGain() : gain_m; + loss_m = trackStatistics.hasTotalAltitudeLoss() ? trackStatistics.getTotalAltitudeLoss() : loss_m; + if (lastTrackPoint != null) { + gain_m = lastTrackPoint.hasAltitudeGain() ? gain_m - lastTrackPoint.getAltitudeGain() : gain_m; + loss_m = lastTrackPoint.hasAltitudeLoss() ? loss_m - lastTrackPoint.getAltitudeLoss() : loss_m; + } + } } } diff --git a/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatisticsModel.java b/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatisticsModel.java index 079e19bfd..ce2d1f944 100644 --- a/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatisticsModel.java +++ b/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatisticsModel.java @@ -12,6 +12,8 @@ import java.util.List; import de.dennisguse.opentracks.content.data.Distance; import de.dennisguse.opentracks.content.data.TrackPoint; +import de.dennisguse.opentracks.util.PreferencesUtils; +import de.dennisguse.opentracks.util.UnitConversions; /** * This model is used to load intervals for a track. @@ -22,9 +24,11 @@ public class IntervalStatisticsModel extends AndroidViewModel { private final List trackPoints = new ArrayList<>(); private MutableLiveData> intervalsLiveData; private Distance distanceInterval; + private Distance minGPSDistance; public IntervalStatisticsModel(@NonNull Application application) { super(application); + minGPSDistance = PreferencesUtils.getRecordingDistanceInterval(PreferencesUtils.getSharedPreferences(application), application); } public MutableLiveData> getIntervalStats(boolean metricUnits, @Nullable IntervalOption interval) { @@ -43,7 +47,7 @@ public class IntervalStatisticsModel extends AndroidViewModel { } private void loadIntervalStatistics() { - IntervalStatistics intervalStatistics = new IntervalStatistics(trackPoints, distanceInterval); + IntervalStatistics intervalStatistics = new IntervalStatistics(trackPoints, distanceInterval, minGPSDistance); intervalsLiveData.postValue(intervalStatistics.getIntervalList()); }