Merge pull request #1310 from OpenTracksApp/time

Refactoring things regarding Duration, Speed, and Distance
This commit is contained in:
Dennis Guse
2022-08-21 23:25:44 +02:00
committed by GitHub
20 changed files with 105 additions and 142 deletions
+4 -2
View File
@@ -6,7 +6,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.2.2'
classpath 'com.android.tools.build:gradle:7.3.0-rc01'
}
}
@@ -81,6 +81,8 @@ android {
}
}
namespace 'de.dennisguse.opentracks'
buildTypes {
debug {
applicationIdSuffix ".debug"
@@ -118,7 +120,7 @@ android {
}
dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.6'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.0'
implementation 'androidx.appcompat:appcompat:1.5.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.5.1'
Binary file not shown.
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -7,6 +7,7 @@ import junit.framework.TestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.time.Duration;
import java.time.Instant;
import de.dennisguse.opentracks.data.models.Track;
@@ -105,7 +106,7 @@ public class TrackSelectionTest extends TestCase {
long oneDay = 24 * 60 * 60 * 1000;
TrackSelection filterWrong1 = new TrackSelection().addDateRange(instant, null);
TrackSelection filterWrong2 = new TrackSelection().addDateRange(null, instant);
TrackSelection filterOk = new TrackSelection().addDateRange(instant, instant.plusMillis(oneDay));
TrackSelection filterOk = new TrackSelection().addDateRange(instant, instant.plus(Duration.ofDays(1)));
// when
SelectionData selectionWrong1 = filterWrong1.buildSelection();
@@ -463,7 +463,7 @@ public class ExportImportTest {
contentProviderUtils.deleteTrack(context, trackId);
// then
InputStream expected = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.csv_export);
InputStream expected = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.csv_export);
String expectedText = new BufferedReader(new InputStreamReader(expected, StandardCharsets.UTF_8))
.lines()
.collect(Collectors.joining("\n"));
@@ -69,7 +69,7 @@ public class GPXTrackImporterTest {
public void gpx_with_pause_resume() throws IOException {
// given
XMLImporter importer = new XMLImporter(new GpxTrackImporter(context, trackImporter));
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.legacy_gpx_pause_resume);
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.legacy_gpx_pause_resume);
// when
// 1. import
@@ -123,7 +123,7 @@ public class GPXTrackImporterTest {
public void gpx_without_speed() throws IOException {
// given
XMLImporter importer = new XMLImporter(new GpxTrackImporter(context, trackImporter));
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.gpx11_without_speed);
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.gpx11_without_speed);
// when
// 1. import
@@ -171,7 +171,7 @@ public class GPXTrackImporterTest {
public void gpx_speed_no_namespace() throws IOException {
// given
XMLImporter importer = new XMLImporter(new GpxTrackImporter(context, trackImporter));
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.gpx11_with_speed_no_namespace);
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.gpx11_with_speed_no_namespace);
// when
// 1. import
@@ -221,8 +221,8 @@ public class GPXTrackImporterTest {
public void importExportTest_timezone() throws IOException {
// given
XMLImporter importer = new XMLImporter(new GpxTrackImporter(context, trackImporter));
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.gpx_timezone);
InputStream inputStreamExpected = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.gpx_timezone);
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.gpx_timezone);
InputStream inputStreamExpected = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.gpx_timezone);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
@@ -60,7 +60,7 @@ public class KMLTrackImporterTest {
public void kml22_order_location_and_when() throws IOException {
// given
XMLImporter importer = new XMLImporter(new KmlTrackImporter(context, trackImporter));
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.kml22_order_location_and_when);
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.kml22_order_location_and_when);
// when
// 1. import
@@ -109,7 +109,7 @@ public class KMLTrackImporterTest {
public void kml22_time_decreases() throws IOException {
// given
XMLImporter importer = new XMLImporter(new KmlTrackImporter(context, trackImporter));
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.kml22_time_decreases);
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.kml22_time_decreases);
// when
// 1. import
@@ -149,7 +149,7 @@ public class KMLTrackImporterTest {
public void kml22_with_statistics_marker() throws IOException {
// given
XMLImporter importer = new XMLImporter(new KmlTrackImporter(context, trackImporter));
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.legacy_kml22_statistics_marker);
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.legacy_kml22_statistics_marker);
// when
// 1. import
@@ -223,7 +223,7 @@ public class KMLTrackImporterTest {
public void kml_without_locations() throws IOException {
// given
XMLImporter importer = new XMLImporter(new KmlTrackImporter(context, trackImporter));
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.kml22_without_locations);
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.kml22_without_locations);
// when
importTrackId = importer.importFile(inputStream).get(0);
@@ -234,7 +234,7 @@ public class KMLTrackImporterTest {
public void kml_when_locations_different() throws IOException {
// given
XMLImporter importer = new XMLImporter(new KmlTrackImporter(context, trackImporter));
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.kml22_when_locations_different);
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.kml22_when_locations_different);
// when
importTrackId = importer.importFile(inputStream).get(0);
@@ -21,7 +21,6 @@ import de.dennisguse.opentracks.data.TrackPointIterator;
import de.dennisguse.opentracks.data.models.Distance;
import de.dennisguse.opentracks.data.models.Track;
import de.dennisguse.opentracks.data.models.TrackPoint;
import de.dennisguse.opentracks.data.models.UnitConversions;
import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.stats.TrackStatisticsUpdater;
@@ -180,7 +179,7 @@ public class IntervalStatisticsTest {
// then
assertEquals(trackStatistics.getTotalDistance().toM(), totalDistance.toM(), 0.01);
assertEquals(trackStatistics.getTotalTime().toMillis(), totalTime * UnitConversions.S_TO_MS, 1);
assertEquals(trackStatistics.getTotalTime().toSeconds(), totalTime, 0.01);
assertEquals(intervalList.size(), (int) Math.ceil(trackStatistics.getTotalDistance().toM() / distanceInterval));
if (totalGain != null) {
assertEquals(totalGain, numberOfPoints * TestDataUtil.ALTITUDE_GAIN, 0.1);
-1
View File
@@ -15,7 +15,6 @@ limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="de.dennisguse.opentracks"
android:installLocation="auto">
<supports-screens
@@ -6,7 +6,6 @@ import androidx.annotation.VisibleForTesting;
import de.dennisguse.opentracks.data.models.Distance;
import de.dennisguse.opentracks.data.models.Speed;
import de.dennisguse.opentracks.data.models.TrackPoint;
import de.dennisguse.opentracks.data.models.UnitConversions;
import de.dennisguse.opentracks.settings.UnitSystem;
import de.dennisguse.opentracks.stats.TrackStatistics;
@@ -41,7 +40,7 @@ public class ChartPoint {
if (smoothedSpeed != null) {
speed = smoothedSpeed.to(unitSystem);
pace = smoothedSpeed.toPace(unitSystem).toMillis() * UnitConversions.MS_TO_S * UnitConversions.S_TO_MIN;
pace = smoothedSpeed.toPace(unitSystem).toSeconds() / 60d;
}
if (trackPoint.hasHeartRate()) {
heartRate = (double) trackPoint.getHeartRate().getBPM();
@@ -2,22 +2,35 @@ package de.dennisguse.opentracks.data.models;
import androidx.annotation.NonNull;
import java.time.Duration;
import java.util.Objects;
public class Cadence {
public static Cadence of(float value) {
return new Cadence(value);
public static Cadence of(float value, Duration duration) {
if (duration.isZero()) {
return zero();
}
return new Cadence(value / (duration.toMillis() / (float) Duration.ofMinutes(1).toMillis()));
}
private final float value;
public static Cadence of(float value_rpm) {
return new Cadence(value_rpm);
}
public static Cadence zero() {
return of(0.0f);
}
private final float value_rpm;
private Cadence(float value) {
this.value = value;
this.value_rpm = value;
}
public float getRPM() {
return value;
return value_rpm;
}
@Override
@@ -25,19 +38,19 @@ public class Cadence {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Cadence cadence = (Cadence) o;
return Float.compare(cadence.value, value) == 0;
return Float.compare(cadence.value_rpm, value_rpm) == 0;
}
@Override
public int hashCode() {
return Objects.hash(value);
return Objects.hash(value_rpm);
}
@NonNull
@Override
public String toString() {
return "Cadence{" +
"value=" + value + " rpm" +
"value=" + value_rpm + " rpm" +
'}';
}
}
@@ -34,15 +34,15 @@ public class Distance {
}
public static Distance ofMile(double distance_mile) {
return of(distance_mile * UnitConversions.MI_TO_M);
return of(distance_mile * MI_TO_M);
}
public static Distance ofNauticalMile(double distance_mile) {
return of(distance_mile * UnitConversions.NAUTICAL_MILE_TO_M);
return of(distance_mile * NAUTICAL_MILE_TO_M);
}
public static Distance ofKilometer(double distance_km) {
return of(distance_km * UnitConversions.KM_TO_M);
return of(distance_km * KM_TO_M);
}
public static Distance ofMM(double distance_mm) {
@@ -117,19 +117,19 @@ public class Distance {
}
public double toKM() {
return distance_m * UnitConversions.M_TO_KM;
return distance_m * M_TO_KM;
}
public double toFT() {
return distance_m * UnitConversions.M_TO_FT;
return distance_m * M_TO_FT;
}
public double toMI() {
return toKM() * UnitConversions.KM_TO_MI;
return distance_m * M_TO_MI;
}
public double toNauticalMiles() {
return toKM() * UnitConversions.KM_TO_NAUTICAL_MILE;
return distance_m * M_TO_NAUTICAL_MILE;
}
public double toKM_Miles(UnitSystem unitSystem) {
@@ -177,4 +177,17 @@ public class Distance {
"distance_m=" + distance_m +
'}';
}
// multiplication factors for conversion
private static final double KM_TO_M = 1000.0;
private static final double M_TO_KM = 1 / KM_TO_M;
public static final double MI_TO_M = 1609.344;
public static final double M_TO_MI = 1 / MI_TO_M;
private static final double MI_TO_FT = 5280.0;
public static final double M_TO_FT = M_TO_MI * MI_TO_FT;
private static final double NAUTICAL_MILE_TO_M = 1852.0;
private static final double M_TO_NAUTICAL_MILE = 1 / NAUTICAL_MILE_TO_M;
}
@@ -16,11 +16,14 @@ public class DistanceFormatter {
private final int decimalCount;
private final double threshold;
private final UnitSystem unitSystem;
private DistanceFormatter(Resources resources, int decimalCount, UnitSystem unitSystem) {
private DistanceFormatter(Resources resources, int decimalCount, double threshold, UnitSystem unitSystem) {
this.resources = resources;
this.decimalCount = decimalCount;
this.threshold = threshold;
this.unitSystem = unitSystem;
assert unitSystem != null;
}
@@ -56,19 +59,19 @@ public class DistanceFormatter {
switch (unitSystem) {
case METRIC:
if (distance.greaterThan(Distance.of(500))) {
if (distance.greaterThan(Distance.ofKilometer(threshold))) {
return new Pair<>(StringUtils.formatDecimal(distance.toKM(), decimalCount), resources.getString(R.string.unit_kilometer));
} else {
return new Pair<>(StringUtils.formatDecimal(distance.toM(), decimalCount), resources.getString(R.string.unit_meter));
}
case IMPERIAL:
if (distance.greaterThan(Distance.ofMile(0.5))) {
if (distance.greaterThan(Distance.ofMile(threshold))) {
return new Pair<>(StringUtils.formatDecimal(distance.toMI(), decimalCount), resources.getString(R.string.unit_mile));
} else {
return new Pair<>(StringUtils.formatDecimal(distance.toFT(), decimalCount), resources.getString(R.string.unit_feet));
}
case NAUTICAL_IMPERIAL:
if (distance.greaterThan(Distance.ofNauticalMile(0.5))) {
if (distance.greaterThan(Distance.ofNauticalMile(threshold))) {
return new Pair<>(StringUtils.formatDecimal(distance.toNauticalMiles(), decimalCount), resources.getString(R.string.unit_nautical_mile));
} else {
return new Pair<>(StringUtils.formatDecimal(distance.toFT(), decimalCount), resources.getString(R.string.unit_feet));
@@ -88,8 +91,11 @@ public class DistanceFormatter {
private UnitSystem unitSystem;
private double threshold;
public Builder() {
decimalCount = 2;
threshold = 0.5;
}
public Builder setDecimalCount(int decimalCount) {
@@ -102,8 +108,13 @@ public class DistanceFormatter {
return this;
}
public Builder setThreshold(double threshold) {
this.threshold = threshold;
return this;
}
public DistanceFormatter build(Resources resource) {
return new DistanceFormatter(resource, decimalCount, unitSystem);
return new DistanceFormatter(resource, decimalCount, threshold, unitSystem);
}
public DistanceFormatter build(Context context) {
@@ -15,7 +15,7 @@ public class Speed {
return zero();
}
return new Speed(distance.toM() / (duration.toMillis() * UnitConversions.MS_TO_S));
return new Speed(distance.toM() / (duration.toMillis() / (double) Duration.ofSeconds(1).toMillis()));
}
public static Speed of(double speed_mps) {
@@ -85,16 +85,23 @@ public class Speed {
return speed_mps;
}
/**
* We interpret {@link Speed} here as a {@link Distance} over 1h.
*/
private Distance toH() {
return Distance.of(speed_mps * Duration.ofHours(1).toSeconds());
}
public double toKMH() {
return speed_mps * UnitConversions.MPS_TO_KMH;
return toH().toKM();
}
public double toMPH() {
return toKMH() * UnitConversions.KM_TO_MI;
return toH().toMI();
}
public double toKnots() {
return toKMH() * UnitConversions.KM_TO_NAUTICAL_MILE;
return toH().toNauticalMiles();
}
public Duration toPace(UnitSystem unitSystem) {
@@ -102,20 +109,7 @@ public class Speed {
return Duration.ofSeconds(0);
}
double distance = speed_mps;
switch (unitSystem) { //TODO Can we use to(UnitSystem)?
case METRIC:
distance *= UnitConversions.M_TO_KM;
break;
case IMPERIAL:
distance *= UnitConversions.M_TO_MI;
break;
case NAUTICAL_IMPERIAL:
distance *= UnitConversions.M_TO_NAUTICAL_MILE;
break;
default:
throw new RuntimeException("Not implemented");
}
double distance = Distance.of(speed_mps).toKM_Miles(unitSystem);
return Duration.ofSeconds(Math.round(1 / distance));
}
@@ -1,69 +0,0 @@
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package de.dennisguse.opentracks.data.models;
/**
* Unit conversion constants.
*
* @author Sandor Dornbush
*/
public class UnitConversions {
// Time //TODO Use Duration
// multiplication factor to convert seconds to milliseconds
@Deprecated
public static final long S_TO_MS = 1000;
// multiplication factor to convert milliseconds to seconds
@Deprecated
public static final double MS_TO_S = 1d / S_TO_MS;
// multiplication factor to convert minutes to seconds
@Deprecated
public static final double MIN_TO_S = 60.0;
// multiplication factor to convert seconds to minutes
@Deprecated
public static final double S_TO_MIN = 1 / MIN_TO_S;
// multiplication factor to convert minutes to hours
@Deprecated
public static final double MIN_TO_HR = 1 / 60.0;
// multiplication factor to convert kilometers to miles
public static final double KM_TO_MI = 0.621371192;
// Distance //TODO Make private to Distance class!
// multiplication factor to convert miles to feet
private static final double MI_TO_FT = 5280.0;
// multiplication factor to covert kilometers to meters
public static final double KM_TO_M = 1000.0;
// multiplication factor to convert meters to kilometers
public static final double M_TO_KM = 1 / KM_TO_M;
// multiplication factor to convert meters to miles
public static final double M_TO_MI = M_TO_KM * KM_TO_MI;
// multiplication factor to convert meters to feet
public static final double M_TO_FT = M_TO_MI * MI_TO_FT;
public static final double NAUTICAL_MILE_TO_M = 1852.0;
public static final double M_TO_NAUTICAL_MILE = 1 / NAUTICAL_MILE_TO_M;
public static final double KM_TO_NAUTICAL_MILE = 1000 * M_TO_NAUTICAL_MILE;
// multiplication factor to convert meters per second to kilometers per hour
public static final double MPS_TO_KMH = M_TO_KM / (S_TO_MIN * MIN_TO_HR);
// multiplication factor to convert miles to km
public static final double MI_TO_KM = 1 / KM_TO_MI;
// multiplication factor to convert miles to m
public static final double MI_TO_M = MI_TO_KM * KM_TO_M;
private UnitConversions() {
}
}
@@ -11,7 +11,6 @@ import java.time.Duration;
import de.dennisguse.opentracks.data.models.Cadence;
import de.dennisguse.opentracks.data.models.Distance;
import de.dennisguse.opentracks.data.models.Speed;
import de.dennisguse.opentracks.data.models.UnitConversions;
import de.dennisguse.opentracks.sensors.UintUtils;
/**
@@ -68,8 +67,9 @@ public final class SensorDataCycling {
public void compute(CyclingCadence previous) {
if (hasData() && previous != null && previous.hasData()) {
float timeDiff_ms = UintUtils.diff(crankRevolutionsTime, previous.crankRevolutionsTime, UintUtils.UINT16_MAX) / 1024f * UnitConversions.S_TO_MS;
if (timeDiff_ms <= 0) {
float timeDiff_ms = UintUtils.diff(crankRevolutionsTime, previous.crankRevolutionsTime, UintUtils.UINT16_MAX) / 1024f * 1000;
Duration timeDiff = Duration.ofMillis((long) timeDiff_ms);
if (timeDiff.isZero() || timeDiff.isNegative()) {
Log.e(TAG, "Timestamps difference is invalid: cannot compute cadence.");
value = null;
return;
@@ -82,8 +82,7 @@ public final class SensorDataCycling {
}
long crankDiff = UintUtils.diff(crankRevolutionsCount, previous.crankRevolutionsCount, UintUtils.UINT32_MAX);
float cadence_ms = crankDiff / timeDiff_ms;
value = Cadence.of((float) (cadence_ms / UnitConversions.MS_TO_S / UnitConversions.S_TO_MIN));
value = Cadence.of(crankDiff, timeDiff);
}
}
@@ -147,7 +146,7 @@ public final class SensorDataCycling {
public void compute(DistanceSpeed previous, Distance wheelCircumference) {
if (hasData() && previous != null && previous.hasData()) {
float timeDiff_ms = UintUtils.diff(wheelRevolutionsTime, previous.wheelRevolutionsTime, UintUtils.UINT16_MAX) / 1024f * UnitConversions.S_TO_MS;
float timeDiff_ms = UintUtils.diff(wheelRevolutionsTime, previous.wheelRevolutionsTime, UintUtils.UINT16_MAX) / 1024f * 1000;
Duration timeDiff = Duration.ofMillis((long) timeDiff_ms);
if (timeDiff.isZero() || timeDiff.isNegative()) {
Log.e(TAG, "Timestamps difference is invalid: cannot compute speed.");
@@ -323,7 +323,7 @@ public class PreferencesUtils {
UnitSystem unitSystem = getUnitSystem();
DistanceFormatter formatter = DistanceFormatter.Builder()
.setDecimalCount(1)
.setDecimalCount(0)
.setUnit(unitSystem)
.build(resources);
for (int i = 0; i < values.length; i++) {
@@ -417,7 +417,8 @@ public class PreferencesUtils {
DistanceFormatter formatter = DistanceFormatter.Builder()
.setUnit(unitSystem)
.setDecimalCount(1)
.setDecimalCount(0)
.setThreshold(Double.MAX_VALUE)
.build(resources);
for (int i = 0; i < entryValues.length; i++) {
int value = Integer.parseInt(entryValues[i]);
@@ -461,7 +462,8 @@ public class PreferencesUtils {
UnitSystem unitSystem = getUnitSystem();
DistanceFormatter formatter = DistanceFormatter.Builder()
.setDecimalCount(1)
.setDecimalCount(0)
.setThreshold(Double.MAX_VALUE)
.setUnit(unitSystem)
.build(resources);
for (int i = 0; i < entryValues.length; i++) {
@@ -534,7 +536,8 @@ public class PreferencesUtils {
UnitSystem unitSystem = getUnitSystem();
DistanceFormatter formatter = DistanceFormatter.Builder()
.setDecimalCount(1)
.setDecimalCount(0)
.setThreshold(Double.MAX_VALUE)
.setUnit(unitSystem)
.build(resources);
@@ -30,7 +30,6 @@ import de.dennisguse.opentracks.data.models.Distance;
import de.dennisguse.opentracks.data.models.Speed;
import de.dennisguse.opentracks.data.models.SpeedFormatter;
import de.dennisguse.opentracks.data.models.Track;
import de.dennisguse.opentracks.data.models.UnitConversions;
import de.dennisguse.opentracks.settings.UnitSystem;
import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.util.StringUtils;
@@ -230,7 +229,7 @@ public class DescriptionGenerator {
@VisibleForTesting
void writeAltitude(double altitude_m, StringBuilder builder, int resId, String lineBreak) {
long altitudeInM = Math.round(altitude_m);
long altitudeInFt = Math.round(altitude_m * UnitConversions.M_TO_FT);
long altitudeInFt = Math.round(Distance.of(altitude_m).toFT());
builder.append(context.getString(resId, altitudeInM, altitudeInFt));
builder.append(lineBreak);
}
@@ -27,7 +27,6 @@ import de.dennisguse.opentracks.data.models.Distance;
import de.dennisguse.opentracks.data.models.HeartRate;
import de.dennisguse.opentracks.data.models.Speed;
import de.dennisguse.opentracks.data.models.TrackPoint;
import de.dennisguse.opentracks.data.models.UnitConversions;
/**
* Updater for {@link TrackStatistics}.
@@ -196,7 +195,7 @@ public class TrackStatisticsUpdater {
// See if the speed seems physically likely. Ignore any speeds that imply acceleration greater than 2g.
Duration timeDifference = Duration.between(lastTrackPoint.getTime(), trackPoint.getTime());
Speed maxSpeedDifference = Speed.of(Distance.of(SPEED_MAX_ACCELERATION), Duration.ofMillis(1000))
.mul(timeDifference.toMillis() / UnitConversions.S_TO_MS);
.mul(timeDifference.toSeconds());
Speed speedDifference = Speed.absDiff(lastTrackPoint.getSpeed(), trackPoint.getSpeed());
return speedDifference.lessThan(maxSpeedDifference);
@@ -257,7 +257,8 @@ public class StringUtils {
//TODO altitude_m should be double or a value object
public static Pair<String, String> getAltitudeParts(Context context, Float altitude_m, UnitSystem unitSystem) {
DistanceFormatter formatter = DistanceFormatter.Builder()
.setDecimalCount(1)
.setDecimalCount(0)
.setThreshold(Double.MAX_VALUE)
.setUnit(unitSystem)
.build(context);