Dennis Review.

This commit is contained in:
Román Martínez
2021-06-10 15:52:37 +02:00
parent 838671e2ce
commit b2c2047ca2
8 changed files with 206 additions and 122 deletions
@@ -14,6 +14,7 @@ import java.util.List;
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
import de.dennisguse.opentracks.content.provider.TrackPointIterator;
import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.stats.TrackStatisticsUpdater;
import de.dennisguse.opentracks.util.FileUtils;
public class TestDataUtil {
@@ -166,4 +167,20 @@ public class TestDataUtil {
}
return trackPoints;
}
public static Pair<Track.Id, TrackStatistics> buildTrackWithTrackPoints(ContentProviderUtils contentProviderUtils, int numberOfPoints) {
Track dummyTrack = new Track();
dummyTrack.setId(new Track.Id(System.currentTimeMillis()));
dummyTrack.setName("Dummy Track");
contentProviderUtils.insertTrack(dummyTrack);
TrackStatisticsUpdater trackStatisticsUpdater = new TrackStatisticsUpdater();
for (int i = 0; i < numberOfPoints; i++) {
TrackPoint tp = TestDataUtil.createTrackPoint(i);
contentProviderUtils.insertTrackPoint(tp, dummyTrack.getId());
trackStatisticsUpdater.addTrackPoint(tp, Distance.of(0));
}
dummyTrack.setTrackStatistics(trackStatisticsUpdater.getTrackStatistics());
contentProviderUtils.updateTrack(dummyTrack);
return new Pair<>(dummyTrack.getId(), trackStatisticsUpdater.getTrackStatistics());
}
}
@@ -1,21 +1,23 @@
package de.dennisguse.opentracks.util;
import android.content.Context;
import android.util.Pair;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.time.Duration;
import java.util.List;
import de.dennisguse.opentracks.content.data.Distance;
import de.dennisguse.opentracks.content.data.Speed;
import de.dennisguse.opentracks.content.data.TestDataUtil;
import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
import de.dennisguse.opentracks.content.provider.TrackPointIterator;
import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.viewmodels.IntervalStatistics;
@@ -25,6 +27,12 @@ import static org.junit.Assert.assertEquals;
public class AnnouncementUtilsTest {
private final Context context = ApplicationProvider.getApplicationContext();
private ContentProviderUtils contentProviderUtils;
@Before
public void setUp() {
contentProviderUtils = new ContentProviderUtils(context);
}
@Test
public void getAnnouncement_metric_speed() {
@@ -44,23 +52,31 @@ public class AnnouncementUtilsTest {
@Test
public void getAnnouncement_withInterval_metric_speed() {
TrackStatistics stats = new TrackStatistics();
stats.setTotalDistance(Distance.of(20000));
stats.setTotalTime(Duration.ofHours(2).plusMinutes(5).plusSeconds(10));
stats.setMovingTime(Duration.ofHours(1).plusMinutes(5).plusSeconds(10));
stats.setMaxSpeed(Speed.of(100));
stats.setTotalAltitudeGain(6000f);
List<TrackPoint> trackPoints = TestDataUtil.createTrack(new Track.Id(System.currentTimeMillis()), 10).second;
IntervalStatistics intervalStatistics = new IntervalStatistics(Distance.of(1000), Distance.of(0));
intervalStatistics.addTrackPoints(trackPoints);
IntervalStatistics.Interval lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1);
// given
int numberOfPoints = 1000;
Pair<Track.Id, TrackStatistics> trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints);
Track.Id trackId = trackWithStats.first;
TrackStatistics stats = trackWithStats.second;
IntervalStatistics.Interval lastInterval;
try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) {
assertEquals(trackPointIterator.getCount(), numberOfPoints);
IntervalStatistics intervalStatistics = new IntervalStatistics(Distance.of(1000), Distance.of(0));
lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1);
}
// when
String announcement = AnnouncementUtils.getAnnouncement(context, stats, true, true, lastInterval);
// then
assertEquals("OpenTracks total distance 20.00 kilometers in 1 hour 5 minutes 10 seconds at 18.4 kilometers per hour Lap speed of 51.2 kilometers per hour", announcement);
assertEquals(
"OpenTracks total distance " +
StringUtils.getDistanceParts(context, stats.getTotalDistance(), true).first +
" kilometers in " + buildAndGetTimeText(stats.getTotalTime(), false) + " at " +
StringUtils.getSpeedParts(context, stats.getAverageMovingSpeed(), true, true).first +
" kilometers per hour Lap speed of " +
StringUtils.getSpeedParts(context, lastInterval.getSpeed(), true, true).first +
" kilometers per hour",
announcement);
}
@Test
@@ -81,23 +97,31 @@ public class AnnouncementUtilsTest {
@Test
public void getAnnouncement_withInterval_metric_pace() {
TrackStatistics stats = new TrackStatistics();
stats.setTotalDistance(Distance.of(20000));
stats.setTotalTime(Duration.ofHours(2).plusMinutes(5).plusSeconds(10));
stats.setMovingTime(Duration.ofHours(1).plusMinutes(5).plusSeconds(10));
stats.setMaxSpeed(Speed.of(100));
stats.setTotalAltitudeGain(6000f);
List<TrackPoint> trackPoints = TestDataUtil.createTrack(new Track.Id(System.currentTimeMillis()), 10).second;
IntervalStatistics intervalStatistics = new IntervalStatistics(Distance.of(1000), Distance.of(0));
intervalStatistics.addTrackPoints(trackPoints);
IntervalStatistics.Interval lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1);
// given
int numberOfPoints = 1000;
Pair<Track.Id, TrackStatistics> trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints);
Track.Id trackId = trackWithStats.first;
TrackStatistics stats = trackWithStats.second;
IntervalStatistics.Interval lastInterval;
try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) {
assertEquals(trackPointIterator.getCount(), numberOfPoints);
IntervalStatistics intervalStatistics = new IntervalStatistics(Distance.of(1000), Distance.of(0));
lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1);
}
// when
String announcement = AnnouncementUtils.getAnnouncement(context, stats, true, false, lastInterval);
// then
assertEquals("OpenTracks total distance 20.00 kilometers in 1 hour 5 minutes 10 seconds at 3 minutes 15 seconds per kilometer Lap time of 1 minute 10 seconds per kilometer", announcement);
assertEquals(
"OpenTracks total distance " +
StringUtils.getDistanceParts(context, stats.getTotalDistance(), true).first +
" kilometers in " + buildAndGetTimeText(stats.getTotalTime(), false) + " at " +
buildAndGetTimeText(stats.getAverageMovingSpeed().toPace(true), true) +
" per kilometer Lap time of " +
buildAndGetTimeText(lastInterval.getSpeed().toPace(true), true) +
" per kilometer",
announcement);
}
@Test
@@ -118,23 +142,31 @@ public class AnnouncementUtilsTest {
@Test
public void getAnnouncement_withInterval_imperial_speed() {
TrackStatistics stats = new TrackStatistics();
stats.setTotalDistance(Distance.of(20000));
stats.setTotalTime(Duration.ofHours(2).plusMinutes(5).plusSeconds(10));
stats.setMovingTime(Duration.ofHours(1).plusMinutes(5).plusSeconds(10));
stats.setMaxSpeed(Speed.of(100));
stats.setTotalAltitudeGain(6000f);
List<TrackPoint> trackPoints = TestDataUtil.createTrack(new Track.Id(System.currentTimeMillis()), 10).second;
IntervalStatistics intervalStatistics = new IntervalStatistics(Distance.of(1000), Distance.of(0));
intervalStatistics.addTrackPoints(trackPoints);
IntervalStatistics.Interval lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1);
// given
int numberOfPoints = 1000;
Pair<Track.Id, TrackStatistics> trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints);
Track.Id trackId = trackWithStats.first;
TrackStatistics stats = trackWithStats.second;
IntervalStatistics.Interval lastInterval;
try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) {
assertEquals(trackPointIterator.getCount(), numberOfPoints);
IntervalStatistics intervalStatistics = new IntervalStatistics(Distance.of(1000), Distance.of(0));
lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1);
}
// when
String announcement = AnnouncementUtils.getAnnouncement(context, stats, false, true, lastInterval);
// then
assertEquals("OpenTracks total distance 12.43 miles in 1 hour 5 minutes 10 seconds at 11.4 miles per hour Lap speed of 31.8 miles per hour", announcement);
assertEquals(
"OpenTracks total distance " +
StringUtils.getDistanceParts(context, stats.getTotalDistance(), false).first +
" miles in " + buildAndGetTimeText(stats.getTotalTime(), false) + " at " +
StringUtils.getSpeedParts(context, stats.getAverageMovingSpeed(), false, true).first +
" miles per hour Lap speed of " +
StringUtils.getSpeedParts(context, lastInterval.getSpeed(), false, true).first +
" miles per hour",
announcement);
}
@Test
@@ -155,22 +187,60 @@ public class AnnouncementUtilsTest {
@Test
public void getAnnouncement_withInterval_imperial_pace() {
TrackStatistics stats = new TrackStatistics();
stats.setTotalDistance(Distance.of(20000));
stats.setTotalTime(Duration.ofHours(2).plusMinutes(5).plusSeconds(10));
stats.setMovingTime(Duration.ofHours(1).plusMinutes(5).plusSeconds(10));
stats.setMaxSpeed(Speed.of(100));
stats.setTotalAltitudeGain(6000f);
List<TrackPoint> trackPoints = TestDataUtil.createTrack(new Track.Id(System.currentTimeMillis()), 10).second;
IntervalStatistics intervalStatistics = new IntervalStatistics(Distance.of(1000), Distance.of(0));
intervalStatistics.addTrackPoints(trackPoints);
IntervalStatistics.Interval lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1);
// given
int numberOfPoints = 1000;
Pair<Track.Id, TrackStatistics> trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints);
Track.Id trackId = trackWithStats.first;
TrackStatistics stats = trackWithStats.second;
IntervalStatistics.Interval lastInterval;
try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) {
assertEquals(trackPointIterator.getCount(), numberOfPoints);
IntervalStatistics intervalStatistics = new IntervalStatistics(Distance.of(1000), Distance.of(0));
lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1);
}
// when
String announcement = AnnouncementUtils.getAnnouncement(context, stats, false, false, lastInterval);
// then
assertEquals("OpenTracks total distance 12.43 miles in 1 hour 5 minutes 10 seconds at 5 minutes 15 seconds per mile Lap time of 1 minute 53 seconds per mile", announcement);
//assertEquals("OpenTracks total distance 12.43 miles in 1 hour 5 minutes 10 seconds at 5 minutes 15 seconds per mile Lap time of 1 minute 53 seconds per mile", announcement);
assertEquals(
"OpenTracks total distance " +
StringUtils.getDistanceParts(context, stats.getTotalDistance(), false).first +
" miles in " + buildAndGetTimeText(stats.getTotalTime(), false) + " at " +
buildAndGetTimeText(stats.getAverageMovingSpeed().toPace(false), true) +
" per mile Lap time of " +
buildAndGetTimeText(lastInterval.getSpeed().toPace(false), true) +
" per mile",
announcement);
}
/**
* Builds an returns the text representing the duration's time.
*
* @param duration Duration object.
* @param showFromMinutes show minutes tough it's 0.
* @return text representing the duratin's time.
*/
private String buildAndGetTimeText(Duration duration, boolean showFromMinutes) {
long hours = Math.abs(duration.getSeconds()) / 3600;
long minutes = (Math.abs(duration.getSeconds()) % 3600) / 60;
long seconds = Math.abs(duration.getSeconds()) % 60;
String hUnit = hours > 1 || hours == 0 ? "hours" : "hour";
String mUnit = minutes > 1 || minutes == 0 ? "minutes" : "minute";
String sUnit = seconds > 1 || seconds == 0 ? "seconds" : "second";
String res = hours > 0 ? hours + " " + hUnit : "";
if (hours > 0) {
res += minutes > 0 || showFromMinutes ? " " + minutes + " " + mUnit : "";
} else {
res += minutes > 0 || showFromMinutes ? minutes + " " + mUnit : "";
}
if (hours > 0 || minutes > 0 || showFromMinutes) {
res += " " + seconds + " " + sUnit;
} else {
res += seconds + " " + sUnit;
}
return res;
}
}
@@ -1,5 +1,11 @@
package de.dennisguse.opentracks.viewmodels;
import android.content.Context;
import android.util.Pair;
import androidx.test.core.app.ApplicationProvider;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -10,6 +16,8 @@ import de.dennisguse.opentracks.content.data.Distance;
import de.dennisguse.opentracks.content.data.TestDataUtil;
import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
import de.dennisguse.opentracks.content.provider.TrackPointIterator;
import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.stats.TrackStatisticsUpdater;
import de.dennisguse.opentracks.util.UnitConversions;
@@ -21,8 +29,12 @@ public class IntervalStatisticsTest {
private static final String TAG = IntervalStatisticsTest.class.getSimpleName();
private List<TrackPoint> buildTrackPoints(int numberOfTrackPoints) {
return TestDataUtil.createTrack(new Track.Id(System.currentTimeMillis()), numberOfTrackPoints).second;
private final Context context = ApplicationProvider.getApplicationContext();
private ContentProviderUtils contentProviderUtils;
@Before
public void setUp() {
contentProviderUtils = new ContentProviderUtils(context);
}
private TrackStatistics buildTrackStatistics(List<TrackPoint> trackPoints) {
@@ -41,12 +53,10 @@ public class IntervalStatisticsTest {
// With 50 points and interval distance of 1000m.
// given
List<TrackPoint> trackPoints = buildTrackPoints(50);
TrackStatistics trackStatistics = buildTrackStatistics(trackPoints);
float distanceInterval = 1000f;
// when and then
whenAndThen(trackPoints, trackStatistics, distanceInterval);
whenAndThen(50, distanceInterval);
}
/**
@@ -57,12 +67,10 @@ public class IntervalStatisticsTest {
// With 200 points and interval distance of 1000m.
// given
List<TrackPoint> trackPoints = buildTrackPoints(200);
TrackStatistics trackStatistics = buildTrackStatistics(trackPoints);
float distanceInterval = 1000f;
// when and then
whenAndThen(trackPoints, trackStatistics, distanceInterval);
whenAndThen(200, distanceInterval);
}
/**
@@ -73,12 +81,10 @@ public class IntervalStatisticsTest {
// With 200 points and interval distance of 3000m.
// given
List<TrackPoint> trackPoints = buildTrackPoints(200);
TrackStatistics trackStatistics = buildTrackStatistics(trackPoints);
float distanceInterval = 3000f;
// when and then
whenAndThen(trackPoints, trackStatistics, distanceInterval);
whenAndThen(3000, distanceInterval);
}
/**
@@ -89,12 +95,10 @@ public class IntervalStatisticsTest {
// With 1000 points and interval distance of 3000m.
// given
List<TrackPoint> trackPoints = buildTrackPoints(1000);
TrackStatistics trackStatistics = buildTrackStatistics(trackPoints);
float distanceInterval = 3000f;
// when and then
whenAndThen(trackPoints, trackStatistics, distanceInterval);
whenAndThen(1000, distanceInterval);
}
/**
@@ -105,17 +109,21 @@ public class IntervalStatisticsTest {
// With 10000 points and interval distance of 1000m.
// given
List<TrackPoint> trackPoints = buildTrackPoints(10000);
TrackStatistics trackStatistics = buildTrackStatistics(trackPoints);
float distanceInterval = 1000f;
// when and then
whenAndThen(trackPoints, trackStatistics, distanceInterval);
whenAndThen(10000, distanceInterval);
}
private void whenAndThen(List<TrackPoint> trackPoints, TrackStatistics trackStatistics, float distanceInterval) {
private void whenAndThen(int numberOfPoints, float distanceInterval) {
IntervalStatistics intervalStatistics = new IntervalStatistics(Distance.of(distanceInterval), Distance.of(0));
intervalStatistics.addTrackPoints(trackPoints);
Pair<Track.Id, TrackStatistics> trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints);
Track.Id trackId = trackWithStats.first;
TrackStatistics trackStatistics = trackWithStats.second;
try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) {
assertEquals(trackPointIterator.getCount(), numberOfPoints);
intervalStatistics.addTrackPoints(trackPointIterator);
}
List<IntervalStatistics.Interval> intervalList = intervalStatistics.getIntervalList();
Distance totalDistance = Distance.of(0);
float totalTime = 0L;
@@ -130,7 +138,7 @@ public class IntervalStatisticsTest {
assertEquals(trackStatistics.getTotalDistance().toM(), totalDistance.toM(), 0.01);
assertEquals(trackStatistics.getTotalTime().toMillis(), totalTime * UnitConversions.S_TO_MS, 1);
assertEquals(intervalList.size(), (int) Math.ceil(trackStatistics.getTotalDistance().toM() / distanceInterval));
assertEquals(totalGain, trackPoints.size() * TestDataUtil.ALTITUDE_GAIN, 0.1);
assertEquals(totalGain, numberOfPoints * TestDataUtil.ALTITUDE_GAIN, 0.1);
for (int i = 0; i < intervalList.size() - 1; i++) {
assertEquals(intervalList.get(i).getDistance().toM(), distanceInterval, 0.001);
@@ -37,6 +37,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import java.util.stream.StreamSupport;
import de.dennisguse.opentracks.BuildConfig;
import de.dennisguse.opentracks.content.data.Altitude;
@@ -745,16 +746,6 @@ public class ContentProviderUtils {
return new TrackPointIterator(this, trackId, startTrackPointId);
}
public List<TrackPoint> getTrackPoints(final Track.Id trackId, final TrackPoint.Id startTrackPointId) {
List<TrackPoint> trackPoints = new ArrayList<>();
try (TrackPointIterator trackPointIterator = getTrackPointLocationIterator(trackId, startTrackPointId)) {
while (trackPointIterator.hasNext()) {
trackPoints.add(trackPointIterator.next());
}
}
return trackPoints;
}
@Deprecated
private TrackPoint findTrackPointBy(String selection, String[] selectionArgs) {
try (Cursor cursor = getTrackPointCursor(null, selection, selectionArgs, TrackPointsColumns._ID)) {
@@ -64,7 +64,7 @@ public class IntervalsFragment extends Fragment {
/**
* Creates an instance of this class.
*
* @param trackId track's id.
* @param trackId
* @param fromTopToBottom If true then the intervals are shown from top to bottom (the first interval on top). Otherwise the intervals are shown from bottom to top.
* @return IntervalsFragment instance.
*/
@@ -185,7 +185,7 @@ public class IntervalsFragment extends Fragment {
}
private synchronized void updateIntervals(boolean metricUnits, IntervalStatisticsModel.IntervalOption selectedInterval) {
boolean update = metricUnits != this.metricUnits || !selectedInterval.equals(this.selectedInterval);
boolean update = metricUnits != this.metricUnits || !selectedInterval.sameMultiplier(this.selectedInterval);
this.metricUnits = metricUnits;
this.selectedInterval = selectedInterval;
@@ -178,19 +178,13 @@ public class AnnouncementPeriodicTask implements PeriodicTask {
}
String category = track.getCategory();
//TODO Querying all TrackPoints all the time is inefficient; get infos from TrackRecordingService
TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), null);
ArrayList<TrackPoint> trackPoints = new ArrayList<>();
while (trackPointIterator.hasNext()) {
trackPoints.add(trackPointIterator.next());
}
boolean isMetricUnits = PreferencesUtils.isMetricUnits(sharedPreferences, context);
boolean isReportSpeed = PreferencesUtils.isReportSpeed(sharedPreferences, context, category);
Distance minGPSDistance = PreferencesUtils.getRecordingDistanceInterval(sharedPreferences, context);
TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), null);
IntervalStatistics intervalStatistics = new IntervalStatistics(Distance.one(isMetricUnits), minGPSDistance);
intervalStatistics.addTrackPoints(trackPoints);
intervalStatistics.addTrackPoints(trackPointIterator);
IntervalStatistics.Interval lastInterval = intervalStatistics.getLastInterval();
String announcement = AnnouncementUtils.getAnnouncement(context, trackStatistics, isMetricUnits, isReportSpeed, lastInterval);
@@ -1,6 +1,5 @@
package de.dennisguse.opentracks.viewmodels;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.time.Duration;
@@ -10,6 +9,7 @@ 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.content.provider.TrackPointIterator;
import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.stats.TrackStatisticsUpdater;
@@ -34,24 +34,28 @@ public class IntervalStatistics {
intervalList.add(lastInterval);
}
public void addTrackPoints(@NonNull List<TrackPoint> trackPoints) {
if (trackPoints.size() == 0) {
return;
}
/**
* Complete intervals with the tracks points from the iterator.
*
* @param trackPointIterator
* @return the last track point's id used to compute the intervals.
*/
public TrackPoint.Id addTrackPoints(TrackPointIterator trackPointIterator) {
boolean newIntervalAdded = false;
for (TrackPoint trackPoint : trackPoints) {
TrackPoint trackPoint = null;
while (trackPointIterator.hasNext()) {
trackPoint = trackPointIterator.next();
trackStatisticsUpdater.addTrackPoint(trackPoint, minGPSDistance);
if (trackStatisticsUpdater.getTrackStatistics().getTotalDistance().plus(interval.distance).greaterOrEqualThan(distanceInterval)) {
interval.update(trackStatisticsUpdater.getTrackStatistics(), trackPoint);
interval.add(trackStatisticsUpdater.getTrackStatistics(), trackPoint);
double adjustFactor = distanceInterval.dividedBy(interval.distance);
Interval adjustedInterval = new Interval(interval);
adjustedInterval.adjust(adjustFactor);
intervalList.remove(intervalList.size() - 1);
intervalList.add(adjustedInterval);
intervalList.set(intervalList.size() - 1, adjustedInterval);
interval = new Interval(interval.distance.minus(adjustedInterval.distance), interval.time.minus(adjustedInterval.time));
trackStatisticsUpdater = new TrackStatisticsUpdater();
@@ -65,10 +69,12 @@ public class IntervalStatistics {
}
if (newIntervalAdded) {
lastInterval.update(trackStatisticsUpdater.getTrackStatistics(), null);
lastInterval.add(trackStatisticsUpdater.getTrackStatistics(), null);
} else {
lastInterval.set(trackStatisticsUpdater.getTrackStatistics());
}
return trackPoint != null ? trackPoint.getId() : null;
}
public List<Interval> getIntervalList() {
@@ -145,7 +151,7 @@ public class IntervalStatistics {
return loss_m;
}
private void update(TrackStatistics trackStatistics, @Nullable TrackPoint lastTrackPoint) {
private void add(TrackStatistics trackStatistics, @Nullable TrackPoint lastTrackPoint) {
distance = distance.plus(trackStatistics.getTotalDistance());
time = time.plus(trackStatistics.getTotalTime());
gain_m = trackStatistics.hasTotalAltitudeGain() ? trackStatistics.getTotalAltitudeGain() : gain_m;
@@ -21,6 +21,7 @@ import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.content.data.TrackPointsColumns;
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
import de.dennisguse.opentracks.content.provider.TrackPointIterator;
import de.dennisguse.opentracks.util.PreferencesUtils;
/**
@@ -47,6 +48,9 @@ public class IntervalStatisticsModel extends AndroidViewModel {
super(application);
minGPSDistance = PreferencesUtils.getRecordingDistanceInterval(PreferencesUtils.getSharedPreferences(application), application);
contentResolver = getApplication().getContentResolver();
handlerThread = new HandlerThread(TAG);
handlerThread.start();
handler = new Handler(handlerThread.getLooper());
}
@Override
@@ -54,6 +58,7 @@ public class IntervalStatisticsModel extends AndroidViewModel {
super.onCleared();
if (trackPointsTableObserver != null) {
contentResolver.unregisterContentObserver(trackPointsTableObserver);
trackPointsTableObserver = null;
}
if (handlerThread != null) {
handlerThread.getLooper().quit();
@@ -75,25 +80,6 @@ public class IntervalStatisticsModel extends AndroidViewModel {
loadIntervalStatistics(trackId);
}
registerTrackPointsObserver(trackId);
return intervalsLiveData;
}
private void loadIntervalStatistics(Track.Id trackId) {
executor.execute(() -> {
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(getApplication());
List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(trackId, lastTrackPointId);
lastTrackPointId = trackPoints.size() > 0 ? trackPoints.get(trackPoints.size() - 1).getId() : lastTrackPointId;
intervalStatistics.addTrackPoints(trackPoints);
intervalsLiveData.postValue(intervalStatistics.getIntervalList());
});
}
private void registerTrackPointsObserver(Track.Id trackId) {
handlerThread = new HandlerThread(TAG);
handlerThread.start();
handler = new Handler(handlerThread.getLooper());
trackPointsTableObserver = new ContentObserver(handler) {
@Override
public void onChange(boolean selfChange, Uri uri) {
@@ -101,6 +87,18 @@ public class IntervalStatisticsModel extends AndroidViewModel {
}
};
contentResolver.registerContentObserver(TrackPointsColumns.CONTENT_URI_BY_TRACKID, false, trackPointsTableObserver);
return intervalsLiveData;
}
private void loadIntervalStatistics(Track.Id trackId) {
executor.execute(() -> {
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(getApplication());
try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, lastTrackPointId)) {
lastTrackPointId = intervalStatistics.addTrackPoints(trackPointIterator);
intervalsLiveData.postValue(intervalStatistics.getIntervalList());
}
});
}
public void onPause() {
@@ -145,7 +143,7 @@ public class IntervalStatisticsModel extends AndroidViewModel {
.multipliedBy(multiplier);
}
public boolean equals(IntervalOption intervalOption) {
public boolean sameMultiplier(IntervalOption intervalOption) {
return intervalOption != null && this.multiplier == intervalOption.multiplier;
}