forked from upstream-mirrors/OpenTracks
Intervals are computated through TrackStatisticsUpdater. Fixes #703.
This commit is contained in:
@@ -52,7 +52,7 @@ public class AnnouncementUtilsTest {
|
|||||||
stats.setTotalAltitudeGain(6000f);
|
stats.setTotalAltitudeGain(6000f);
|
||||||
|
|
||||||
List<TrackPoint> trackPoints = TestDataUtil.createTrack(new Track.Id(System.currentTimeMillis()), 10).second;
|
List<TrackPoint> 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);
|
IntervalStatistics.Interval lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
|
|||||||
+1
-1
@@ -114,7 +114,7 @@ public class IntervalStatisticsTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void whenAndThen(List<TrackPoint> trackPoints, TrackStatistics trackStatistics, float distanceInterval) {
|
private void whenAndThen(List<TrackPoint> 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<IntervalStatistics.Interval> intervalList = intervalStatistics.getIntervalList();
|
List<IntervalStatistics.Interval> intervalList = intervalStatistics.getIntervalList();
|
||||||
Distance totalDistance = Distance.of(0);
|
Distance totalDistance = Distance.of(0);
|
||||||
float totalTime = 0L;
|
float totalTime = 0L;
|
||||||
|
|||||||
@@ -140,11 +140,14 @@ public class IntervalsFragment extends Fragment implements TrackDataListener {
|
|||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
|
resumeTrackDataHub();
|
||||||
|
|
||||||
sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
||||||
sharedPreferenceChangeListener.onSharedPreferenceChanged(sharedPreferences, null);
|
sharedPreferenceChangeListener.onSharedPreferenceChanged(sharedPreferences, null);
|
||||||
|
|
||||||
viewModel = new ViewModelProvider(getActivity()).get(IntervalStatisticsModel.class);
|
viewModel = new ViewModelProvider(getActivity()).get(IntervalStatisticsModel.class);
|
||||||
loadIntervals();
|
loadIntervals();
|
||||||
resumeTrackDataHub();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -224,28 +227,28 @@ public class IntervalsFragment extends Fragment implements TrackDataListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearTrackPoints() {
|
public void clearTrackPoints() {
|
||||||
if (isResumed()) {
|
if (isResumed() && viewModel != null) {
|
||||||
viewModel.clear();
|
viewModel.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSampledInTrackPoint(@NonNull TrackPoint trackPoint, @NonNull TrackStatistics unused, Speed unused2, double unused3) {
|
public void onSampledInTrackPoint(@NonNull TrackPoint trackPoint, @NonNull TrackStatistics unused, Speed unused2, double unused3) {
|
||||||
if (isResumed()) {
|
if (isResumed() && viewModel != null) {
|
||||||
viewModel.add(trackPoint);
|
viewModel.add(trackPoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSampledOutTrackPoint(@NonNull TrackPoint trackPoint, @NonNull TrackStatistics unused) {
|
public void onSampledOutTrackPoint(@NonNull TrackPoint trackPoint, @NonNull TrackStatistics unused) {
|
||||||
if (isResumed()) {
|
if (isResumed() && viewModel != null) {
|
||||||
viewModel.add(trackPoint);
|
viewModel.add(trackPoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNewTrackPointsDone() {
|
public void onNewTrackPointsDone() {
|
||||||
if (isResumed()) {
|
if (isResumed() && viewModel != null) {
|
||||||
runOnUiThread(viewModel::onNewTrackPoints);
|
runOnUiThread(viewModel::onNewTrackPoints);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,8 +187,9 @@ public class AnnouncementPeriodicTask implements PeriodicTask {
|
|||||||
|
|
||||||
boolean isMetricUnits = PreferencesUtils.isMetricUnits(sharedPreferences, context);
|
boolean isMetricUnits = PreferencesUtils.isMetricUnits(sharedPreferences, context);
|
||||||
boolean isReportSpeed = PreferencesUtils.isReportSpeed(sharedPreferences, context, category);
|
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();
|
IntervalStatistics.Interval lastInterval = intervalStatistics.getLastInterval();
|
||||||
|
|
||||||
String announcement = AnnouncementUtils.getAnnouncement(context, trackStatistics, isMetricUnits, isReportSpeed, lastInterval);
|
String announcement = AnnouncementUtils.getAnnouncement(context, trackStatistics, isMetricUnits, isReportSpeed, lastInterval);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package de.dennisguse.opentracks.viewmodels;
|
package de.dennisguse.opentracks.viewmodels;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.ArrayList;
|
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.Distance;
|
||||||
import de.dennisguse.opentracks.content.data.Speed;
|
import de.dennisguse.opentracks.content.data.Speed;
|
||||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||||
|
import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||||
|
import de.dennisguse.opentracks.stats.TrackStatisticsUpdater;
|
||||||
|
|
||||||
public class IntervalStatistics {
|
public class IntervalStatistics {
|
||||||
private final List<Interval> intervalList = new ArrayList<>();
|
private final List<Interval> intervalList = new ArrayList<>();
|
||||||
private final Distance distanceInterval;
|
private final Distance distanceInterval;
|
||||||
|
|
||||||
public IntervalStatistics(@NonNull List<TrackPoint> 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<TrackPoint> trackPoints, Distance distanceInterval, Distance minGPSDistance) {
|
||||||
intervalList.clear();
|
intervalList.clear();
|
||||||
this.distanceInterval = distanceInterval;
|
this.distanceInterval = distanceInterval;
|
||||||
|
|
||||||
@@ -22,30 +30,29 @@ public class IntervalStatistics {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TrackStatisticsUpdater trackStatisticsUpdater = new TrackStatisticsUpdater();
|
||||||
Interval interval = new Interval();
|
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()) {
|
for (TrackPoint trackPoint : trackPoints) {
|
||||||
interval.distance = interval.distance.plus(prevTrackPoint.distanceToPrevious(trackPoint));
|
trackStatisticsUpdater.addTrackPoint(trackPoint, minGPSDistance);
|
||||||
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;
|
|
||||||
|
|
||||||
if (interval.distance.greaterThan(distanceInterval)) {
|
if (trackStatisticsUpdater.getTrackStatistics().getTotalDistance().plus(interval.distance).greaterOrEqualThan(distanceInterval)) {
|
||||||
Interval adjustedInterval = new Interval(interval, distanceInterval.dividedBy(interval.distance));
|
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);
|
intervalList.add(interval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,8 +84,8 @@ public class IntervalStatistics {
|
|||||||
public static class Interval {
|
public 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 = 0f;
|
private float gain_m;
|
||||||
private float loss_m = 0f;
|
private float loss_m;
|
||||||
|
|
||||||
public Interval() {
|
public Interval() {
|
||||||
}
|
}
|
||||||
@@ -96,6 +103,18 @@ public class IntervalStatistics {
|
|||||||
loss_m = i.loss_m;
|
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() {
|
public Distance getDistance() {
|
||||||
return distance;
|
return distance;
|
||||||
}
|
}
|
||||||
@@ -111,5 +130,16 @@ public class IntervalStatistics {
|
|||||||
public float getLoss_m() {
|
public float getLoss_m() {
|
||||||
return loss_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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import java.util.List;
|
|||||||
|
|
||||||
import de.dennisguse.opentracks.content.data.Distance;
|
import de.dennisguse.opentracks.content.data.Distance;
|
||||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
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.
|
* This model is used to load intervals for a track.
|
||||||
@@ -22,9 +24,11 @@ public class IntervalStatisticsModel extends AndroidViewModel {
|
|||||||
private final List<TrackPoint> trackPoints = new ArrayList<>();
|
private final List<TrackPoint> trackPoints = new ArrayList<>();
|
||||||
private MutableLiveData<List<IntervalStatistics.Interval>> intervalsLiveData;
|
private MutableLiveData<List<IntervalStatistics.Interval>> intervalsLiveData;
|
||||||
private Distance distanceInterval;
|
private Distance distanceInterval;
|
||||||
|
private Distance minGPSDistance;
|
||||||
|
|
||||||
public IntervalStatisticsModel(@NonNull Application application) {
|
public IntervalStatisticsModel(@NonNull Application application) {
|
||||||
super(application);
|
super(application);
|
||||||
|
minGPSDistance = PreferencesUtils.getRecordingDistanceInterval(PreferencesUtils.getSharedPreferences(application), application);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MutableLiveData<List<IntervalStatistics.Interval>> getIntervalStats(boolean metricUnits, @Nullable IntervalOption interval) {
|
public MutableLiveData<List<IntervalStatistics.Interval>> getIntervalStats(boolean metricUnits, @Nullable IntervalOption interval) {
|
||||||
@@ -43,7 +47,7 @@ public class IntervalStatisticsModel extends AndroidViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loadIntervalStatistics() {
|
private void loadIntervalStatistics() {
|
||||||
IntervalStatistics intervalStatistics = new IntervalStatistics(trackPoints, distanceInterval);
|
IntervalStatistics intervalStatistics = new IntervalStatistics(trackPoints, distanceInterval, minGPSDistance);
|
||||||
intervalsLiveData.postValue(intervalStatistics.getIntervalList());
|
intervalsLiveData.postValue(intervalStatistics.getIntervalList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user