TrackStatistics and ChartView: handle altitude and speed as optional with null as default value.

Then only the relevant part of the y-axis is shown.

Fixes #795.
This commit is contained in:
Dennis Guse
2021-12-29 23:12:49 +01:00
parent 8c20d5583a
commit 07074ad260
11 changed files with 172 additions and 73 deletions
@@ -1,5 +1,8 @@
package de.dennisguse.opentracks.chart; package de.dennisguse.opentracks.chart;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test; import org.junit.Test;
@@ -7,15 +10,13 @@ import org.junit.runner.RunWith;
import java.time.Duration; import java.time.Duration;
import de.dennisguse.opentracks.content.data.Altitude;
import de.dennisguse.opentracks.content.data.Distance; import de.dennisguse.opentracks.content.data.Distance;
import de.dennisguse.opentracks.content.data.Speed; import de.dennisguse.opentracks.content.data.Speed;
import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.fragments.TrackStubUtils; import de.dennisguse.opentracks.fragments.TrackStubUtils;
import de.dennisguse.opentracks.stats.TrackStatistics; import de.dennisguse.opentracks.stats.TrackStatistics;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
public class ChartPointTest { public class ChartPointTest {
@@ -26,7 +27,7 @@ public class ChartPointTest {
statistics.setTotalTime(Duration.ofSeconds(1000)); statistics.setTotalTime(Duration.ofSeconds(1000));
// when // when
ChartPoint point = new ChartPoint(statistics, TrackStubUtils.createDefaultTrackPoint(), Speed.of(0), 0, false, false); ChartPoint point = new ChartPoint(statistics, TrackStubUtils.createDefaultTrackPoint(), Speed.of(0), Altitude.EGM2008.of(0), false, false);
// then // then
assertEquals(1000000, (long) point.getTimeOrDistance()); assertEquals(1000000, (long) point.getTimeOrDistance());
@@ -39,7 +40,7 @@ public class ChartPointTest {
statistics.setTotalDistance(Distance.of(1000)); statistics.setTotalDistance(Distance.of(1000));
// when // when
ChartPoint point = new ChartPoint(statistics, TrackStubUtils.createDefaultTrackPoint(), Speed.of(0), 0, true, true); ChartPoint point = new ChartPoint(statistics, TrackStubUtils.createDefaultTrackPoint(), Speed.of(0), Altitude.EGM2008.of(0), true, true);
// then // then
assertEquals(1, (long) point.getTimeOrDistance()); assertEquals(1, (long) point.getTimeOrDistance());
@@ -51,7 +52,7 @@ public class ChartPointTest {
TrackStatistics statistics = new TrackStatistics(); TrackStatistics statistics = new TrackStatistics();
// when // when
ChartPoint point = new ChartPoint(statistics, TrackStubUtils.createDefaultTrackPoint(), Speed.of(10), 50, false, true); ChartPoint point = new ChartPoint(statistics, TrackStubUtils.createDefaultTrackPoint(), Speed.of(10), Altitude.EGM2008.of(50), false, true);
// then // then
assertEquals(50, point.getAltitude(), 0.01); assertEquals(50, point.getAltitude(), 0.01);
@@ -65,7 +66,7 @@ public class ChartPointTest {
TrackStatistics statistics = new TrackStatistics(); TrackStatistics statistics = new TrackStatistics();
// when // when
ChartPoint point = new ChartPoint(statistics, TrackStubUtils.createDefaultTrackPoint(), Speed.of(10), 50, false, true); ChartPoint point = new ChartPoint(statistics, TrackStubUtils.createDefaultTrackPoint(), Speed.of(10), Altitude.EGM2008.of(50), false, true);
// then // then
assertNull(point.getHeartRate()); assertNull(point.getHeartRate());
@@ -84,7 +85,7 @@ public class ChartPointTest {
TrackStatistics statistics = new TrackStatistics(); TrackStatistics statistics = new TrackStatistics();
// when // when
ChartPoint point = new ChartPoint(statistics, trackPoint, Speed.of(10), 50, false, true); ChartPoint point = new ChartPoint(statistics, trackPoint, Speed.of(10), Altitude.EGM2008.of(50), false, true);
// then // then
assertEquals(100.0, point.getHeartRate(), 0.01); assertEquals(100.0, point.getHeartRate(), 0.01);
@@ -3,6 +3,7 @@ package de.dennisguse.opentracks.chart;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import de.dennisguse.opentracks.content.data.Altitude;
import de.dennisguse.opentracks.content.data.Distance; import de.dennisguse.opentracks.content.data.Distance;
import de.dennisguse.opentracks.content.data.Speed; import de.dennisguse.opentracks.content.data.Speed;
import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.data.TrackPoint;
@@ -14,7 +15,7 @@ public class ChartPoint {
private double timeOrDistance; private double timeOrDistance;
//Y-axis //Y-axis
private final double altitude; private Double altitude;
private Double speed; private Double speed;
private Double pace; private Double pace;
private Double heartRate; private Double heartRate;
@@ -27,17 +28,21 @@ public class ChartPoint {
this.altitude = altitude; this.altitude = altitude;
} }
public ChartPoint(@NonNull TrackStatistics trackStatistics, @NonNull TrackPoint trackPoint, Speed smoothedSpeed, double smoothedAltitude_m, boolean chartByDistance, boolean metricUnits) { public ChartPoint(@NonNull TrackStatistics trackStatistics, @NonNull TrackPoint trackPoint, Speed smoothedSpeed, Altitude smoothedAltitude, boolean chartByDistance, boolean metricUnits) {
if (chartByDistance) { if (chartByDistance) {
timeOrDistance = trackStatistics.getTotalDistance().toKM_Miles(metricUnits); timeOrDistance = trackStatistics.getTotalDistance().toKM_Miles(metricUnits);
} else { } else {
timeOrDistance = trackStatistics.getTotalTime().toMillis(); timeOrDistance = trackStatistics.getTotalTime().toMillis();
} }
altitude = Distance.of(smoothedAltitude_m).toM_FT(metricUnits); if (smoothedAltitude != null) {
altitude = Distance.of(smoothedAltitude.toM()).toM_FT(metricUnits);
}
speed = smoothedSpeed.to(metricUnits); if (smoothedSpeed != null) {
pace = smoothedSpeed.toPace(metricUnits).toMillis() * UnitConversions.MS_TO_S * UnitConversions.S_TO_MIN; speed = smoothedSpeed.to(metricUnits);
pace = smoothedSpeed.toPace(metricUnits).toMillis() * UnitConversions.MS_TO_S * UnitConversions.S_TO_MIN;
}
if (trackPoint.hasHeartRate()) { if (trackPoint.hasHeartRate()) {
heartRate = (double) trackPoint.getHeartRate_bpm(); heartRate = (double) trackPoint.getHeartRate_bpm();
} }
@@ -41,7 +41,6 @@ import androidx.core.view.GestureDetectorCompat;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.time.Duration; import java.time.Duration;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import java.util.List;
import de.dennisguse.opentracks.MarkerDetailActivity; import de.dennisguse.opentracks.MarkerDetailActivity;
@@ -873,9 +872,9 @@ public class ChartView extends View {
boolean drawFirstPoint = false; boolean drawFirstPoint = false;
path.rewind(); path.rewind();
Iterator<ChartPoint> iterator = chartPoints.iterator(); Integer finalX = null;
while (iterator.hasNext()) {
ChartPoint point = iterator.next(); for (ChartPoint point : chartPoints) {
if (!series.isChartPointValid(point)) { if (!series.isChartPointValid(point)) {
continue; continue;
} }
@@ -893,10 +892,12 @@ public class ChartView extends View {
// draw graph // draw graph
path.lineTo(x, y); path.lineTo(x, y);
// last point: move to lower right finalX = x;
if (!iterator.hasNext()) { }
path.lineTo(x, yCorner);
} // last point: move to lower right
if (finalX != null) {
path.lineTo(finalX, yCorner);
} }
// back to lower left corner // back to lower left corner
@@ -17,7 +17,9 @@
package de.dennisguse.opentracks.content; package de.dennisguse.opentracks.content;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import de.dennisguse.opentracks.content.data.Altitude;
import de.dennisguse.opentracks.content.data.Marker; import de.dennisguse.opentracks.content.data.Marker;
import de.dennisguse.opentracks.content.data.Speed; import de.dennisguse.opentracks.content.data.Speed;
import de.dennisguse.opentracks.content.data.Track; import de.dennisguse.opentracks.content.data.Track;
@@ -49,7 +51,7 @@ public interface TrackDataListener {
* *
* @param trackPoint the trackPoint * @param trackPoint the trackPoint
*/ */
default void onSampledInTrackPoint(@NonNull TrackPoint trackPoint, @NonNull TrackStatistics trackStatistics, Speed smoothedSpeed, double smoothedAltitude_m) { default void onSampledInTrackPoint(@NonNull TrackPoint trackPoint, @NonNull TrackStatistics trackStatistics, Speed smoothedSpeed, @Nullable Altitude smoothedAltitude_m) {
} }
/** /**
@@ -14,6 +14,8 @@ public abstract class Altitude {
return altitude_m; return altitude_m;
} }
public abstract Altitude replace(double altitude_m);
public abstract int getLabelId(); public abstract int getLabelId();
public static class WGS84 extends Altitude { public static class WGS84 extends Altitude {
@@ -30,6 +32,11 @@ public abstract class Altitude {
public static Altitude of(double altitude_m) { public static Altitude of(double altitude_m) {
return new WGS84(altitude_m); return new WGS84(altitude_m);
} }
@Override
public Altitude replace(double altitude_m) {
return new WGS84(altitude_m);
}
} }
public static class EGM2008 extends Altitude { public static class EGM2008 extends Altitude {
@@ -46,6 +53,11 @@ public abstract class Altitude {
public static Altitude of(double altitude_m) { public static Altitude of(double altitude_m) {
return new EGM2008(altitude_m); return new EGM2008(altitude_m);
} }
@Override
public Altitude replace(double altitude_m) {
return new EGM2008(altitude_m);
}
} }
} }
@@ -35,14 +35,15 @@ import de.dennisguse.opentracks.TrackActivityDataHubInterface;
import de.dennisguse.opentracks.chart.ChartPoint; import de.dennisguse.opentracks.chart.ChartPoint;
import de.dennisguse.opentracks.content.TrackDataHub; import de.dennisguse.opentracks.content.TrackDataHub;
import de.dennisguse.opentracks.content.TrackDataListener; import de.dennisguse.opentracks.content.TrackDataListener;
import de.dennisguse.opentracks.content.data.Altitude;
import de.dennisguse.opentracks.content.data.Marker; import de.dennisguse.opentracks.content.data.Marker;
import de.dennisguse.opentracks.content.data.Speed; import de.dennisguse.opentracks.content.data.Speed;
import de.dennisguse.opentracks.content.data.Track; import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.databinding.ChartBinding; import de.dennisguse.opentracks.databinding.ChartBinding;
import de.dennisguse.opentracks.settings.PreferencesUtils;
import de.dennisguse.opentracks.stats.TrackStatistics; import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.stats.TrackStatisticsUpdater; import de.dennisguse.opentracks.stats.TrackStatisticsUpdater;
import de.dennisguse.opentracks.settings.PreferencesUtils;
/** /**
* A fragment to display track chart to the user. * A fragment to display track chart to the user.
@@ -189,9 +190,9 @@ public class ChartFragment extends Fragment implements TrackDataListener {
} }
} }
public void onSampledInTrackPoint(@NonNull TrackPoint trackPoint, @NonNull TrackStatistics trackStatistics, Speed smoothedSpeed, double smoothedAltitude_m) { public void onSampledInTrackPoint(@NonNull TrackPoint trackPoint, @NonNull TrackStatistics trackStatistics, Speed smoothedSpeed, Altitude smoothedAltitude) {
if (isResumed()) { if (isResumed()) {
ChartPoint point = new ChartPoint(trackStatistics, trackPoint, smoothedSpeed, smoothedAltitude_m, chartByDistance, viewBinding.chartView.getMetricUnits()); ChartPoint point = new ChartPoint(trackStatistics, trackPoint, smoothedSpeed, smoothedAltitude, chartByDistance, viewBinding.chartView.getMetricUnits());
pendingPoints.add(point); pendingPoints.add(point);
} }
} }
@@ -0,0 +1,32 @@
package de.dennisguse.opentracks.stats;
import androidx.annotation.Nullable;
import de.dennisguse.opentracks.content.data.Altitude;
public class AltitudeRingBuffer extends RingBuffer<Altitude> {
private Altitude firstAltitude;
AltitudeRingBuffer(int size) {
super(size);
}
AltitudeRingBuffer(RingBuffer<Altitude> toCopy) {
super(toCopy);
}
@Nullable
@Override
protected Number from(Altitude object) {
if (firstAltitude == null) {
firstAltitude = object;
}
return object.toM();
}
@Override
protected Altitude to(double object) {
return firstAltitude.replace(object);
}
}
@@ -17,8 +17,9 @@
package de.dennisguse.opentracks.stats; package de.dennisguse.opentracks.stats;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.Arrays; import java.util.ArrayList;
/** /**
* This class maintains a ring buffer of doubles. * This class maintains a ring buffer of doubles.
@@ -27,10 +28,9 @@ import java.util.Arrays;
* *
* @author Sandor Dornbush * @author Sandor Dornbush
*/ */
class DoubleRingBuffer { abstract class RingBuffer<T> {
// The sliding buffer of doubles. private final ArrayList<T> buffer;
private final double[] buffer;
// The location that the next write will occur at. // The location that the next write will occur at.
private int index; private int index;
@@ -43,16 +43,17 @@ class DoubleRingBuffer {
* *
* @param size the size * @param size the size
*/ */
DoubleRingBuffer(int size) { RingBuffer(int size) {
if (size < 1) { if (size < 1) {
throw new IllegalArgumentException("The buffer size must be greater than 1."); throw new IllegalArgumentException("The buffer size must be greater than 1.");
} }
buffer = new double[size];
buffer = new ArrayList<T>(size);
reset(); reset();
} }
DoubleRingBuffer(DoubleRingBuffer toCopy) { RingBuffer(RingBuffer<T> toCopy) {
this.buffer = Arrays.copyOf(toCopy.buffer, toCopy.buffer.length); this.buffer = new ArrayList<>(toCopy.buffer);
this.index = toCopy.index; this.index = toCopy.index;
this.isFull = toCopy.isFull; this.isFull = toCopy.isFull;
} }
@@ -75,31 +76,48 @@ class DoubleRingBuffer {
/** /**
* Gets the average of the buffer. * Gets the average of the buffer.
*/ */
public double getAverage() { public T getAverage() {
int numberOfEntries = isFull ? buffer.length : index; int numberOfEntries = isFull ? buffer.size() : index;
if (numberOfEntries == 0) { if (numberOfEntries == 0) {
return 0; return null;
} }
double sum = 0; Double sum = null;
int numberOfUsedEntries = 0;
for (int i = 0; i < numberOfEntries; i++) { for (int i = 0; i < numberOfEntries; i++) {
sum += buffer[i]; Number value = from(buffer.get(i));
if (value != null) {
if (sum == null) {
sum = 0.0;
}
sum += value.doubleValue();
numberOfUsedEntries++;
}
}
if (sum == null) {
return null;
} else {
return to(sum / numberOfUsedEntries);
} }
return sum / numberOfEntries;
} }
@Nullable
protected abstract Number from(T object);
protected abstract T to(double object);
/** /**
* Adds a double to the buffer. * Adds a double to the buffer.
* If the buffer is full the oldest element is overwritten. * If the buffer is full the oldest element is overwritten.
* *
* @param value the double to add * @param value the double to add
*/ */
public void setNext(double value) { public void setNext(T value) {
if (index == buffer.length) { if (index == buffer.size()) {
index = 0; index = 0;
} }
buffer[index] = value; buffer.add(index, value);
index++; index++;
if (index == buffer.length) { if (index == buffer.size()) {
isFull = true; isFull = true;
} }
} }
@@ -110,9 +128,9 @@ class DoubleRingBuffer {
StringBuilder builder = new StringBuilder("Full: "); StringBuilder builder = new StringBuilder("Full: ");
builder.append(isFull); builder.append(isFull);
builder.append("\n"); builder.append("\n");
for (int i = 0; i < buffer.length; i++) { for (int i = 0; i < buffer.size(); i++) {
builder.append((i == index) ? "<<" : "["); builder.append((i == index) ? "<<" : "[");
builder.append(buffer[i]); builder.append(buffer.get(i));
builder.append((i == index) ? ">> " : "] "); builder.append((i == index) ? ">> " : "] ");
} }
return builder.toString(); return builder.toString();
@@ -0,0 +1,27 @@
package de.dennisguse.opentracks.stats;
import androidx.annotation.Nullable;
import de.dennisguse.opentracks.content.data.Speed;
public class SpeedRingBuffer extends RingBuffer<Speed> {
SpeedRingBuffer(int size) {
super(size);
}
SpeedRingBuffer(RingBuffer<Speed> toCopy) {
super(toCopy);
}
@Nullable
@Override
protected Number from(Speed object) {
return object.toMPS();
}
@Override
protected Speed to(double object) {
return Speed.of(object);
}
}
@@ -23,6 +23,7 @@ import androidx.annotation.VisibleForTesting;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import de.dennisguse.opentracks.content.data.Altitude;
import de.dennisguse.opentracks.content.data.Distance; import de.dennisguse.opentracks.content.data.Distance;
import de.dennisguse.opentracks.content.data.Speed; import de.dennisguse.opentracks.content.data.Speed;
@@ -258,8 +259,10 @@ public class TrackStatistics {
altitudeExtremities.setMax(altitude_m); altitudeExtremities.setMax(altitude_m);
} }
public void updateAltitudeExtremities(double altitude_m) { public void updateAltitudeExtremities(Altitude altitude) {
altitudeExtremities.update(altitude_m); if (altitude != null) {
altitudeExtremities.update(altitude.toM());
}
} }
public boolean hasTotalAltitudeGain() { public boolean hasTotalAltitudeGain() {
@@ -24,6 +24,7 @@ import androidx.annotation.VisibleForTesting;
import java.time.Duration; import java.time.Duration;
import java.util.List; import java.util.List;
import de.dennisguse.opentracks.content.data.Altitude;
import de.dennisguse.opentracks.content.data.Distance; import de.dennisguse.opentracks.content.data.Distance;
import de.dennisguse.opentracks.content.data.Speed; import de.dennisguse.opentracks.content.data.Speed;
import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.data.TrackPoint;
@@ -61,8 +62,8 @@ public class TrackStatisticsUpdater {
private final TrackStatistics trackStatistics; private final TrackStatistics trackStatistics;
private final DoubleRingBuffer altitudeBuffer_m; private final AltitudeRingBuffer altitudeBuffer;
private final DoubleRingBuffer speedBuffer_mps; private final SpeedRingBuffer speedBuffer;
// The current segment's statistics // The current segment's statistics
private final TrackStatistics currentSegment; private final TrackStatistics currentSegment;
@@ -82,16 +83,16 @@ public class TrackStatisticsUpdater {
this.trackStatistics = trackStatistics; this.trackStatistics = trackStatistics;
this.currentSegment = new TrackStatistics(); this.currentSegment = new TrackStatistics();
altitudeBuffer_m = new DoubleRingBuffer(ALTITUDE_SMOOTHING_FACTOR); altitudeBuffer = new AltitudeRingBuffer(ALTITUDE_SMOOTHING_FACTOR);
speedBuffer_mps = new DoubleRingBuffer(SPEED_SMOOTHING_FACTOR); speedBuffer = new SpeedRingBuffer(SPEED_SMOOTHING_FACTOR);
} }
public TrackStatisticsUpdater(TrackStatisticsUpdater toCopy) { public TrackStatisticsUpdater(TrackStatisticsUpdater toCopy) {
this.currentSegment = new TrackStatistics(toCopy.currentSegment); this.currentSegment = new TrackStatistics(toCopy.currentSegment);
this.trackStatistics = new TrackStatistics(toCopy.trackStatistics); this.trackStatistics = new TrackStatistics(toCopy.trackStatistics);
this.altitudeBuffer_m = new DoubleRingBuffer(toCopy.altitudeBuffer_m); this.altitudeBuffer = new AltitudeRingBuffer(toCopy.altitudeBuffer);
this.speedBuffer_mps = new DoubleRingBuffer(toCopy.speedBuffer_mps); this.speedBuffer = new SpeedRingBuffer(toCopy.speedBuffer);
this.lastTrackPoint = toCopy.lastTrackPoint; this.lastTrackPoint = toCopy.lastTrackPoint;
} }
@@ -136,7 +137,11 @@ public class TrackStatisticsUpdater {
//Update absolute (GPS-based) altitude //Update absolute (GPS-based) altitude
if (trackPoint.hasAltitude()) { if (trackPoint.hasAltitude()) {
updateAbsoluteAltitude(trackPoint.getAltitude().toM()); // Update altitude using the smoothed average
altitudeBuffer.setNext(trackPoint.getAltitude());
Altitude newAverage = altitudeBuffer.getAverage();
currentSegment.updateAltitudeExtremities(newAverage);
} }
// Update total distance // Update total distance
@@ -164,7 +169,7 @@ public class TrackStatisticsUpdater {
// Update max speed // Update max speed
updateSpeed(trackPoint, lastTrackPoint); updateSpeed(trackPoint, lastTrackPoint);
} else { } else {
speedBuffer_mps.reset(); speedBuffer.reset();
} }
@@ -183,20 +188,20 @@ public class TrackStatisticsUpdater {
currentSegment.reset(trackPoint.getTime()); currentSegment.reset(trackPoint.getTime());
lastTrackPoint = null; lastTrackPoint = null;
altitudeBuffer_m.reset(); altitudeBuffer.reset();
speedBuffer_mps.reset(); speedBuffer.reset();
} }
/** /**
* Gets the smoothed altitude over several readings. * Gets the smoothed altitude over several readings.
* The altitude readings is noisy so the smoothed altitude is better than the raw altitude for many tasks. * The altitude readings is noisy so the smoothed altitude is better than the raw altitude for many tasks.
*/ */
public double getSmoothedAltitude() { public Altitude getSmoothedAltitude() {
return altitudeBuffer_m.getAverage(); return altitudeBuffer.getAverage();
} }
public Speed getSmoothedSpeed() { public Speed getSmoothedSpeed() {
return Speed.of(speedBuffer_mps.getAverage()); return speedBuffer.getAverage();
} }
/** /**
@@ -205,10 +210,10 @@ public class TrackStatisticsUpdater {
@VisibleForTesting @VisibleForTesting
private void updateSpeed(@NonNull TrackPoint trackPoint, @NonNull TrackPoint lastTrackPoint) { private void updateSpeed(@NonNull TrackPoint trackPoint, @NonNull TrackPoint lastTrackPoint) {
if (!trackPoint.isMoving()) { if (!trackPoint.isMoving()) {
speedBuffer_mps.reset(); speedBuffer.reset();
} else if (isValidSpeed(trackPoint, lastTrackPoint)) { } else if (isValidSpeed(trackPoint, lastTrackPoint)) {
speedBuffer_mps.setNext(trackPoint.getSpeed().toMPS()); speedBuffer.setNext(trackPoint.getSpeed());
Speed average = Speed.of(speedBuffer_mps.getAverage()); Speed average = speedBuffer.getAverage();
if (average.greaterThan(currentSegment.getMaxSpeed())) { if (average.greaterThan(currentSegment.getMaxSpeed())) {
currentSegment.setMaxSpeed(average); currentSegment.setMaxSpeed(average);
} }
@@ -217,14 +222,6 @@ public class TrackStatisticsUpdater {
} }
} }
private void updateAbsoluteAltitude(double altitude) {
// Update altitude using the smoothed average
altitudeBuffer_m.setNext(altitude);
double newAverage = altitudeBuffer_m.getAverage();
currentSegment.updateAltitudeExtremities(newAverage);
}
private boolean isValidSpeed(@NonNull TrackPoint trackPoint, @NonNull TrackPoint lastTrackPoint) { private boolean isValidSpeed(@NonNull TrackPoint trackPoint, @NonNull TrackPoint lastTrackPoint) {
// There are a lot of noisy speed readings. Do the cheapest checks first, most expensive last. // There are a lot of noisy speed readings. Do the cheapest checks first, most expensive last.
if (trackPoint.getSpeed().isZero()) { if (trackPoint.getSpeed().isZero()) {
@@ -242,8 +239,8 @@ public class TrackStatisticsUpdater {
} }
// Only check if the speed buffer is full. Check that the speed is less than 10X the smoothed average and the speed difference doesn't imply 2g acceleration. // Only check if the speed buffer is full. Check that the speed is less than 10X the smoothed average and the speed difference doesn't imply 2g acceleration.
if (speedBuffer_mps.isFull()) { if (speedBuffer.isFull()) {
Speed average = Speed.of(speedBuffer_mps.getAverage()); Speed average = speedBuffer.getAverage();
Speed speedDifference = Speed.absDiff(average, trackPoint.getSpeed()); Speed speedDifference = Speed.absDiff(average, trackPoint.getSpeed());
return trackPoint.getSpeed().lessThan(average.mul(10)) && speedDifference.lessThan(maxAcceleration); return trackPoint.getSpeed().lessThan(average.mul(10)) && speedDifference.lessThan(maxAcceleration);