mirror of
https://codeberg.org/OpenTracksApp/OpenTracks.git
synced 2026-10-02 17:43:06 +02:00
Move .merge() from SegmentStatisticUpdater to Statistics.
This is a functional change as maxSpeed is now determined by Segment (rather than the joined Segment).
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
package de.dennisguse.opentracks.data.models;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
//TODO Add @NonNull to attributes
|
||||
public record Statistics(
|
||||
@@ -54,4 +56,73 @@ public record Statistics(
|
||||
if (altitudeExtremities == null) return 0;
|
||||
return altitudeExtremities.max_m();
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines these statistics with those from another object.
|
||||
* This assumes that the time periods covered by each do not intersect.
|
||||
*/
|
||||
//TODO Should be refactored to append only
|
||||
@NonNull
|
||||
public Statistics merge(@NonNull Statistics other) {
|
||||
HeartRate newAvgHeartRate = avgHeartRate;
|
||||
if (avgHeartRate == null) {
|
||||
newAvgHeartRate = other.avgHeartRate;
|
||||
} else {
|
||||
if (other.avgHeartRate != null) {
|
||||
// Using total time as weights for the averaging.
|
||||
// Important to do this before total time is updated
|
||||
newAvgHeartRate = HeartRate.of(
|
||||
(totalDuration.getSeconds() * avgHeartRate.getBPM() + other.totalDuration.getSeconds() * other.avgHeartRate.getBPM())
|
||||
/ (totalDuration.getSeconds() + other.totalDuration.getSeconds())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Power newAvgPower = avgPower;
|
||||
if (avgPower == null) {
|
||||
newAvgPower = other.avgPower;
|
||||
} else {
|
||||
if (other.avgPower != null) {
|
||||
// Using total time as weights for the averaging.
|
||||
// Important to do this before total time is updated
|
||||
newAvgPower = Power.of(
|
||||
(totalDuration.getSeconds() * avgPower.getW() + other.totalDuration.getSeconds() * other.avgPower.getW())
|
||||
/ (totalDuration.getSeconds() + other.totalDuration.getSeconds())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AltitudeExtremities newAltitudeExtremities;
|
||||
if (altitudeExtremities != null && other.altitudeExtremities != null) {
|
||||
newAltitudeExtremities = new AltitudeExtremities(
|
||||
Math.min(altitudeExtremities.min_m(), other.altitudeExtremities.min_m()),
|
||||
Math.max(altitudeExtremities.max_m(), other.altitudeExtremities.max_m())
|
||||
);
|
||||
} else {
|
||||
newAltitudeExtremities = altitudeExtremities != null ? altitudeExtremities : other.altitudeExtremities;
|
||||
}
|
||||
|
||||
AltitudeGainLoss newAltitudeGainLoss;
|
||||
if (altitudeGainLoss != null && other.altitudeGainLoss != null) {
|
||||
newAltitudeGainLoss = new AltitudeGainLoss(
|
||||
altitudeGainLoss.gain_m() + other.altitudeGainLoss.gain_m(),
|
||||
altitudeGainLoss.loss_m() + other.altitudeGainLoss.loss_m()
|
||||
);
|
||||
} else {
|
||||
newAltitudeGainLoss = altitudeGainLoss != null ? altitudeGainLoss : other.altitudeGainLoss;
|
||||
}
|
||||
|
||||
return new Statistics(
|
||||
startTime == null ? other.startTime : startTime.isBefore(other.startTime) ? startTime : other.startTime,
|
||||
stopTime == null ? other.stopTime : stopTime.isAfter(other.stopTime) ? stopTime : other.stopTime,
|
||||
totalDuration.plus(other.totalDuration),
|
||||
movingDuration.plus(other.movingDuration),
|
||||
totalDistance.plus(other.totalDistance),
|
||||
Speed.max(maxSpeed, other.maxSpeed),
|
||||
newAltitudeExtremities,
|
||||
newAltitudeGainLoss,
|
||||
newAvgHeartRate,
|
||||
newAvgPower
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,10 @@ public class SegmentStatisticUpdater {
|
||||
reset();
|
||||
}
|
||||
|
||||
public SegmentStatisticUpdater(Instant startTime) {
|
||||
reset(startTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
*
|
||||
@@ -98,81 +102,8 @@ public class SegmentStatisticUpdater {
|
||||
avgPower = statistics.avgPower();
|
||||
}
|
||||
|
||||
public Statistics aggregate(Statistics statistics) {
|
||||
SegmentStatisticUpdater intermediate = new SegmentStatisticUpdater(statistics);
|
||||
intermediate.merge(this);
|
||||
return intermediate.getStatistics();
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines these statistics with those from another object.
|
||||
* This assumes that the time periods covered by each do not intersect.
|
||||
*/
|
||||
//TODO Should be refactored to append only [mainly due to isIdle]
|
||||
public void merge(SegmentStatisticUpdater other) {
|
||||
if (startTime == null) {
|
||||
startTime = other.startTime;
|
||||
} else {
|
||||
startTime = startTime.isBefore(other.startTime) ? startTime : other.startTime;
|
||||
}
|
||||
if (stopTime == null) {
|
||||
stopTime = other.stopTime;
|
||||
} else {
|
||||
stopTime = stopTime.isAfter(other.stopTime) ? stopTime : other.stopTime;
|
||||
}
|
||||
|
||||
if (avgHeartRate == null) {
|
||||
avgHeartRate = other.avgHeartRate;
|
||||
} else {
|
||||
if (other.avgHeartRate != null) {
|
||||
// Using total time as weights for the averaging.
|
||||
// Important to do this before total time is updated
|
||||
avgHeartRate = HeartRate.of(
|
||||
(totalDuration.getSeconds() * avgHeartRate.getBPM() + other.totalDuration.getSeconds() * other.avgHeartRate.getBPM())
|
||||
/ (totalDuration.getSeconds() + other.totalDuration.getSeconds())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (avgPower == null) {
|
||||
avgPower = other.avgPower;
|
||||
} else {
|
||||
if (other.avgPower != null) {
|
||||
// Using total time as weights for the averaging.
|
||||
// Important to do this before total time is updated
|
||||
avgPower = Power.of(
|
||||
(totalDuration.getSeconds() * avgPower.getW() + other.totalDuration.getSeconds() * other.avgPower.getW())
|
||||
/ (totalDuration.getSeconds() + other.totalDuration.getSeconds())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
totalDistance = totalDistance.plus(other.totalDistance);
|
||||
totalDuration = totalDuration.plus(other.totalDuration);
|
||||
movingDuration = movingDuration.plus(other.movingDuration);
|
||||
maxSpeed = Speed.max(maxSpeed, other.maxSpeed);
|
||||
if (other.altitudeExtremities.hasData()) {
|
||||
altitudeExtremities.update(other.altitudeExtremities.getMin());
|
||||
altitudeExtremities.update(other.altitudeExtremities.getMax());
|
||||
}
|
||||
if (totalAltitudeGain_m == null) {
|
||||
if (other.totalAltitudeGain_m != null) {
|
||||
totalAltitudeGain_m = other.totalAltitudeGain_m;
|
||||
}
|
||||
} else {
|
||||
if (other.totalAltitudeGain_m != null) {
|
||||
totalAltitudeGain_m += other.totalAltitudeGain_m;
|
||||
}
|
||||
}
|
||||
if (totalAltitudeLoss_m == null) {
|
||||
if (other.totalAltitudeLoss_m != null) {
|
||||
totalAltitudeLoss_m = other.totalAltitudeLoss_m;
|
||||
}
|
||||
} else {
|
||||
if (other.totalAltitudeLoss_m != null) {
|
||||
totalAltitudeLoss_m += other.totalAltitudeLoss_m;
|
||||
}
|
||||
}
|
||||
public Statistics merge(Statistics statistics) {
|
||||
return statistics.merge(getStatistics());
|
||||
}
|
||||
|
||||
public boolean isInitialized() {
|
||||
|
||||
@@ -94,7 +94,7 @@ public class TrackStatisticsUpdater {
|
||||
* Compute TrackStatistics.
|
||||
*/
|
||||
public Statistics getTrackStatistics() {
|
||||
return currentSegment.aggregate(statisticsWithoutCurrentSegment);
|
||||
return currentSegment.merge(statisticsWithoutCurrentSegment);
|
||||
}
|
||||
|
||||
public boolean isIdle() {
|
||||
@@ -200,7 +200,7 @@ public class TrackStatisticsUpdater {
|
||||
|
||||
private void reset(TrackPoint trackPoint) {
|
||||
if (currentSegment.isInitialized()) {
|
||||
statisticsWithoutCurrentSegment = currentSegment.aggregate(statisticsWithoutCurrentSegment);
|
||||
statisticsWithoutCurrentSegment = currentSegment.merge(statisticsWithoutCurrentSegment);
|
||||
}
|
||||
currentSegment.reset(trackPoint.getTime());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user