diff --git a/doc/opentracks-schema-1.0.xsd b/doc/opentracks-schema-1.0.xsd
index 55c2b3d4b..c9eba6e4f 100644
--- a/doc/opentracks-schema-1.0.xsd
+++ b/doc/opentracks-schema-1.0.xsd
@@ -1,8 +1,32 @@
-
-
+
+
+
+ A unique track identifier stored as UUID.
+
+
+
-
\ No newline at end of file
+
+
+
+ The lost elevation in meters from the previous to the current TrackPoint.
+ Only used in GPX.
+
+
+
+
+
+
+ The gained elevation in meters from the previous to the current TrackPoint.
+ Only used in GPX.
+
+
+
+
\ No newline at end of file
diff --git a/src/androidTest/java/de/dennisguse/opentracks/content/sensor/SensorDataCyclingTest.java b/src/androidTest/java/de/dennisguse/opentracks/content/sensor/SensorDataCyclingTest.java
index 8f8dd01d9..491133f83 100644
--- a/src/androidTest/java/de/dennisguse/opentracks/content/sensor/SensorDataCyclingTest.java
+++ b/src/androidTest/java/de/dennisguse/opentracks/content/sensor/SensorDataCyclingTest.java
@@ -96,34 +96,36 @@ public class SensorDataCyclingTest {
@Test
public void compute_speed() {
// given
- SensorDataCycling.Speed previous = new SensorDataCycling.Speed("sensorAddress", "sensorName", 1, 6184);
- SensorDataCycling.Speed current = new SensorDataCycling.Speed("sensorAddress", "sensorName", 2, 8016);
+ SensorDataCycling.DistanceSpeed previous = new SensorDataCycling.DistanceSpeed("sensorAddress", "sensorName", 1, 6184);
+ SensorDataCycling.DistanceSpeed current = new SensorDataCycling.DistanceSpeed("sensorAddress", "sensorName", 2, 8016);
// when
current.compute(previous, 2150);
// then
- assertEquals(1.20, current.getValue(), 0.01);
+ assertEquals(1.20, current.getValue().distance_m, 2150);
+ assertEquals(1.20, current.getValue().speed_mps, 0.01);
}
@Test
public void compute_speed_rollOverCount() {
// given
- SensorDataCycling.Speed previous = new SensorDataCycling.Speed("sensorAddress", "sensorName", UintUtils.UINT16_MAX - 1, 1024);
- SensorDataCycling.Speed current = new SensorDataCycling.Speed("sensorAddress", "sensorName", 0, 2048);
+ SensorDataCycling.DistanceSpeed previous = new SensorDataCycling.DistanceSpeed("sensorAddress", "sensorName", UintUtils.UINT16_MAX - 1, 1024);
+ SensorDataCycling.DistanceSpeed current = new SensorDataCycling.DistanceSpeed("sensorAddress", "sensorName", 0, 2048);
// when
current.compute(previous, 2000);
// then
- assertEquals(2, current.getValue(), 0.01);
+ assertEquals(1.20, current.getValue().distance_m, 2000);
+ assertEquals(2, current.getValue().speed_mps, 0.01);
}
@Test
public void equals_speed_with_no_data() {
// given
- SensorDataCycling.Speed previous = new SensorDataCycling.Speed("sensorAddress");
- SensorDataCycling.Speed current = new SensorDataCycling.Speed("sensorAddress", "sensorName", 0, 2048);
+ SensorDataCycling.DistanceSpeed previous = new SensorDataCycling.DistanceSpeed("sensorAddress");
+ SensorDataCycling.DistanceSpeed current = new SensorDataCycling.DistanceSpeed("sensorAddress", "sensorName", 0, 2048);
// when
previous.toString();
diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java
index 8d4e064be..1b1db95e3 100644
--- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java
+++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java
@@ -3,7 +3,6 @@ package de.dennisguse.opentracks.io.file.importer;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
-import android.location.Location;
import android.os.Looper;
import android.util.Log;
@@ -24,6 +23,7 @@ import org.junit.runners.JUnit4;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
+import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -91,17 +91,17 @@ public class ExportImportTest {
trackId = service.startNewTrack();
- service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 14, 10, 15, 10, 0, 66, 3, 50), 0);
+ service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 14, 10, 15, 10, 0, 66, 3, 50, 5), 0);
service.insertMarker("Marker 1", "Marker 1 category", "Marker 1 desc", null);
- service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 14.001, 10, 15, 10, 0, 66, 3, 50), 0);
- service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 14.002, 10, 15, 10, 0, 66, 3, 50), 0);
+ service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 14.001, 10, 15, 10, 0, 66, 3, 50, 5), 0);
+ service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 14.002, 10, 15, 10, 0, 66, 3, 50, 5), 0);
service.insertMarker("Marker 2", "Marker 2 category", "Marker 2 desc", null);
service.pauseCurrentTrack();
service.resumeCurrentTrack();
- service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 14.003, 10, 15, 10, 0, 66, 3, 50), 0);
- service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 16, 10, 15, 10, 0, 66, 3, 50), 0);
- service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 16.001, 10, 15, 10, 0, 66, 3, 50), 0);
+ service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 14.003, 10, 15, 10, 0, 66, 3, 50, 5), 0);
+ service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 16, 10, 15, 10, 0, 66, 3, 50, 5), 0);
+ service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 16.001, 10, 15, 10, 0, 66, 3, 50, 5), 0);
service.endCurrentTrack();
track = contentProviderUtils.getTrack(trackId);
@@ -163,10 +163,10 @@ public class ExportImportTest {
assertEquals(track.getUuid(), importedTrack.getUuid());
// 2. trackpoints
- assertTrackpoints(trackPoints, false, false, false, false, false);
+ assertTrackpoints(trackPoints, false, false, false, false, false, false);
// 3. trackstatistics
- assertTrackStatistics(false, false);
+ assertTrackStatistics(false, false, false);
// 4. markers
assertMarkers();
@@ -201,10 +201,10 @@ public class ExportImportTest {
assertEquals(track.getIcon(), importedTrack.getIcon());
// 2. trackpoints
- assertTrackpoints(trackPoints, true, true, true, true, true);
+ assertTrackpoints(trackPoints, true, true, true, true, true, true);
// 2. trackstatistics
- assertTrackStatistics(false, true);
+ assertTrackStatistics(false, true, true);
// 4. markers
assertMarkers();
@@ -234,38 +234,6 @@ public class ExportImportTest {
assertNull(importedTrack);
}
- @Ignore
- @LargeTest
- @Test
- public void kmz_only_track() {
- // TODO
- Log.e(TAG, "Test not implemented.");
- }
-
- @Ignore
- @LargeTest
- @Test
- public void kmz_with_trackdetail() {
- // TODO
- Log.e(TAG, "Test not implemented.");
- }
-
- @Ignore
- @LargeTest
- @Test
- public void kmz_with_trackdetail_and_sensordata() {
- // TODO
- Log.e(TAG, "Test not implemented.");
- }
-
- @Ignore
- @LargeTest
- @Test
- public void kmz_with_trackdetail_and_sensordata_and_pictures() {
- // TODO
- Log.e(TAG, "Test not implemented.");
- }
-
@LargeTest
@Test
public void gpx() {
@@ -303,10 +271,10 @@ public class ExportImportTest {
trackPointsWithCoordinates.get(0).setType(TrackPoint.Type.SEGMENT_START_AUTOMATIC);
trackPointsWithCoordinates.get(3).setType(TrackPoint.Type.SEGMENT_START_AUTOMATIC);
- assertTrackpoints(trackPointsWithCoordinates, true, true, true, true, true);
+ assertTrackpoints(trackPointsWithCoordinates, true, true, true, true, true, false);
// 3. trackstatistics
- assertTrackStatistics(true, true);
+ assertTrackStatistics(true, true, false);
// 4. markers
assertMarkers();
@@ -356,7 +324,7 @@ public class ExportImportTest {
}
}
- private void assertTrackpoints(List trackPoints, boolean verifyPower, boolean verifyHeartrate, boolean verifyCadence, boolean verifyElevationGain, boolean verifyElevationLoss) {
+ private void assertTrackpoints(List trackPoints, boolean verifyPower, boolean verifyHeartrate, boolean verifyCadence, boolean verifyElevationGain, boolean verifyElevationLoss, boolean verifyDistance) {
List importedTrackPoints = contentProviderUtils.getTrackPoints(importTrackId);
assertEquals(trackPoints.size(), importedTrackPoints.size());
@@ -407,10 +375,13 @@ public class ExportImportTest {
if (verifyElevationLoss) {
assertEquals(trackPoint.getElevationLoss(), importedTrackPoint.getElevationLoss(), 0.01);
}
+ if (verifyDistance) {
+ assertEquals(trackPoint.getSensorDistance(), importedTrackPoint.getSensorDistance(), 0.01);
+ }
}
}
- private void assertTrackStatistics(boolean isGpx, boolean verifyElevationGainAndLoss) {
+ private void assertTrackStatistics(boolean isGpx, boolean verifyElevationGainAndLoss, boolean verifyDistance) {
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
assertNotNull(importedTrack.getTrackStatistics());
@@ -428,7 +399,9 @@ public class ExportImportTest {
assertEquals(trackStatistics.getMovingTime(), importedTrackStatistics.getMovingTime());
// Distance
- assertEquals(trackStatistics.getTotalDistance(), importedTrackStatistics.getTotalDistance(), 0.01);
+ if (verifyDistance) {
+ assertEquals(trackStatistics.getTotalDistance(), importedTrackStatistics.getTotalDistance(), 0.01);
+ }
// Speed
assertEquals(trackStatistics.getMaxSpeed(), importedTrackStatistics.getMaxSpeed(), 0.01);
@@ -448,20 +421,15 @@ public class ExportImportTest {
}
}
- private static TrackPoint createTrackPoint(long time, double latitude, double longitude, float accuracy, long speed, long altitude, float elevationGain, float heartRate, float cyclingCadence, float power) {
- Location location = new Location("");
- location.setTime(time);
- location.setLongitude(longitude);
- location.setLatitude(latitude);
- location.setAccuracy(accuracy);
- location.setAltitude(altitude);
- location.setSpeed(speed);
-
- TrackPoint tp = new TrackPoint(location);
+ private static TrackPoint createTrackPoint(long time, double latitude, double longitude, float accuracy, float speed, float altitude, float elevationGain, float heartRate, float cyclingCadence, float power, float distance) {
+ TrackPoint tp = new TrackPoint(latitude, longitude, (double) altitude, Instant.ofEpochMilli(time));
+ tp.setAccuracy(accuracy);
+ tp.setSpeed(speed);
tp.setHeartRate_bpm(heartRate);
tp.setCyclingCadence_rpm(cyclingCadence);
tp.setPower(power);
tp.setElevationGain(elevationGain);
+ tp.setSensorDistance(distance);
return tp;
}
}
\ No newline at end of file
diff --git a/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdaterTest.java b/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdaterTest.java
index 90a25602a..0b439d9c0 100644
--- a/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdaterTest.java
+++ b/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdaterTest.java
@@ -1,27 +1,36 @@
package de.dennisguse.opentracks.stats;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Ignore;
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.time.Duration;
+import java.time.Instant;
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;
+@RunWith(AndroidJUnit4.class)
public class TrackStatisticsUpdaterTest {
+ private static final int GPS_DISTANCE = 50;
+
@Test
- public void addTrackPoint() {
+ public void addTrackPoint_TestingTrack() {
// given
TestDataUtil.TrackData data = TestDataUtil.createTestingTrack(new Track.Id(1));
// when
- TrackStatisticsUpdater updater = new TrackStatisticsUpdater();
- data.trackPoints.forEach(it -> updater.addTrackPoint(it, 50));
+ TrackStatisticsUpdater subject = new TrackStatisticsUpdater();
+ data.trackPoints.forEach(it -> subject.addTrackPoint(it, GPS_DISTANCE));
// then
- TrackStatistics statistics = updater.getTrackStatistics();
+ TrackStatistics statistics = subject.getTrackStatistics();
assertEquals(85.35, statistics.getTotalDistance(), 0.01);
assertEquals(Duration.ofMillis(13999), statistics.getTotalTime());
assertEquals(Duration.ofSeconds(6), statistics.getMovingTime());
@@ -35,4 +44,122 @@ public class TrackStatisticsUpdaterTest {
assertEquals(14.226, statistics.getAverageMovingSpeed(), 0.01);
assertEquals(6.566, statistics.getAverageSpeed(), 0.01);
}
+
+ @Test
+ public void addTrackPoint_distance_from_GPS_not_moving() {
+ // given
+ TrackStatisticsUpdater subject = new TrackStatisticsUpdater();
+
+ TrackPoint tp1 = new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochMilli(1000));
+ TrackPoint tp2 = new TrackPoint(0, 0, 5.0, Instant.ofEpochMilli(2000));
+ TrackPoint tp3 = new TrackPoint(0.00001, 0, 5.0, Instant.ofEpochMilli(3000));
+
+ // when
+ subject.addTrackPoint(tp1, GPS_DISTANCE);
+ subject.addTrackPoint(tp2, GPS_DISTANCE);
+ subject.addTrackPoint(tp3, GPS_DISTANCE);
+
+ // then
+ assertEquals(0, subject.getTrackStatistics().getTotalDistance(), 0.01);
+ }
+
+ @Test
+ public void addTrackPoint_distance_from_GPS_moving() {
+ // given
+ TrackStatisticsUpdater subject = new TrackStatisticsUpdater();
+
+ TrackPoint tp1 = new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochMilli(1000));
+ TrackPoint tp2 = new TrackPoint(0, 0, 5.0, Instant.ofEpochMilli(2000));
+ TrackPoint tp3 = new TrackPoint(0.00001, 0, 5.0, Instant.ofEpochMilli(3000));
+ tp3.setSpeed(5f);
+
+ // when
+ subject.addTrackPoint(tp1, GPS_DISTANCE);
+ subject.addTrackPoint(tp2, GPS_DISTANCE);
+ subject.addTrackPoint(tp3, GPS_DISTANCE);
+
+ // then
+ assertEquals(1.10, subject.getTrackStatistics().getTotalDistance(), 0.01);
+ }
+
+ @Test
+ public void addTrackPoint_distance_from_GPS_moving_and_sensor_moving() {
+ // given
+ TrackStatisticsUpdater subject = new TrackStatisticsUpdater();
+
+ TrackPoint tp1 = new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochMilli(1000));
+ TrackPoint tp2 = new TrackPoint(0, 0, 5.0, Instant.ofEpochMilli(2000));
+ tp2.setSpeed(5f);
+ TrackPoint tp3 = new TrackPoint(0.001, 0, 5.0, Instant.ofEpochMilli(3000));
+ tp2.setSpeed(5f);
+ TrackPoint tp4 = new TrackPoint(0.001, 0, 5.0, Instant.ofEpochMilli(4000));
+ tp2.setSpeed(5f);
+ tp4.setSensorDistance(5f);
+ TrackPoint tp5 = new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.ofEpochMilli(5000));
+ tp5.setSensorDistance(10f);
+
+ // when
+ subject.addTrackPoint(tp1, GPS_DISTANCE);
+ subject.addTrackPoint(tp2, GPS_DISTANCE);
+ subject.addTrackPoint(tp3, GPS_DISTANCE);
+
+ // then
+ assertEquals(110.57, subject.getTrackStatistics().getTotalDistance(), 0.01);
+
+ // when
+ subject.addTrackPoint(tp4, GPS_DISTANCE);
+ subject.addTrackPoint(tp5, GPS_DISTANCE);
+
+ // then
+ assertEquals(125.57, subject.getTrackStatistics().getTotalDistance(), 0.01);
+ }
+
+ @Test
+ public void addTrackPoint_distance_from_GPS_not_moving_and_sensor_moving() {
+ // given
+ TrackStatisticsUpdater subject = new TrackStatisticsUpdater();
+
+ TrackPoint tp1 = new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochMilli(1000));
+ TrackPoint tp2 = new TrackPoint(0, 0, 5.0, Instant.ofEpochMilli(2000));
+ TrackPoint tp3 = new TrackPoint(0.00001, 0, 5.0, Instant.ofEpochMilli(3000));
+ TrackPoint tp4 = new TrackPoint(0.00001, 0, 5.0, Instant.ofEpochMilli(4000));
+ tp4.setSensorDistance(5f);
+ TrackPoint tp5 = new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.ofEpochMilli(5000));
+ tp5.setSensorDistance(10f);
+
+ // when
+ subject.addTrackPoint(tp1, GPS_DISTANCE);
+ subject.addTrackPoint(tp2, GPS_DISTANCE);
+ subject.addTrackPoint(tp3, GPS_DISTANCE);
+
+ // then
+ assertEquals(0, subject.getTrackStatistics().getTotalDistance(), 0.01);
+
+ // when
+ subject.addTrackPoint(tp4, GPS_DISTANCE);
+ subject.addTrackPoint(tp5, GPS_DISTANCE);
+
+ // then
+ assertEquals(15, subject.getTrackStatistics().getTotalDistance(), 0.01);
+ }
+
+ @Ignore("TODO: create a concept ont to compute speed from GPS and sensor")
+ @Test
+ public void addTrackPoint_speed_from_GPS_not_moving() {
+ }
+
+ @Ignore("TODO: create a concept ont to compute speed from GPS and sensor")
+ @Test
+ public void addTrackPoint_speed_from_GPS_moving() {
+ }
+
+ @Ignore("TODO: create a concept ont to compute speed from GPS and sensor")
+ @Test
+ public void addTrackPoint_speed_from_GPS_not_moving_and_sensor_speed() {
+ }
+
+ @Ignore("TODO: create a concept ont to compute speed from GPS and sensor")
+ @Test
+ public void addTrackPoint_speed_from_GPS_moving_and_sensor_speed() {
+ }
}
\ No newline at end of file
diff --git a/src/androidTest/java/de/dennisguse/opentracks/util/BluetoothUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/util/BluetoothUtilsTest.java
index 5137e9f6d..58dcf0c6b 100644
--- a/src/androidTest/java/de/dennisguse/opentracks/util/BluetoothUtilsTest.java
+++ b/src/androidTest/java/de/dennisguse/opentracks/util/BluetoothUtilsTest.java
@@ -47,7 +47,7 @@ public class BluetoothUtilsTest {
// then
assertEquals(200, sensor.getCadence().getCrankRevolutionsCount());
- assertNull(sensor.getSpeed());
+ assertNull(sensor.getDistanceSpeed());
}
@Test
@@ -60,7 +60,7 @@ public class BluetoothUtilsTest {
// then
assertNull(sensor.getCadence());
- assertEquals(225, sensor.getSpeed().getWheelRevolutionsCount());
+ assertEquals(225, sensor.getDistanceSpeed().getWheelRevolutionsCount());
}
@Test
@@ -73,7 +73,7 @@ public class BluetoothUtilsTest {
// then
assertEquals(200, sensor.getCadence().getCrankRevolutionsCount());
- assertEquals(225, sensor.getSpeed().getWheelRevolutionsCount());
+ assertEquals(225, sensor.getDistanceSpeed().getWheelRevolutionsCount());
}
@Test
diff --git a/src/main/java/de/dennisguse/opentracks/content/data/TrackPoint.java b/src/main/java/de/dennisguse/opentracks/content/data/TrackPoint.java
index e9660daaf..a3698093b 100644
--- a/src/main/java/de/dennisguse/opentracks/content/data/TrackPoint.java
+++ b/src/main/java/de/dennisguse/opentracks/content/data/TrackPoint.java
@@ -57,6 +57,7 @@ public class TrackPoint {
private Double altitude_m;
private Float speed_mps;
private Float bearing;
+ private Float sensorDistance_m;
public enum Type {
SEGMENT_START_MANUAL(-2), //Start of a segment due to user interaction (start, resume)
@@ -224,7 +225,7 @@ public class TrackPoint {
return elevationGain != null;
}
- public Float getElevationGain() {
+ public float getElevationGain() {
return elevationGain;
}
@@ -310,8 +311,12 @@ public class TrackPoint {
this.accuracy = horizontalAccuracy;
}
- public float distanceTo(@NonNull TrackPoint dest) {
- return getLocation().distanceTo(dest.getLocation());
+ public float distanceToPrevious(@NonNull TrackPoint previous) {
+ if (hasSensorDistance()) {
+ return getSensorDistance();
+ }
+
+ return getLocation().distanceTo(previous.getLocation());
}
public boolean fulfillsAccuracy(int poorAccuracy) {
@@ -327,6 +332,18 @@ public class TrackPoint {
}
// Sensor data
+ public boolean hasSensorDistance() {
+ return sensorDistance_m != null;
+ }
+
+ public Float getSensorDistance() {
+ return sensorDistance_m;
+ }
+
+ public void setSensorDistance(Float distance_m) {
+ this.sensorDistance_m = distance_m;
+ }
+
public boolean hasSensorData() {
return hasHeartRate() || hasCyclingCadence() || hasPower();
}
@@ -347,7 +364,7 @@ public class TrackPoint {
return cyclingCadence_rpm != null;
}
- public Float getCyclingCadence_rpm() {
+ public float getCyclingCadence_rpm() {
return cyclingCadence_rpm;
}
@@ -359,7 +376,7 @@ public class TrackPoint {
return power != null;
}
- public Float getPower() {
+ public float getPower() {
return power;
}
diff --git a/src/main/java/de/dennisguse/opentracks/content/data/TrackPointsColumns.java b/src/main/java/de/dennisguse/opentracks/content/data/TrackPointsColumns.java
index 6bf61e236..3de0e668e 100644
--- a/src/main/java/de/dennisguse/opentracks/content/data/TrackPointsColumns.java
+++ b/src/main/java/de/dennisguse/opentracks/content/data/TrackPointsColumns.java
@@ -50,6 +50,7 @@ public interface TrackPointsColumns extends BaseColumns {
String BEARING = "bearing";
String SENSOR_HEARTRATE = "sensor_heartrate";
String SENSOR_CADENCE = "sensor_cadence";
+ String SENSOR_DISTANCE = "sensor_distance"; //DISTANCE from previous TrackPoint
String SENSOR_POWER = "sensor_power";
String ELEVATION_GAIN = "elevation_gain";
String ELEVATION_LOSS = "elevation_loss";
@@ -77,6 +78,7 @@ public interface TrackPointsColumns extends BaseColumns {
+ ELEVATION_GAIN + " FLOAT, "
+ ELEVATION_LOSS + " FLOAT, "
+ TYPE + " TEXT CHECK(type IN (-2, -1, 0, 1)), "
+ + SENSOR_DISTANCE + " FLOAT, "
+ "FOREIGN KEY (" + TRACKID + ") REFERENCES " + TracksColumns.TABLE_NAME + "(" + TracksColumns._ID + ") ON UPDATE CASCADE ON DELETE CASCADE"
+ ")";
diff --git a/src/main/java/de/dennisguse/opentracks/content/provider/CachedTrackPointsIndexes.java b/src/main/java/de/dennisguse/opentracks/content/provider/CachedTrackPointsIndexes.java
index f391d7916..999be652e 100644
--- a/src/main/java/de/dennisguse/opentracks/content/provider/CachedTrackPointsIndexes.java
+++ b/src/main/java/de/dennisguse/opentracks/content/provider/CachedTrackPointsIndexes.java
@@ -19,6 +19,7 @@ class CachedTrackPointsIndexes {
final int bearingIndex;
final int sensorHeartRateIndex;
final int sensorCadenceIndex;
+ final int sensorDistanceIndex;
final int sensorPowerIndex;
final int elevationGainIndex;
final int elevationLossIndex;
@@ -35,6 +36,7 @@ class CachedTrackPointsIndexes {
bearingIndex = cursor.getColumnIndexOrThrow(TrackPointsColumns.BEARING);
sensorHeartRateIndex = cursor.getColumnIndexOrThrow(TrackPointsColumns.SENSOR_HEARTRATE);
sensorCadenceIndex = cursor.getColumnIndexOrThrow(TrackPointsColumns.SENSOR_CADENCE);
+ sensorDistanceIndex = cursor.getColumnIndexOrThrow(TrackPointsColumns.SENSOR_DISTANCE);
sensorPowerIndex = cursor.getColumnIndexOrThrow(TrackPointsColumns.SENSOR_POWER);
elevationGainIndex = cursor.getColumnIndexOrThrow(TrackPointsColumns.ELEVATION_GAIN);
elevationLossIndex = cursor.getColumnIndexOrThrow(TrackPointsColumns.ELEVATION_LOSS);
diff --git a/src/main/java/de/dennisguse/opentracks/content/provider/ContentProviderUtils.java b/src/main/java/de/dennisguse/opentracks/content/provider/ContentProviderUtils.java
index c0b3e9728..dcd85c720 100644
--- a/src/main/java/de/dennisguse/opentracks/content/provider/ContentProviderUtils.java
+++ b/src/main/java/de/dennisguse/opentracks/content/provider/ContentProviderUtils.java
@@ -556,6 +556,9 @@ public class ContentProviderUtils {
if (!cursor.isNull(indexes.sensorCadenceIndex)) {
trackPoint.setCyclingCadence_rpm(cursor.getFloat(indexes.sensorCadenceIndex));
}
+ if (!cursor.isNull(indexes.sensorDistanceIndex)) {
+ trackPoint.setSensorDistance(cursor.getFloat(indexes.sensorDistanceIndex));
+ }
if (!cursor.isNull(indexes.sensorPowerIndex)) {
trackPoint.setPower(cursor.getFloat(indexes.sensorPowerIndex));
}
@@ -708,6 +711,9 @@ public class ContentProviderUtils {
if (trackPoint.hasCyclingCadence()) {
values.put(TrackPointsColumns.SENSOR_CADENCE, trackPoint.getCyclingCadence_rpm());
}
+ if (trackPoint.hasSensorDistance()) {
+ values.put(TrackPointsColumns.SENSOR_DISTANCE, trackPoint.getSensorDistance());
+ }
if (trackPoint.hasPower()) {
values.put(TrackPointsColumns.SENSOR_POWER, trackPoint.getPower());
}
diff --git a/src/main/java/de/dennisguse/opentracks/content/provider/CustomSQLiteOpenHelper.java b/src/main/java/de/dennisguse/opentracks/content/provider/CustomSQLiteOpenHelper.java
index 84117e7c6..aee2b7549 100644
--- a/src/main/java/de/dennisguse/opentracks/content/provider/CustomSQLiteOpenHelper.java
+++ b/src/main/java/de/dennisguse/opentracks/content/provider/CustomSQLiteOpenHelper.java
@@ -25,7 +25,7 @@ public class CustomSQLiteOpenHelper extends SQLiteOpenHelper {
private static final String TAG = CustomSQLiteOpenHelper.class.getSimpleName();
- private static final int DATABASE_VERSION = 30;
+ private static final int DATABASE_VERSION = 31;
@VisibleForTesting
public static final String DATABASE_NAME = "database.db";
@@ -82,6 +82,9 @@ public class CustomSQLiteOpenHelper extends SQLiteOpenHelper {
case 30:
upgradeFrom29to30(db);
break;
+ case 31:
+ upgradeFrom30to31(db);
+ break;
default:
throw new RuntimeException("Not implemented: upgrade to " + toVersion);
@@ -115,7 +118,9 @@ public class CustomSQLiteOpenHelper extends SQLiteOpenHelper {
case 29:
downgradeFrom30to29(db);
break;
-
+ case 30:
+ downgradeFrom31to30(db);
+ break;
default:
throw new RuntimeException("Not implemented: downgrade to " + toVersion);
}
@@ -394,4 +399,32 @@ public class CustomSQLiteOpenHelper extends SQLiteOpenHelper {
db.setTransactionSuccessful();
db.endTransaction();
}
+
+ /**
+ * Add distance column to TrackPoint.
+ */
+ private void upgradeFrom30to31(SQLiteDatabase db) {
+ db.beginTransaction();
+
+ // TrackPoints
+ db.execSQL("ALTER TABLE trackpoints ADD COLUMN sensor_distance FLOAT");
+
+ db.setTransactionSuccessful();
+ db.endTransaction();
+ }
+
+ private void downgradeFrom31to30(SQLiteDatabase db) {
+ db.beginTransaction();
+
+ // TrackPoints; identical to upgradeFrom27to28()
+ db.execSQL("ALTER TABLE trackpoints RENAME TO trackpoints_old");
+ db.execSQL("CREATE TABLE trackpoints (_id INTEGER PRIMARY KEY AUTOINCREMENT, trackid INTEGER NOT NULL, longitude INTEGER, latitude INTEGER, time INTEGER, elevation FLOAT, accuracy FLOAT, speed FLOAT, bearing FLOAT, sensor_heartrate FLOAT, sensor_cadence FLOAT, sensor_power FLOAT, elevation_gain FLOAT, elevation_loss FLOAT, type TEXT CHECK(type IN (-2, -1, 0, 1)), FOREIGN KEY (trackid) REFERENCES tracks(_id) ON UPDATE CASCADE ON DELETE CASCADE)");
+ db.execSQL("INSERT INTO trackpoints SELECT _id, trackid, longitude, latitude, time, elevation, accuracy, speed, bearing, sensor_heartrate, sensor_cadence, sensor_power, elevation_gain, elevation_gain, type FROM trackpoints_old");
+ db.execSQL("DROP TABLE trackpoints_old");
+
+ db.execSQL("CREATE INDEX trackpoints_trackid_index ON trackpoints(trackid)");
+
+ db.setTransactionSuccessful();
+ db.endTransaction();
+ }
}
diff --git a/src/main/java/de/dennisguse/opentracks/content/sensor/SensorData.java b/src/main/java/de/dennisguse/opentracks/content/sensor/SensorData.java
index 5caff36ff..a5e110e01 100644
--- a/src/main/java/de/dennisguse/opentracks/content/sensor/SensorData.java
+++ b/src/main/java/de/dennisguse/opentracks/content/sensor/SensorData.java
@@ -54,6 +54,12 @@ public abstract class SensorData {
return value;
}
+ /**
+ * Reset long term aggregated values (more than derived from previous SensorData). e.g. overall distance.
+ */
+ public void reset() {
+ }
+
/**
* Is the data recent considering the current time.
*/
@@ -61,4 +67,10 @@ public abstract class SensorData {
return Instant.now()
.isBefore(time.plus(BluetoothRemoteSensorManager.MAX_SENSOR_DATE_SET_AGE_MS));
}
+
+ @NonNull
+ @Override
+ public String toString() {
+ return "sensorAddress='" + sensorAddress;
+ }
}
diff --git a/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataCycling.java b/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataCycling.java
index 2fc466567..2c3a94e00 100644
--- a/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataCycling.java
+++ b/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataCycling.java
@@ -41,7 +41,7 @@ public final class SensorDataCycling {
/**
* Workaround for Wahoo CADENCE: provides speed instead of cadence
*/
- public Cadence(@NonNull SensorDataCycling.Speed speed) {
+ public Cadence(@NonNull DistanceSpeed speed) {
this(speed.getSensorAddress(), speed.getSensorName(), speed.wheelRevolutionsCount, speed.wheelRevolutionsTime);
}
@@ -74,7 +74,7 @@ public final class SensorDataCycling {
@NonNull
@Override
public String toString() {
- return "cadence=" + value + " time=" + crankRevolutionsTime + " count=" + crankRevolutionsCount;
+ return super.toString() + " cadence=" + value + " time=" + crankRevolutionsTime + " count=" + crankRevolutionsCount;
}
@Override
@@ -90,18 +90,18 @@ public final class SensorDataCycling {
}
}
- public static class Speed extends SensorData {
+ public static class DistanceSpeed extends SensorData {
private final Integer wheelRevolutionsCount; // UINT16
private final Integer wheelRevolutionsTime; // UINT16; 1/1024s
- public Speed(String sensorAddress) {
+ public DistanceSpeed(String sensorAddress) {
super(sensorAddress);
this.wheelRevolutionsCount = null;
this.wheelRevolutionsTime = null;
}
- public Speed(String sensorAddress, String sensorName, int wheelRevolutionsCount, int wheelRevolutionsTime) {
+ public DistanceSpeed(String sensorAddress, String sensorName, int wheelRevolutionsCount, int wheelRevolutionsTime) {
super(sensorAddress, sensorName);
this.wheelRevolutionsCount = wheelRevolutionsCount;
this.wheelRevolutionsTime = wheelRevolutionsTime;
@@ -119,7 +119,7 @@ public final class SensorDataCycling {
return wheelRevolutionsTime;
}
- public void compute(Speed previous, int wheel_circumference_mm) {
+ public void compute(DistanceSpeed previous, int wheel_circumference_mm) {
if (hasData() && previous != null && previous.hasData()) {
float timeDiff_ms = UintUtils.diff(wheelRevolutionsTime, previous.wheelRevolutionsTime, UintUtils.UINT16_MAX) / 1024f * UnitConversions.S_TO_MS;
if (timeDiff_ms <= 0) {
@@ -128,42 +128,76 @@ public final class SensorDataCycling {
} else {
long wheelDiff = UintUtils.diff(wheelRevolutionsCount, previous.wheelRevolutionsCount, UintUtils.UINT16_MAX);
double timeDiff_s = timeDiff_ms * UnitConversions.MS_TO_S;
- value = (float) (wheelDiff * wheel_circumference_mm * UnitConversions.MM_TO_M / timeDiff_s);
+ float distance_m = (float) (wheelDiff * wheel_circumference_mm * UnitConversions.MM_TO_M);
+ float distance_overall_m = distance_m;
+ if (previous.hasValue()) {
+ distance_overall_m += previous.getValue().distance_overall_m;
+ }
+ float speed_mps = (float) (distance_m / timeDiff_s);
+ value = new Data(distance_m, distance_overall_m, speed_mps);
}
}
}
+ @Override
+ public void reset() {
+ if (value != null) {
+ value = new Data(value.distance_m, 0, value.speed_mps);
+ }
+ }
+
@NonNull
@Override
public String toString() {
- return "speed=" + value + " time=" + wheelRevolutionsTime + " count=" + wheelRevolutionsCount;
+ return super.toString() + " data=" + value + " time=" + wheelRevolutionsTime + " count=" + wheelRevolutionsCount;
}
@Override
public boolean equals(@Nullable Object obj) {
- if (!(obj instanceof Speed)) return false;
+ if (!(obj instanceof DistanceSpeed)) return false;
- Speed comp = (Speed) obj;
+ DistanceSpeed comp = (DistanceSpeed) obj;
if (hasData() && comp.hasData() == hasData()) {
return getWheelRevolutionsCount() == comp.getWheelRevolutionsCount() && getWheelRevolutionsTime() == comp.getWheelRevolutionsTime();
} else {
return false;
}
}
+
+ public static class Data {
+ public final float distance_m;
+ public final float distance_overall_m;
+ public final float speed_mps;
+
+ private Data(float distance_m, float distance_overall_m, float speed_mps) {
+ this.distance_m = distance_m;
+ this.distance_overall_m = distance_overall_m;
+ this.speed_mps = speed_mps;
+ }
+
+ @Override
+ public String toString() {
+ return "Data{" +
+ "distance_m=" + distance_m +
+ ", distance_overall_m=" + distance_overall_m +
+ ", speed_mps=" + speed_mps +
+ '}';
+ }
+ }
}
- public static class CadenceAndSpeed extends SensorData> {
+ public static class CadenceAndSpeed extends SensorData> {
- public CadenceAndSpeed(String sensorAddress, String sensorName, @NonNull Cadence cadence, @NonNull Speed speed) {
+ public CadenceAndSpeed(String sensorAddress, String sensorName, @Nullable Cadence cadence, @Nullable DistanceSpeed distanceSpeed) {
super(sensorAddress, sensorName);
- this.value = new Pair<>(cadence, speed);
+ this.value = new Pair<>(cadence, distanceSpeed);
}
public Cadence getCadence() {
return this.value != null ? this.value.first : null;
}
- public Speed getSpeed() {
+ public DistanceSpeed getDistanceSpeed() {
return this.value != null ? this.value.second : null;
}
}
diff --git a/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataCyclingPower.java b/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataCyclingPower.java
index 2fa263a1f..3662bcd3d 100644
--- a/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataCyclingPower.java
+++ b/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataCyclingPower.java
@@ -16,6 +16,6 @@ public class SensorDataCyclingPower extends SensorData {
@NonNull
@Override
public String toString() {
- return "power=" + value;
+ return super.toString() + " power=" + value;
}
}
diff --git a/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataHeartRate.java b/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataHeartRate.java
index b1b4db565..d1e7c1604 100644
--- a/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataHeartRate.java
+++ b/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataHeartRate.java
@@ -16,6 +16,6 @@ public class SensorDataHeartRate extends SensorData {
@NonNull
@Override
public String toString() {
- return "heart=" + value;
+ return super.toString() + " heart=" + value;
}
}
diff --git a/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataSet.java b/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataSet.java
index 7469e68c5..cc054e663 100644
--- a/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataSet.java
+++ b/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataSet.java
@@ -10,7 +10,7 @@ public final class SensorDataSet {
private SensorDataCycling.Cadence cyclingCadence;
- private SensorDataCycling.Speed cyclingSpeed;
+ private SensorDataCycling.DistanceSpeed cyclingDistanceSpeed;
private SensorDataCyclingPower cyclingPower;
@@ -25,8 +25,8 @@ public final class SensorDataSet {
return cyclingCadence;
}
- public SensorDataCycling.Speed getCyclingSpeed() {
- return cyclingSpeed;
+ public SensorDataCycling.DistanceSpeed getCyclingDistanceSpeed() {
+ return cyclingDistanceSpeed;
}
public SensorDataCyclingPower getCyclingPower() {
@@ -44,7 +44,7 @@ public final class SensorDataSet {
public void clear() {
this.heartRate = null;
this.cyclingCadence = null;
- this.cyclingSpeed = null;
+ this.cyclingDistanceSpeed = null;
this.cyclingPower = null;
}
@@ -57,8 +57,9 @@ public final class SensorDataSet {
trackPoint.setCyclingCadence_rpm(cyclingCadence.getValue());
}
- if (cyclingSpeed != null && cyclingSpeed.hasValue()) {
- trackPoint.setSpeed(cyclingSpeed.getValue());
+ if (cyclingDistanceSpeed != null && cyclingDistanceSpeed.hasValue()) {
+ trackPoint.setSensorDistance(cyclingDistanceSpeed.getValue().distance_overall_m);
+ trackPoint.setSpeed(cyclingDistanceSpeed.getValue().speed_mps);
}
if (cyclingPower != null && cyclingPower.hasValue()) {
@@ -66,12 +67,19 @@ public final class SensorDataSet {
}
}
+ public void reset() {
+ if (heartRate != null) heartRate.reset();
+ if (cyclingCadence != null) cyclingCadence.reset();
+ if (cyclingDistanceSpeed != null) cyclingDistanceSpeed.reset();
+ if (cyclingPower != null) cyclingPower.reset();
+ }
+
@NonNull
@Override
public String toString() {
return (getHeartRate() != null ? "" + getHeartRate() : "")
+ (getCyclingCadence() != null ? " " + getCyclingCadence() : "")
- + (getCyclingSpeed() != null ? " " + getCyclingSpeed() : "")
+ + (getCyclingDistanceSpeed() != null ? " " + getCyclingDistanceSpeed() : "")
+ (getCyclingPower() != null ? " " + getCyclingPower() : "");
}
@@ -85,8 +93,8 @@ public final class SensorDataSet {
this.cyclingCadence = (SensorDataCycling.Cadence) data;
return;
}
- if (type instanceof SensorDataCycling.Speed) {
- this.cyclingSpeed = (SensorDataCycling.Speed) data;
+ if (type instanceof SensorDataCycling.DistanceSpeed) {
+ this.cyclingDistanceSpeed = (SensorDataCycling.DistanceSpeed) data;
return;
}
diff --git a/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordingFragment.java b/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordingFragment.java
index ddfff026d..254c1fa8c 100644
--- a/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordingFragment.java
+++ b/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordingFragment.java
@@ -62,6 +62,7 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
private TrackRecordingServiceConnection trackRecordingServiceConnection = new TrackRecordingServiceConnection();
private TrackPoint lastTrackPoint;
+ //TODO Should not be nullable
private TrackStatistics lastTrackStatistics;
private String category = "";
@@ -366,29 +367,26 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
}
private void setSpeedSensorData(SensorDataSet sensorDataSet) {
- if (sensorDataSet != null && sensorDataSet.getCyclingSpeed() != null) {
- SensorDataCycling.Speed data = sensorDataSet.getCyclingSpeed();
+ if (sensorDataSet != null && sensorDataSet.getCyclingDistanceSpeed() != null) {
+ SensorDataCycling.DistanceSpeed data = sensorDataSet.getCyclingDistanceSpeed();
if (data.hasValue() && data.isRecent()) {
- setSpeed(data.getValue());
+ setTotalDistance(data.getValue().distance_overall_m);
+ setSpeed(data.getValue().speed_mps);
+ }
+ if (data.hasValue() && data.isRecent()) {
+ setSpeed(data.getValue().speed_mps);
}
}
}
private void updateStats() {
- String trackIconValue = TrackIconUtils.getIconValue(getContext(), category);
- // Set total distance
- {
- double totalDistance = lastTrackStatistics == null ? Double.NaN : lastTrackStatistics.getTotalDistance();
- Pair parts = StringUtils.getDistanceParts(getContext(), totalDistance, preferenceMetricUnits);
-
- viewBinding.statsDistanceValue.setText(parts.first);
- viewBinding.statsDistanceUnit.setText(parts.second);
- }
+ setTotalDistance(0);
// Set activity type
{
+ String trackIconValue = TrackIconUtils.getIconValue(getContext(), category);
viewBinding.statsActivityTypeIcon.setEnabled(isSelectedTrackRecording());
viewBinding.statsActivityTypeIcon.setImageResource(TrackIconUtils.getIconDrawable(trackIconValue));
}
@@ -479,6 +477,14 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
}
}
+ private void setTotalDistance(double sensorDistanceSinceLastTrackpoint) {
+ double totalDistance = lastTrackStatistics != null ? (lastTrackStatistics.getTotalDistance() + sensorDistanceSinceLastTrackpoint) : Double.NaN;
+ Pair parts = StringUtils.getDistanceParts(getContext(), totalDistance, preferenceMetricUnits);
+
+ viewBinding.statsDistanceValue.setText(parts.first);
+ viewBinding.statsDistanceUnit.setText(parts.second);
+ }
+
private void setSpeed(double speed) {
viewBinding.statsSpeedLabel.setText(preferenceReportSpeed ? R.string.stats_speed : R.string.stats_pace);
diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java
index 54ed0f635..2150dbf6a 100644
--- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java
+++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java
@@ -49,6 +49,7 @@ public class GPXTrackExporter implements TrackExporter {
private static final NumberFormat ELEVATION_FORMAT = NumberFormat.getInstance(Locale.US);
private static final NumberFormat COORDINATE_FORMAT = NumberFormat.getInstance(Locale.US);
private static final NumberFormat SPEED_FORMAT = NumberFormat.getInstance(Locale.US);
+ private static final NumberFormat DISTANCE_FORMAT = NumberFormat.getInstance(Locale.US);
private static final NumberFormat HEARTRATE_FORMAT = NumberFormat.getInstance(Locale.US);
private static final NumberFormat CADENCE_FORMAT = NumberFormat.getInstance(Locale.US);
private static final NumberFormat POWER_FORMAT = NumberFormat.getInstance(Locale.US);
@@ -312,6 +313,10 @@ public class GPXTrackExporter implements TrackExporter {
printWriter.println("" + ELEVATION_FORMAT.format(trackPoint.getElevationLoss()) + "");
}
+ if (trackPoint.hasSensorDistance()) {
+ printWriter.println("" + DISTANCE_FORMAT.format(trackPoint.getElevationLoss()) + "");
+ }
+
printWriter.println("");
}
diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/KMLTrackExporter.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/KMLTrackExporter.java
index 0de60e743..5c8664a7f 100644
--- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/KMLTrackExporter.java
+++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/KMLTrackExporter.java
@@ -57,6 +57,7 @@ public class KMLTrackExporter implements TrackExporter {
private static final String SCHEMA_ID = "schema";
public static final String EXTENDED_DATA_TYPE_SPEED = "speed";
+ public static final String EXTENDED_DATA_TYPE_DISTANCE = "distance";
public static final String EXTENDED_DATA_TYPE_CADENCE = "cadence";
public static final String EXTENDED_DATA_TYPE_HEART_RATE = "heart_rate";
public static final String EXTENDED_DATA_TYPE_POWER = "power";
@@ -74,6 +75,7 @@ public class KMLTrackExporter implements TrackExporter {
private PrintWriter printWriter;
private final List speedList = new ArrayList<>();
+ private final List distanceList = new ArrayList<>();
private final List powerList = new ArrayList<>();
private final List cadenceList = new ArrayList<>();
private final List heartRateList = new ArrayList<>();
@@ -338,6 +340,7 @@ public class KMLTrackExporter implements TrackExporter {
if (printWriter != null) {
printWriter.println("");
speedList.clear();
+ distanceList.clear();
powerList.clear();
cadenceList.clear();
heartRateList.clear();
@@ -355,6 +358,9 @@ public class KMLTrackExporter implements TrackExporter {
writeSimpleArrayData(speedList, EXTENDED_DATA_TYPE_SPEED);
}
if (exportSensorData) {
+ if (distanceList.stream().anyMatch(Objects::nonNull)) {
+ writeSimpleArrayData(distanceList, EXTENDED_DATA_TYPE_DISTANCE);
+ }
if (powerList.stream().anyMatch(Objects::nonNull)) {
writeSimpleArrayData(powerList, EXTENDED_DATA_TYPE_POWER);
}
@@ -392,6 +398,7 @@ public class KMLTrackExporter implements TrackExporter {
speedList.add(trackPoint.hasSpeed() ? trackPoint.getSpeed() : null);
if (exportSensorData) {
+ distanceList.add(trackPoint.hasSensorDistance() ? trackPoint.getSensorDistance() : null);
heartRateList.add(trackPoint.hasHeartRate() ? trackPoint.getHeartRate_bpm() : null);
cadenceList.add(trackPoint.hasCyclingCadence() ? trackPoint.getCyclingCadence_rpm() : null);
powerList.add(trackPoint.hasPower() ? trackPoint.getPower() : null);
diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/AbstractFileTrackImporter.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/AbstractFileTrackImporter.java
index 1b6443f95..360d5f8f5 100644
--- a/src/main/java/de/dennisguse/opentracks/io/file/importer/AbstractFileTrackImporter.java
+++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/AbstractFileTrackImporter.java
@@ -91,6 +91,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
protected String uuid;
protected String gain;
protected String loss;
+ protected String distance;
// The current track data
private TrackData trackData;
@@ -141,9 +142,6 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
}
}
- /**
- * On file end.
- */
protected void onFileEnd() {
// Add markers to the last imported track
int size = trackIds.size();
@@ -376,7 +374,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
* GPS points tend to have some inherent imprecision, speed and bearing will likely be off, so the statistics for things like max speed will also be off.
*/
if (trackPoint.hasLocation() && trackData.lastLocationInCurrentSegment.hasLocation()) {
- float speed = trackData.lastLocationInCurrentSegment.distanceTo(trackPoint) / timeDifference.toMillis();
+ float speed = trackData.lastLocationInCurrentSegment.distanceToPrevious(trackPoint) / timeDifference.toMillis();
trackPoint.setSpeed(speed);
}
}
@@ -385,7 +383,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
trackPoint.setBearing(trackData.lastLocationInCurrentSegment.bearingTo(trackPoint));
long maxRecordingDistance = PreferencesUtils.getMaxRecordingDistance(sharedPreferences, context); //TODO Should only be read once!
- double distanceToLastTrackLocation = trackPoint.distanceTo(trackData.lastLocationInCurrentSegment);
+ double distanceToLastTrackLocation = trackPoint.distanceToPrevious(trackData.lastLocationInCurrentSegment);
if (distanceToLastTrackLocation > maxRecordingDistance) {
trackPoint.setType(TrackPoint.Type.SEGMENT_START_AUTOMATIC);
}
@@ -505,6 +503,13 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
throw new ParsingException(createErrorMessage(String.format(Locale.US, "Unable to parse elevation loss: %s", loss)), e);
}
}
+ if (distance != null) {
+ try {
+ trackPoint.setSensorDistance(Float.parseFloat(distance));
+ } catch (Exception e) {
+ throw new ParsingException(createErrorMessage(String.format(Locale.US, "Unable to parse distance: %s", distance)), e);
+ }
+ }
return trackPoint;
}
diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/GpxFileTrackImporter.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/GpxFileTrackImporter.java
index 72dab53b3..cd1b42e4c 100644
--- a/src/main/java/de/dennisguse/opentracks/io/file/importer/GpxFileTrackImporter.java
+++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/GpxFileTrackImporter.java
@@ -63,6 +63,7 @@ public class GpxFileTrackImporter extends AbstractFileTrackImporter {
private static final String TAG_EXTENSION_GAIN = "opentracks:gain";
private static final String TAG_EXTENSION_LOSS = "opentracks:loss";
+ private static final String TAG_EXTENSION_DISTANCE = "opentracks:distance";
/**
* Constructor.
@@ -179,6 +180,11 @@ public class GpxFileTrackImporter extends AbstractFileTrackImporter {
loss = content.trim();
}
break;
+ case TAG_EXTENSION_DISTANCE:
+ if (content != null) {
+ distance = content.trim();
+ }
+ break;
}
// Reset element content
diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/KmlFileTrackImporter.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/KmlFileTrackImporter.java
index 84544fcf3..b2786c1f6 100644
--- a/src/main/java/de/dennisguse/opentracks/io/file/importer/KmlFileTrackImporter.java
+++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/KmlFileTrackImporter.java
@@ -66,6 +66,7 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
private String extendedDataType;
private final ArrayList trackPoints = new ArrayList<>();
private final ArrayList speedList = new ArrayList<>();
+ private final ArrayList distanceList = new ArrayList<>();
private final ArrayList cadenceList = new ArrayList<>();
private final ArrayList heartRateList = new ArrayList<>();
private final ArrayList powerList = new ArrayList<>();
@@ -216,6 +217,7 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
super.onTrackSegmentStart();
trackPoints.clear();
speedList.clear();
+ distanceList.clear();
heartRateList.clear();
cadenceList.clear();
powerList.clear();
@@ -232,6 +234,9 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
if (i < speedList.size()) {
trackPoint.setSpeed(speedList.get(i));
}
+ if (i < distanceList.size()) {
+ trackPoint.setSensorDistance(distanceList.get(i));
+ }
if (i < heartRateList.size()) {
trackPoint.setHeartRate_bpm(heartRateList.get(i));
}
@@ -310,6 +315,9 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
case KMLTrackExporter.EXTENDED_DATA_TYPE_SPEED:
speedList.add(value);
break;
+ case KMLTrackExporter.EXTENDED_DATA_TYPE_DISTANCE:
+ distanceList.add(value);
+ break;
case KMLTrackExporter.EXTENDED_DATA_TYPE_POWER:
powerList.add(value);
break;
diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java
index 3d58063b6..4be7ad436 100644
--- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java
+++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java
@@ -571,7 +571,7 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
return;
}
- double distanceToLastTrackLocation = trackPoint.distanceTo(lastValidTrackPoint);
+ double distanceToLastTrackLocation = trackPoint.distanceToPrevious(lastValidTrackPoint);
if (distanceToLastTrackLocation > maxRecordingDistance) {
insertTrackPointIfNewer(track, lastTrackPoint);
@@ -664,6 +664,10 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
trackPoint.setElevationLoss(elevationSumManager.getElevationLoss_m());
elevationSumManager.reset();
}
+ if (remoteSensorManager != null) {
+ fillWithSensorDataSet(trackPoint);
+ remoteSensorManager.reset();
+ }
contentProviderUtils.insertTrackPoint(trackPoint, track.getId());
trackStatisticsUpdater.addTrackPoint(trackPoint, recordingDistanceInterval);
diff --git a/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothConnectionManager.java b/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothConnectionManager.java
index 671ec09ad..c518a9c59 100644
--- a/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothConnectionManager.java
+++ b/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothConnectionManager.java
@@ -101,11 +101,11 @@ public abstract class BluetoothConnectionManager {
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, @NonNull BluetoothGattCharacteristic characteristic) {
- String sensorName = gatt.getDevice().getName();
- Log.d(TAG, "Received data from " + sensorName);
+ Log.d(TAG, "Received data from " + gatt.getDevice().getAddress());
- SensorData sensorData = parsePayload(sensorName, gatt.getDevice().getAddress(), characteristic);
+ SensorData> sensorData = parsePayload(gatt.getDevice().getName(), gatt.getDevice().getAddress(), characteristic);
if (sensorData != null) {
+ Log.d(TAG, "Decoded data from " + gatt.getDevice().getAddress() + ": " + sensorData);
observer.onChanged(sensorData);
}
}
@@ -125,7 +125,7 @@ public abstract class BluetoothConnectionManager {
Log.d(TAG, "Connecting to: " + device);
bluetoothGatt = device.connectGatt(context, true, connectCallback);
- SensorData sensorData = createEmptySensorData(bluetoothGatt.getDevice().getAddress());
+ SensorData> sensorData = createEmptySensorData(bluetoothGatt.getDevice().getAddress());
observer.onChanged(sensorData);
}
@@ -148,12 +148,12 @@ public abstract class BluetoothConnectionManager {
return address.equals(bluetoothGatt.getDevice().getAddress());
}
- protected abstract SensorData createEmptySensorData(String address);
+ protected abstract SensorData> createEmptySensorData(String address);
/**
* @return null if data could not be parsed.
*/
- protected abstract SensorData parsePayload(String sensorName, String address, BluetoothGattCharacteristic characteristic);
+ protected abstract SensorData> parsePayload(String sensorName, String address, BluetoothGattCharacteristic characteristic);
public static class HeartRate extends BluetoothConnectionManager {
@@ -162,7 +162,7 @@ public abstract class BluetoothConnectionManager {
}
@Override
- protected SensorData createEmptySensorData(String address) {
+ protected SensorDataHeartRate createEmptySensorData(String address) {
return new SensorDataHeartRate(address);
}
@@ -181,7 +181,7 @@ public abstract class BluetoothConnectionManager {
}
@Override
- protected SensorData createEmptySensorData(String address) {
+ protected SensorDataCycling.Cadence createEmptySensorData(String address) {
return new SensorDataCycling.Cadence(address);
}
@@ -197,30 +197,30 @@ public abstract class BluetoothConnectionManager {
}
//Workaround for Wahoo CADENCE: this sensor reports speed (instead of cadence)
- if (cadenceAndSpeed.getSpeed() != null) {
- return new SensorDataCycling.Cadence(cadenceAndSpeed.getSpeed());
+ if (cadenceAndSpeed.getDistanceSpeed() != null) {
+ return new SensorDataCycling.Cadence(cadenceAndSpeed.getDistanceSpeed());
}
return null;
}
}
- public static class CyclingSpeed extends BluetoothConnectionManager {
+ public static class CyclingDistanceSpeed extends BluetoothConnectionManager {
- CyclingSpeed(SensorDataObserver observer) {
+ CyclingDistanceSpeed(SensorDataObserver observer) {
super(BluetoothUtils.CYCLING_SPEED_CADENCE_SERVICE_UUID, BluetoothUtils.CYCLING_SPEED_CADENCE_MEASUREMENT_CHAR_UUID, observer);
}
@Override
- protected SensorData createEmptySensorData(String address) {
- return new SensorDataCycling.Speed(address);
+ protected SensorDataCycling.DistanceSpeed createEmptySensorData(String address) {
+ return new SensorDataCycling.DistanceSpeed(address);
}
@Override
- protected SensorDataCycling.Speed parsePayload(String sensorName, String address, BluetoothGattCharacteristic characteristic) {
+ protected SensorDataCycling.DistanceSpeed parsePayload(String sensorName, String address, BluetoothGattCharacteristic characteristic) {
SensorDataCycling.CadenceAndSpeed cadenceAndSpeed = BluetoothUtils.parseCyclingCrankAndWheel(address, sensorName, characteristic);
if (cadenceAndSpeed != null) {
- return cadenceAndSpeed.getSpeed();
+ return cadenceAndSpeed.getDistanceSpeed();
}
return null;
}
@@ -233,7 +233,7 @@ public abstract class BluetoothConnectionManager {
}
@Override
- protected SensorData createEmptySensorData(String address) {
+ protected SensorDataCyclingPower createEmptySensorData(String address) {
return new SensorDataCyclingPower(address);
}
@@ -247,8 +247,8 @@ public abstract class BluetoothConnectionManager {
interface SensorDataObserver {
- void onChanged(SensorData sensorData);
+ void onChanged(SensorData> sensorData);
- void onDisconnecting(SensorData sensorData);
+ void onDisconnecting(SensorData> sensorData);
}
}
diff --git a/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothRemoteSensorManager.java b/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothRemoteSensorManager.java
index 0af815b6b..748162fe0 100644
--- a/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothRemoteSensorManager.java
+++ b/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothRemoteSensorManager.java
@@ -53,13 +53,15 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
private final BluetoothAdapter bluetoothAdapter;
private final Context context;
- private final SharedPreferences sharedPreferences;
private boolean started = false;
+ private final SharedPreferences sharedPreferences;
+ private int preferenceWheelCircumference;
+
private final BluetoothConnectionManager.HeartRate heartRate = new BluetoothConnectionManager.HeartRate(this);
private final BluetoothConnectionManager.CyclingCadence cyclingCadence = new BluetoothConnectionManager.CyclingCadence(this);
- private final BluetoothConnectionManager.CyclingSpeed cyclingSpeed = new BluetoothConnectionManager.CyclingSpeed(this);
+ private final BluetoothConnectionManager.CyclingDistanceSpeed cyclingSpeed = new BluetoothConnectionManager.CyclingDistanceSpeed(this);
private final BluetoothConnectionManager.CyclingPower cyclingPower = new BluetoothConnectionManager.CyclingPower(this);
private final SensorDataSet sensorDataSet = new SensorDataSet();
@@ -90,6 +92,11 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
connect(cyclingPower, address);
}
+
+ if (PreferencesUtils.isKey(context, R.string.settings_sensor_bluetooth_cycling_power_key, key)) {
+ preferenceWheelCircumference = PreferencesUtils.getWheelCircumference(sharedPreferences, context);
+
+ }
}
};
@@ -155,11 +162,15 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
return sensorDataSet;
}
+ public void reset() {
+ sensorDataSet.reset();
+ }
+
@Override
- public synchronized void onChanged(SensorData sensorData) {
+ public synchronized void onChanged(SensorData> sensorData) {
if (sensorData instanceof SensorDataCycling.Cadence) {
SensorDataCycling.Cadence previous = sensorDataSet.getCyclingCadence();
- Log.d(TAG, "previous " + previous + "; current" + sensorData);
+ Log.d(TAG, "Previous: " + previous + "; current: " + sensorData);
if (sensorData.equals(previous)) {
Log.d(TAG, "onChanged: cadence data repeated.");
@@ -167,21 +178,21 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
}
((SensorDataCycling.Cadence) sensorData).compute(previous);
}
- if (sensorData instanceof SensorDataCycling.Speed) {
- SensorDataCycling.Speed previous = sensorDataSet.getCyclingSpeed();
- Log.d(TAG, "previous " + previous + "; current" + sensorData);
+ if (sensorData instanceof SensorDataCycling.DistanceSpeed) {
+ SensorDataCycling.DistanceSpeed previous = sensorDataSet.getCyclingDistanceSpeed();
+ Log.d(TAG, "Previous: " + previous + "; Current" + sensorData);
if (sensorData.equals(previous)) {
Log.d(TAG, "onChanged: speed data repeated.");
return;
}
- ((SensorDataCycling.Speed) sensorData).compute(previous, PreferencesUtils.getWheelCircumference(sharedPreferences, context));
+ ((SensorDataCycling.DistanceSpeed) sensorData).compute(previous, PreferencesUtils.getWheelCircumference(sharedPreferences, context));
}
sensorDataSet.set(sensorData);
}
@Override
- public void onDisconnecting(SensorData sensorData) {
+ public void onDisconnecting(SensorData> sensorData) {
sensorDataSet.remove(sensorData);
}
}
diff --git a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java
index f5b7f5f33..0926a2080 100644
--- a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java
+++ b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java
@@ -103,10 +103,15 @@ public class TrackStatisticsUpdater {
/**
* Adds a trackPoint.
*
- * @param trackPoint the trackPoint
- * @param minRecordingDistance the min recording distance
+ * @param trackPoint the trackPoint
+ * @param minGPSDistance the min recording distance
*/
- public void addTrackPoint(TrackPoint trackPoint, int minRecordingDistance) {
+ public void addTrackPoint(TrackPoint trackPoint, int minGPSDistance) {
+ internalAddTrackPoint(trackPoint, minGPSDistance);
+ Log.d(TAG, this.toString());
+ }
+
+ private void internalAddTrackPoint(TrackPoint trackPoint, int minGPSDistance) {
if (!trackInitialized) {
trackStatistics.setStartTime(trackPoint.getTime());
trackInitialized = true;
@@ -120,19 +125,26 @@ public class TrackStatisticsUpdater {
currentSegment.setStopTime(trackPoint.getTime());
currentSegment.setTotalTime(Duration.between(currentSegment.getStartTime(), trackPoint.getTime()));
- if (trackPoint.isSegmentStart() || trackPoint.isSegmentEnd()) {
- if (trackPoint.isSegmentEnd()) {
- if (lastTrackPoint != null && lastMovingTrackPoint != null && lastTrackPoint != lastMovingTrackPoint) {
- currentSegment.addTotalDistance(lastMovingTrackPoint.distanceTo(lastTrackPoint));
- }
- }
- trackStatistics.merge(currentSegment);
- currentSegment.reset(trackPoint.getTime());
+ if (trackPoint.isSegmentStart()) {
+ reset(trackPoint);
+ return;
+ }
- lastTrackPoint = null;
- lastMovingTrackPoint = null;
- elevationBuffer_m.reset();
- speedBuffer_ms.reset();
+ // Process sensor data
+ if (trackPoint.hasElevationGain()) {
+ currentSegment.addTotalElevationGain(trackPoint.getElevationGain());
+ }
+
+ if (trackPoint.hasElevationLoss()) {
+ currentSegment.addTotalElevationLoss(trackPoint.getElevationLoss());
+ }
+
+ if (trackPoint.hasSensorDistance()) {
+ currentSegment.addTotalDistance(trackPoint.getSensorDistance());
+ }
+
+ if (trackPoint.isSegmentEnd()) {
+ reset(trackPoint);
return;
}
@@ -141,39 +153,30 @@ public class TrackStatisticsUpdater {
updateAbsoluteElevation(trackPoint.getAltitude());
}
- //Get elevation gain
- if (trackPoint.hasElevationGain()) {
- currentSegment.addTotalElevationGain(trackPoint.getElevationGain());
- Log.d(TAG, "elevation gain: " + trackPoint.getElevationGain());
- }
-
- //Get elevation loss
- if (trackPoint.hasElevationLoss()) {
- currentSegment.addTotalElevationLoss(trackPoint.getElevationLoss());
- Log.d(TAG, "elevation loss: " + trackPoint.getElevationLoss());
- }
-
if (lastTrackPoint == null || lastMovingTrackPoint == null) {
lastTrackPoint = trackPoint;
lastMovingTrackPoint = trackPoint;
return;
}
- double movingDistance = lastMovingTrackPoint.distanceTo(trackPoint);
- if (movingDistance < minRecordingDistance && !trackPoint.isMoving()) {
- speedBuffer_ms.reset();
- lastTrackPoint = trackPoint;
- return;
+ if (!trackPoint.hasSensorDistance()) {
+ // GPS-based distance/speed
+ float movingDistance = lastMovingTrackPoint.distanceToPrevious(trackPoint);
+ if (movingDistance < minGPSDistance && !trackPoint.isMoving()) {
+ speedBuffer_ms.reset();
+ lastTrackPoint = trackPoint;
+ return;
+ }
+ // Update total distance
+ currentSegment.addTotalDistance(movingDistance);
}
+
Duration movingTime = Duration.between(lastTrackPoint.getTime(), trackPoint.getTime());
if (movingTime.isNegative()) {
lastTrackPoint = trackPoint;
return;
}
- // Update total distance
- currentSegment.addTotalDistance(movingDistance);
-
// Update moving time
currentSegment.addMovingTime(movingTime);
@@ -186,6 +189,16 @@ public class TrackStatisticsUpdater {
lastMovingTrackPoint = trackPoint;
}
+ private void reset(TrackPoint trackPoint) {
+ trackStatistics.merge(currentSegment);
+ currentSegment.reset(trackPoint.getTime());
+
+ lastTrackPoint = null;
+ lastMovingTrackPoint = null;
+ elevationBuffer_m.reset();
+ speedBuffer_ms.reset();
+ }
+
public void addTrackPoint(TrackPointIterator iterator, int minRecordingDistance) {
while (iterator.hasNext()) {
TrackPoint location = iterator.next();
@@ -224,20 +237,14 @@ public class TrackStatisticsUpdater {
/**
* Updates an elevation reading.
- *
- * @param elevation the elevation
- * @return the difference
*/
- @VisibleForTesting
- private double updateAbsoluteElevation(double elevation) {
+ private void updateAbsoluteElevation(double elevation) {
// Update elevation using the smoothed average
double oldAverage = elevationBuffer_m.getAverage();
elevationBuffer_m.setNext(elevation);
double newAverage = elevationBuffer_m.getAverage();
currentSegment.updateElevationExtremities(newAverage);
-
- return newAverage - oldAverage;
}
private boolean isValidSpeed(@NonNull TrackPoint trackPoint, @NonNull TrackPoint lastTrackPoint) {
@@ -267,4 +274,11 @@ public class TrackStatisticsUpdater {
return true;
}
+
+ @Override
+ public String toString() {
+ return "TrackStatisticsUpdater{" +
+ "trackStatistics=" + trackStatistics +
+ '}';
+ }
}
diff --git a/src/main/java/de/dennisguse/opentracks/util/BluetoothUtils.java b/src/main/java/de/dennisguse/opentracks/util/BluetoothUtils.java
index 5150ec5a0..730c6c965 100644
--- a/src/main/java/de/dennisguse/opentracks/util/BluetoothUtils.java
+++ b/src/main/java/de/dennisguse/opentracks/util/BluetoothUtils.java
@@ -126,12 +126,12 @@ public class BluetoothUtils {
cadence = new SensorDataCycling.Cadence(address, sensorName, crankCount, crankTime);
}
- SensorDataCycling.Speed speed = null;
+ SensorDataCycling.DistanceSpeed speed = null;
if (hasWheel && valueLength - index >= 4) {
int wheelCount = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, index);
index += 2;
int wheelTime = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, index); // 1/1024s
- speed = new SensorDataCycling.Speed(address, sensorName, wheelCount, wheelTime);
+ speed = new SensorDataCycling.DistanceSpeed(address, sensorName, wheelCount, wheelTime);
}
return new SensorDataCycling.CadenceAndSpeed(address, sensorName, cadence, speed);
diff --git a/src/main/java/de/dennisguse/opentracks/util/PreferencesUtils.java b/src/main/java/de/dennisguse/opentracks/util/PreferencesUtils.java
index 1cfe05fd4..4537de37d 100644
--- a/src/main/java/de/dennisguse/opentracks/util/PreferencesUtils.java
+++ b/src/main/java/de/dennisguse/opentracks/util/PreferencesUtils.java
@@ -42,6 +42,7 @@ public class PreferencesUtils {
private PreferencesUtils() {
}
+ @Deprecated //Should only be used to get a sharedPreference for more than one interaction!
public static SharedPreferences getSharedPreferences(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context);
}
@@ -102,7 +103,6 @@ public class PreferencesUtils {
editor.apply();
}
-
private static int getInt(SharedPreferences sharedPreferences, Context context, int keyId, int defaultValue) {
try {
return sharedPreferences.getInt(getKey(context, keyId), defaultValue);
@@ -206,7 +206,6 @@ public class PreferencesUtils {
return getString(sharedPreferences, context, R.string.settings_sensor_bluetooth_cycling_power_key, getBluetoothSensorAddressNone(context));
}
-
public static boolean shouldShowStatsOnLockscreen(SharedPreferences sharedPreferences, Context context) {
final boolean STATS_SHOW_ON_LOCKSCREEN_DEFAULT = context.getResources().getBoolean(R.bool.stats_show_on_lockscreen_while_recording_default);
return getBoolean(sharedPreferences, context, R.string.stats_show_on_lockscreen_while_recording_key, STATS_SHOW_ON_LOCKSCREEN_DEFAULT);
diff --git a/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatistics.java b/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatistics.java
index a461f5ee2..b73ff0421 100644
--- a/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatistics.java
+++ b/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatistics.java
@@ -33,7 +33,7 @@ public class IntervalStatistics {
TrackPoint trackPoint = trackPoints.get(i);
if (trackPoint.hasLocation() && prevTrackPoint.hasLocation()) {
- interval.distance_m += prevTrackPoint.distanceTo(trackPoint);
+ interval.distance_m += prevTrackPoint.distanceToPrevious(trackPoint);
interval.time = interval.time.plus(Duration.between(prevTrackPoint.getTime(), trackPoint.getTime()));
interval.gain_m += trackPoint.hasElevationGain() ? trackPoint.getElevationGain() : 0;
interval.loss_m += trackPoint.hasElevationLoss() ? trackPoint.getElevationLoss() : 0;