mirror of
https://codeberg.org/OpenTracksApp/OpenTracks.git
synced 2026-10-02 17:43:06 +02:00
Moving time: re-implement idle/non-idle TrackPoints.
Simplify computation of TrackStatistics. Part of #1046.
This commit is contained in:
+4
-4
@@ -312,16 +312,16 @@ public class ExportImportTest {
|
||||
assertEquals(Instant.parse("2020-02-02T02:02:03Z"), importedTrackStatistics.getStartTime());
|
||||
assertEquals(Instant.parse("2020-02-02T02:02:23Z"), importedTrackStatistics.getStopTime());
|
||||
|
||||
assertEquals(Duration.ofSeconds(20), importedTrackStatistics.getTotalTime());
|
||||
assertEquals(Duration.ofSeconds(19), importedTrackStatistics.getMovingTime());
|
||||
assertEquals(Duration.ofSeconds(4), importedTrackStatistics.getTotalTime());
|
||||
assertEquals(Duration.ofSeconds(4), importedTrackStatistics.getMovingTime());
|
||||
|
||||
// Distance
|
||||
assertEquals(Distance.of(60), importedTrackStatistics.getTotalDistance());
|
||||
|
||||
// Speed
|
||||
assertEquals(Speed.of(15), importedTrackStatistics.getMaxSpeed());
|
||||
assertEquals(Speed.of(3.0), importedTrackStatistics.getAverageSpeed());
|
||||
assertEquals(Speed.of(3.1578947368421053), importedTrackStatistics.getAverageMovingSpeed());
|
||||
assertEquals(Speed.of(15), importedTrackStatistics.getAverageSpeed());
|
||||
assertEquals(Speed.of(15), importedTrackStatistics.getAverageMovingSpeed());
|
||||
|
||||
// Altitude
|
||||
assertEquals(10, importedTrackStatistics.getMinAltitude(), 0.01);
|
||||
|
||||
+2
-2
@@ -83,14 +83,14 @@ public class TrackPointAssert {
|
||||
try {
|
||||
Assert.assertEquals(expected.size(), actual.size());
|
||||
} catch (AssertionError e) {
|
||||
throw new AssertionError("Size difference: " + expected.size() + " vs. " + actual.size() + "\nExpected: " + expected + "\n actual: " + actual);
|
||||
throw new AssertionError("Size difference; expected: " + expected.size() + "; actual: " + actual.size() + "\nExpected: " + expected + "\n actual: " + actual);
|
||||
}
|
||||
|
||||
for (int i = 0; i < expected.size(); i++) {
|
||||
try {
|
||||
assertEquals(expected.get(i), actual.get(i));
|
||||
} catch (AssertionError e) {
|
||||
throw new AssertionError("Expected: " + expected.get(i) + "\n actual: " + actual.get(i), e);
|
||||
throw new AssertionError("Expected: " + i + " to be " + expected.get(i) + "\n actual: " + actual.get(i), e);
|
||||
}
|
||||
}
|
||||
Assert.assertEquals(expected.size(), actual.size());
|
||||
|
||||
+2
-5
@@ -64,8 +64,8 @@ import de.dennisguse.opentracks.content.provider.CustomContentProvider;
|
||||
import de.dennisguse.opentracks.io.file.importer.TrackPointAssert;
|
||||
import de.dennisguse.opentracks.services.handlers.TrackPointCreator;
|
||||
import de.dennisguse.opentracks.services.sensors.AltitudeSumManager;
|
||||
import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||
import de.dennisguse.opentracks.settings.PreferencesUtils;
|
||||
import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||
|
||||
/**
|
||||
* Tests for the track recording service.
|
||||
@@ -451,10 +451,7 @@ public class TrackRecordingServiceTest {
|
||||
newTrackPoint(trackRecordingService, latitude, longitude, accuracy, speed, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a location and waits for 200ms.
|
||||
*/
|
||||
private static void newTrackPoint(TrackRecordingService trackRecordingService, double latitude, double longitude, float accuracy, long speed, long time) {
|
||||
static void newTrackPoint(TrackRecordingService trackRecordingService, double latitude, double longitude, float accuracy, long speed, long time) {
|
||||
TrackPoint trackPoint = new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.ofEpochMilli(time))
|
||||
.setLongitude(longitude)
|
||||
.setLatitude(latitude)
|
||||
|
||||
+16
-2
@@ -275,8 +275,8 @@ public class TrackRecordingServiceTestLocation {
|
||||
// when
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0, 35.0, 1, 15);
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0, 35.0, 2, 0);
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0, 35.0, 3, 0);
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0, 35.0, 4, 0);
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0, 35.0, 3, 0); // will be ignored
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0, 35.0, 4, 0); // will be ignored
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0, 35.0, 5, 0);
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0, 35.0, 6, 15);
|
||||
|
||||
@@ -297,6 +297,20 @@ public class TrackRecordingServiceTestLocation {
|
||||
.setSpeed(Speed.of(15))
|
||||
.setAltitudeGain(0f)
|
||||
.setAltitudeLoss(0f),
|
||||
new TrackPoint(TrackPoint.Type.TRACKPOINT, null)
|
||||
.setLatitude(45)
|
||||
.setLongitude(35)
|
||||
.setHorizontalAccuracy(Distance.of(2))
|
||||
.setSpeed(Speed.of(0))
|
||||
.setAltitudeGain(0f)
|
||||
.setAltitudeLoss(0f),
|
||||
new TrackPoint(TrackPoint.Type.TRACKPOINT, null)
|
||||
.setLatitude(45)
|
||||
.setLongitude(35)
|
||||
.setHorizontalAccuracy(Distance.of(5))
|
||||
.setSpeed(Speed.of(0))
|
||||
.setAltitudeGain(0f)
|
||||
.setAltitudeLoss(0f),
|
||||
new TrackPoint(TrackPoint.Type.TRACKPOINT, null)
|
||||
.setLatitude(45)
|
||||
.setLongitude(35)
|
||||
|
||||
+191
@@ -0,0 +1,191 @@
|
||||
package de.dennisguse.opentracks.services;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import androidx.test.filters.MediumTest;
|
||||
import androidx.test.rule.GrantPermissionRule;
|
||||
import androidx.test.rule.ServiceTestRule;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Function;
|
||||
|
||||
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.CustomContentProvider;
|
||||
import de.dennisguse.opentracks.services.sensors.AltitudeSumManager;
|
||||
import de.dennisguse.opentracks.settings.PreferencesUtils;
|
||||
import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||
|
||||
/**
|
||||
* Tests resulting TrackStatistics.
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class TrackRecordingServiceTestStatistics {
|
||||
|
||||
@Rule
|
||||
public final ServiceTestRule mServiceRule = ServiceTestRule.withTimeout(5, TimeUnit.SECONDS);
|
||||
|
||||
@Rule
|
||||
public GrantPermissionRule mRuntimePermissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION);
|
||||
|
||||
private final Context context = ApplicationProvider.getApplicationContext();
|
||||
private ContentProviderUtils contentProviderUtils;
|
||||
|
||||
private TrackRecordingService service;
|
||||
|
||||
private final AltitudeSumManager altitudeSumManager = new AltitudeSumManager() {
|
||||
@Override
|
||||
public void fill(@NonNull TrackPoint trackPoint) {
|
||||
trackPoint.setAltitudeGain(0f);
|
||||
trackPoint.setAltitudeLoss(0f);
|
||||
}
|
||||
};
|
||||
|
||||
@BeforeClass
|
||||
public static void preSetUp() {
|
||||
// Prepare looper for Android's message queue
|
||||
if (Looper.myLooper() == null) Looper.prepare();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void finalTearDown() {
|
||||
if (Looper.myLooper() != null) Looper.myLooper().quit();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws TimeoutException {
|
||||
// Set up the mock content resolver
|
||||
ContentProvider customContentProvider = new CustomContentProvider() {
|
||||
};
|
||||
customContentProvider.attachInfo(context, null);
|
||||
|
||||
contentProviderUtils = new ContentProviderUtils(context);
|
||||
tearDown();
|
||||
|
||||
// Let's use default values.
|
||||
PreferencesUtils.clear();
|
||||
|
||||
service = ((TrackRecordingService.Binder) mServiceRule.bindService(TrackRecordingServiceTest.createStartIntent(context)))
|
||||
.getService();
|
||||
service.getTrackPointCreator().stopGPS();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws TimeoutException {
|
||||
TrackRecordingService service = ((TrackRecordingService.Binder) mServiceRule.bindService(new Intent(context, TrackRecordingService.class)))
|
||||
.getService();
|
||||
service.getTrackPointCreator().setClock(Clock.systemUTC());
|
||||
}
|
||||
|
||||
/**
|
||||
* Moving time should increase if the previous and current TrackPoint have speed > threshold by the timeDiff(previousTrackPoint, currentTrackPoint).
|
||||
*/
|
||||
@MediumTest
|
||||
@Test
|
||||
public void movingtime_with_pauses() {
|
||||
// given
|
||||
service.getTrackPointCreator().setClock(Clock.fixed(Instant.ofEpochMilli(0), ZoneId.systemDefault()));
|
||||
Track.Id trackId = service.startNewTrack();
|
||||
service.getTrackPointCreator().setAltitudeSumManager(altitudeSumManager);
|
||||
|
||||
Function<Integer, Void> assertMovingTime = expected -> {
|
||||
Duration actual = contentProviderUtils.getTrack(trackId).getTrackStatistics().getMovingTime();
|
||||
assertEquals(Duration.ofSeconds(expected), actual);
|
||||
return null;
|
||||
};
|
||||
|
||||
Function<Integer, Void> assertTotalTime = expected -> {
|
||||
Duration actual = contentProviderUtils.getTrack(trackId).getTrackStatistics().getTotalTime();
|
||||
assertEquals(Duration.ofSeconds(expected), actual);
|
||||
return null;
|
||||
};
|
||||
|
||||
// when / then
|
||||
int movingtime_s = 0;
|
||||
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0, 35.0, 1, 15, 5 * 60000);
|
||||
assertMovingTime.apply(movingtime_s);
|
||||
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0001, 35.0, 2, 15, 6 * 60000);
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0002, 35.0, 2, 15, (long) (6.5 * 60000));
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0003, 35.0, 2, 15, 7 * 60000);
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0004, 35.0, 2, 15, 8 * 60000);
|
||||
movingtime_s += 3 * 60;
|
||||
assertMovingTime.apply(movingtime_s);
|
||||
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0004, 35.0, 2, 0, 9 * 60000); //will be ignored
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0004, 35.0, 2, 0, 10 * 60000); //will be ignored
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0004, 35.0, 2, 0, 11 * 60000);
|
||||
assertMovingTime.apply(movingtime_s);
|
||||
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0004, 35.0, 2, 15, 13 * 60000);
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0004, 35.0, 2, 15, (long) (13.5 * 60000)); //will be ignored
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0005, 35.0, 2, 15, 14 * 60000);
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0006, 35.0, 2, 15, 15 * 60000);
|
||||
movingtime_s += 2 * 60;
|
||||
assertMovingTime.apply(movingtime_s);
|
||||
assertTotalTime.apply(15 * 60);
|
||||
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0006, 35.0, 2, 0, 16 * 60000); //will be ignored
|
||||
assertMovingTime.apply(movingtime_s);
|
||||
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0015, 35.0, 2, 0, 17 * 60000);
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0016, 35.0, 2, 15, 18 * 60000);
|
||||
assertMovingTime.apply(movingtime_s);
|
||||
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0016, 35.0, 2, 0, 19 * 60000); //TODO we could ignore this TrackPoint
|
||||
assertMovingTime.apply(movingtime_s);
|
||||
assertTotalTime.apply(19 * 60);
|
||||
|
||||
service.getTrackPointCreator().setClock(Clock.fixed(Instant.ofEpochSecond(40 * 60), ZoneId.systemDefault()));
|
||||
assertMovingTime.apply(movingtime_s);
|
||||
service.pauseCurrentTrack();
|
||||
assertTotalTime.apply(40 * 60);
|
||||
|
||||
service.getTrackPointCreator().setClock(Clock.fixed(Instant.ofEpochSecond(41 * 60), ZoneId.systemDefault()));
|
||||
service.resumeCurrentTrack();
|
||||
TrackRecordingServiceTest.newTrackPoint(service, 45.0016, 35.0, 2, 15, 42 * 60000);
|
||||
assertMovingTime.apply(movingtime_s);
|
||||
assertTotalTime.apply(41 * 60);
|
||||
|
||||
service.getTrackPointCreator().setClock(Clock.fixed(Instant.ofEpochSecond(50 * 60), ZoneId.systemDefault()));
|
||||
service.endCurrentTrack();
|
||||
assertMovingTime.apply(movingtime_s);
|
||||
assertTotalTime.apply(49 * 60);
|
||||
|
||||
// then
|
||||
assertFalse(service.isRecording());
|
||||
|
||||
TrackStatistics trackStatistics = contentProviderUtils.getTrack(trackId).getTrackStatistics();
|
||||
|
||||
List<TrackPoint> trackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, trackId);
|
||||
assertEquals(20, trackPoints.size());
|
||||
|
||||
assertEquals(Duration.ofMinutes(49), trackStatistics.getTotalTime());
|
||||
}
|
||||
}
|
||||
+16
-10
@@ -1,5 +1,8 @@
|
||||
package de.dennisguse.opentracks.stats;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Ignore;
|
||||
@@ -16,9 +19,6 @@ import de.dennisguse.opentracks.content.data.TestDataUtil;
|
||||
import de.dennisguse.opentracks.content.data.Track;
|
||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class TrackStatisticsUpdaterTest {
|
||||
|
||||
@@ -81,18 +81,18 @@ public class TrackStatisticsUpdaterTest {
|
||||
|
||||
// then
|
||||
TrackStatistics statistics = subject.getTrackStatistics();
|
||||
assertEquals(99.58, statistics.getTotalDistance().toM(), 0.01);
|
||||
assertEquals(Duration.ofSeconds(14), statistics.getTotalTime());
|
||||
assertEquals(Duration.ofSeconds(7), statistics.getMovingTime());
|
||||
assertEquals(128.03, statistics.getTotalDistance().toM(), 0.01);
|
||||
assertEquals(Duration.ofSeconds(13), statistics.getTotalTime());
|
||||
assertEquals(Duration.ofSeconds(9), statistics.getMovingTime());
|
||||
|
||||
assertEquals(2.5, statistics.getMinAltitude(), 0.01);
|
||||
assertEquals(27.5, statistics.getMaxAltitude(), 0.01);
|
||||
assertEquals(28.75, statistics.getMaxAltitude(), 0.01);
|
||||
assertEquals(36, statistics.getTotalAltitudeGain(), 0.01);
|
||||
assertEquals(36, statistics.getTotalAltitudeLoss(), 0.01);
|
||||
|
||||
assertEquals(14.226, statistics.getMaxSpeed().toMPS(), 0.01);
|
||||
assertEquals(14.226, statistics.getAverageMovingSpeed().toMPS(), 0.01);
|
||||
assertEquals(7.11, statistics.getAverageSpeed().toMPS(), 0.01);
|
||||
assertEquals(9.84, statistics.getAverageSpeed().toMPS(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -141,9 +141,9 @@ public class TrackStatisticsUpdaterTest {
|
||||
TrackPoint tp2 = new TrackPoint(0, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(2000));
|
||||
tp2.setSpeed(Speed.of(5f));
|
||||
TrackPoint tp3 = new TrackPoint(0.001, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(3000));
|
||||
tp2.setSpeed(Speed.of(5f));
|
||||
tp3.setSpeed(Speed.of(5f));
|
||||
TrackPoint tp4 = new TrackPoint(0.001, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(4000));
|
||||
tp2.setSpeed(Speed.of(5f));
|
||||
tp4.setSpeed(Speed.of(5f));
|
||||
tp4.setSensorDistance(Distance.of(5f));
|
||||
TrackPoint tp5 = new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.ofEpochMilli(5000));
|
||||
tp5.setSensorDistance(Distance.of(10f));
|
||||
@@ -200,9 +200,12 @@ public class TrackStatisticsUpdaterTest {
|
||||
|
||||
TrackPoint tp1 = new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochMilli(1000));
|
||||
TrackPoint tp2 = new TrackPoint(0, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(2000));
|
||||
tp2.setSpeed(Speed.of(5f));
|
||||
TrackPoint tp3 = new TrackPoint(0.00001, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(3000));
|
||||
tp3.setSensorDistance(Distance.of(5f));
|
||||
tp3.setSpeed(Speed.of(5f));
|
||||
TrackPoint tp4 = new TrackPoint(0.0005, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(4000));
|
||||
tp4.setSpeed(Speed.of(5f));
|
||||
TrackPoint tp5 = new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.ofEpochMilli(5000));
|
||||
|
||||
// when
|
||||
@@ -248,8 +251,11 @@ public class TrackStatisticsUpdaterTest {
|
||||
|
||||
TrackPoint tp1 = new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochMilli(1000));
|
||||
TrackPoint tp2 = new TrackPoint(0, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(2000));
|
||||
tp2.setSpeed(Speed.of(5f));
|
||||
TrackPoint tp3 = new TrackPoint(0.00001, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(3000));
|
||||
tp3.setSpeed(Speed.of(5f));
|
||||
TrackPoint tp4 = new TrackPoint(0.0005, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(4000));
|
||||
tp4.setSpeed(Speed.of(5f));
|
||||
TrackPoint tp5 = new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.ofEpochMilli(5000));
|
||||
|
||||
subject.addTrackPoint(tp1, GPS_DISTANCE);
|
||||
|
||||
@@ -171,7 +171,13 @@ class TrackRecordingManager {
|
||||
}
|
||||
}
|
||||
|
||||
Log.d(TAG, "Not recording TrackPoint, idle");
|
||||
if (lastStoredTrackPoint != null && trackPoint.isMoving() != lastStoredTrackPoint.isMoving()) {
|
||||
// Moving from non-moving to moving or vice versa; required to compute moving time correctly.
|
||||
insertTrackPoint(trackId, trackPoint);
|
||||
return true;
|
||||
}
|
||||
|
||||
Log.d(TAG, "Not recording TrackPoint");
|
||||
lastTrackPoint = trackPoint;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -68,8 +68,6 @@ public class TrackStatisticsUpdater {
|
||||
private final TrackStatistics currentSegment;
|
||||
// Current segment's last trackPoint
|
||||
private TrackPoint lastTrackPoint;
|
||||
// Current segment's last moving trackPoint
|
||||
private TrackPoint lastMovingTrackPoint;
|
||||
|
||||
public TrackStatisticsUpdater() {
|
||||
this(new TrackStatistics());
|
||||
@@ -96,7 +94,6 @@ public class TrackStatisticsUpdater {
|
||||
this.speedBuffer_mps = new DoubleRingBuffer(toCopy.speedBuffer_mps);
|
||||
|
||||
this.lastTrackPoint = toCopy.lastTrackPoint;
|
||||
this.lastMovingTrackPoint = toCopy.lastMovingTrackPoint;
|
||||
}
|
||||
|
||||
public TrackStatistics getTrackStatistics() {
|
||||
@@ -116,9 +113,8 @@ public class TrackStatisticsUpdater {
|
||||
* @param minGPSDistance the min recording distance
|
||||
*/
|
||||
public void addTrackPoint(TrackPoint trackPoint, Distance minGPSDistance) {
|
||||
if (trackPoint.getType() == TrackPoint.Type.SEGMENT_START_MANUAL) {
|
||||
if (trackPoint.isSegmentStart()) {
|
||||
reset(trackPoint);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!currentSegment.isInitialized()) {
|
||||
@@ -129,7 +125,7 @@ public class TrackStatisticsUpdater {
|
||||
currentSegment.setStopTime(trackPoint.getTime());
|
||||
currentSegment.setTotalTime(Duration.between(currentSegment.getStartTime(), trackPoint.getTime()));
|
||||
|
||||
// Process sensor data
|
||||
// Process sensor data: barometer
|
||||
if (trackPoint.hasAltitudeGain()) {
|
||||
currentSegment.addTotalAltitudeGain(trackPoint.getAltitudeGain());
|
||||
}
|
||||
@@ -138,62 +134,46 @@ public class TrackStatisticsUpdater {
|
||||
currentSegment.addTotalAltitudeLoss(trackPoint.getAltitudeLoss());
|
||||
}
|
||||
|
||||
if (trackPoint.hasSensorDistance()) {
|
||||
currentSegment.addTotalDistance(trackPoint.getSensorDistance());
|
||||
//Update absolute (GPS-based) altitude
|
||||
if (trackPoint.hasAltitude()) {
|
||||
updateAbsoluteAltitude(trackPoint.getAltitude().toM());
|
||||
}
|
||||
|
||||
// Update total distance
|
||||
if (trackPoint.hasSensorDistance()) {
|
||||
// Sensor-based distance/speed
|
||||
currentSegment.addTotalDistance(trackPoint.getSensorDistance());
|
||||
} else if (lastTrackPoint != null && trackPoint.isMoving()) {
|
||||
// GPS-based distance/speed
|
||||
// Assumption: we ignore TrackPoints that are not moving as those are likely imprecise GPS measurements
|
||||
Distance movingDistance = trackPoint.distanceToPrevious(lastTrackPoint);
|
||||
if (movingDistance != null) {
|
||||
currentSegment.addTotalDistance(movingDistance);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Update moving time
|
||||
if (trackPoint.isMoving() && lastTrackPoint != null && lastTrackPoint.isMoving()) {
|
||||
Duration movingTime = Duration.between(lastTrackPoint.getTime(), trackPoint.getTime());
|
||||
if (movingTime.isNegative()) {
|
||||
throw new RuntimeException("Moving time cannot be negative");
|
||||
}
|
||||
currentSegment.addMovingTime(movingTime);
|
||||
|
||||
// Update max speed
|
||||
updateSpeed(trackPoint, lastTrackPoint);
|
||||
} else {
|
||||
speedBuffer_mps.reset();
|
||||
}
|
||||
|
||||
|
||||
if (trackPoint.isSegmentEnd()) {
|
||||
reset(trackPoint);
|
||||
return;
|
||||
}
|
||||
|
||||
//Update absolute (GPS-based) altitude
|
||||
if (trackPoint.hasAltitude()) {
|
||||
updateAbsoluteAltitude(trackPoint.getAltitude().toM());
|
||||
}
|
||||
|
||||
if (lastTrackPoint == null || lastMovingTrackPoint == null) {
|
||||
lastTrackPoint = trackPoint;
|
||||
lastMovingTrackPoint = trackPoint;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!trackPoint.hasSensorDistance()
|
||||
&& trackPoint.hasLocation() && lastMovingTrackPoint.hasLocation()) {
|
||||
// GPS-based distance/speed
|
||||
Distance movingDistance = trackPoint.distanceToPrevious(lastMovingTrackPoint);
|
||||
if (movingDistance != null && movingDistance.lessThan(minGPSDistance) && !trackPoint.isMoving()) {
|
||||
speedBuffer_mps.reset();
|
||||
lastTrackPoint = trackPoint;
|
||||
return; //TOOD Why? Is there nothing to be done afterwards?
|
||||
}
|
||||
// Update total distance
|
||||
currentSegment.addTotalDistance(movingDistance);
|
||||
}
|
||||
|
||||
Duration movingTime = Duration.between(lastTrackPoint.getTime(), trackPoint.getTime());
|
||||
if (movingTime.isNegative()) {
|
||||
lastTrackPoint = trackPoint;
|
||||
return;
|
||||
}
|
||||
|
||||
// Update moving time
|
||||
if (lastTrackPoint.isMoving()) {
|
||||
currentSegment.addMovingTime(movingTime);
|
||||
}
|
||||
|
||||
// Update max speed
|
||||
if (trackPoint.hasSpeed() && lastTrackPoint.hasSpeed()) {
|
||||
updateSpeed(trackPoint, lastTrackPoint);
|
||||
}
|
||||
|
||||
if (trackPoint.getType() == TrackPoint.Type.SEGMENT_START_AUTOMATIC) {
|
||||
reset(trackPoint);
|
||||
return;
|
||||
}
|
||||
|
||||
lastTrackPoint = trackPoint;
|
||||
lastMovingTrackPoint = trackPoint;
|
||||
}
|
||||
|
||||
private void reset(TrackPoint trackPoint) {
|
||||
@@ -203,7 +183,6 @@ public class TrackStatisticsUpdater {
|
||||
currentSegment.reset(trackPoint.getTime());
|
||||
|
||||
lastTrackPoint = null;
|
||||
lastMovingTrackPoint = null;
|
||||
altitudeBuffer_m.reset();
|
||||
speedBuffer_mps.reset();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user