diff --git a/src/androidTest/java/de/dennisguse/opentracks/data/models/DistanceFormatterTest.java b/src/androidTest/java/de/dennisguse/opentracks/data/models/DistanceFormatterTest.java
index 95eff8d34..7cbbcad47 100644
--- a/src/androidTest/java/de/dennisguse/opentracks/data/models/DistanceFormatterTest.java
+++ b/src/androidTest/java/de/dennisguse/opentracks/data/models/DistanceFormatterTest.java
@@ -12,6 +12,7 @@ import org.junit.runner.RunWith;
import de.dennisguse.opentracks.settings.UnitSystem;
+//TODO Parametrized tests
@RunWith(AndroidJUnit4.class)
public class DistanceFormatterTest {
@@ -42,4 +43,17 @@ public class DistanceFormatterTest {
// A small number in imperial
assertEquals("328.08 ft", formatter.formatDistance(Distance.of(100)));
}
+
+ @Test
+ public void testFormatDistance_nautical() {
+ DistanceFormatter formatter = DistanceFormatter.Builder()
+ .setDecimalCount(2)
+ .setUnit(UnitSystem.NAUTICAL_IMPERIAL)
+ .build(context);
+
+ // A large number in nautical
+ assertEquals("2.70 NM", formatter.formatDistance(Distance.of(5000)));
+ // A small number in nautical
+ assertEquals("0.05 NM", formatter.formatDistance(Distance.of(100)));
+ }
}
\ No newline at end of file
diff --git a/src/androidTest/java/de/dennisguse/opentracks/data/models/SpeedFormatterTest.java b/src/androidTest/java/de/dennisguse/opentracks/data/models/SpeedFormatterTest.java
index c9ce7ee1f..2a5df4026 100644
--- a/src/androidTest/java/de/dennisguse/opentracks/data/models/SpeedFormatterTest.java
+++ b/src/androidTest/java/de/dennisguse/opentracks/data/models/SpeedFormatterTest.java
@@ -12,6 +12,7 @@ import org.junit.runner.RunWith;
import de.dennisguse.opentracks.settings.UnitSystem;
+//TODO Use make parametrized tests?
@RunWith(AndroidJUnit4.class)
public class SpeedFormatterTest {
@@ -39,12 +40,22 @@ public class SpeedFormatterTest {
.setReportSpeedOrPace(false)
.build(context);
-// assertEquals("TODO", formatter.getSpeedParts(Speed.of(3.34)).first);
-// assertEquals("TODO", formatter.getSpeedParts(Speed.of(3.33)).first);
-
+ assertEquals("8:02", formatter.getSpeedParts(Speed.of(3.34)).first);
assertEquals("min/mi", formatter.getSpeedParts(Speed.zero()).second);
}
+ @Test
+ public void testGetSpeedParts_pace_nautical() {
+ SpeedFormatter formatter = SpeedFormatter.Builder()
+ .setDecimalCount(2)
+ .setUnit(UnitSystem.NAUTICAL_IMPERIAL)
+ .setReportSpeedOrPace(false)
+ .build(context);
+
+ assertEquals("9:14", formatter.getSpeedParts(Speed.of(3.34)).first);
+ assertEquals("min/NM", formatter.getSpeedParts(Speed.zero()).second);
+ }
+
@Test
public void testGetSpeedParts_speed_metric() {
SpeedFormatter formatter = SpeedFormatter.Builder()
@@ -69,6 +80,18 @@ public class SpeedFormatterTest {
assertEquals("mph", formatter.getSpeedParts(Speed.zero()).second);
}
+ @Test
+ public void testGetSpeedParts_speed_nautical() {
+ SpeedFormatter formatter = SpeedFormatter.Builder()
+ .setDecimalCount(2)
+ .setUnit(UnitSystem.NAUTICAL_IMPERIAL)
+ .setReportSpeedOrPace(true)
+ .build(context);
+
+ assertEquals("6.5", formatter.getSpeedParts(Speed.of(3.34)).first);
+ assertEquals("knots", formatter.getSpeedParts(Speed.zero()).second);
+ }
+
@Test
public void testFormatSpeed() {
SpeedFormatter formatter = SpeedFormatter.Builder()
diff --git a/src/main/java/de/dennisguse/opentracks/chart/ChartValueSeries.java b/src/main/java/de/dennisguse/opentracks/chart/ChartValueSeries.java
index dcdd57df1..07bdc50d4 100644
--- a/src/main/java/de/dennisguse/opentracks/chart/ChartValueSeries.java
+++ b/src/main/java/de/dennisguse/opentracks/chart/ChartValueSeries.java
@@ -44,6 +44,7 @@ abstract class ChartValueSeries {
private final int[] intervalValues;
private final int metricTitleId;
private final int imperialTitleId;
+ private final int nauticalTitleId;
private final Paint fillPaint;
private final Paint strokePaint;
private final Paint titlePaint;
@@ -57,24 +58,13 @@ abstract class ChartValueSeries {
private int maxMarkerValue = interval * ChartView.Y_AXIS_INTERVALS;
private boolean enabled = true;
- /**
- * Constructor.
- *
- * @param context the context
- * @param absoluteMin the absolute min value
- * @param absoluteMax the absolute max value
- * @param intervalValues the list of interval values
- * @param metricTitleId the metric title id
- * @param imperialTitleId the imperial title id
- * @param fillColor the fill color
- * @param strokeColor the stroke color
- */
- ChartValueSeries(Context context, int absoluteMin, int absoluteMax, int[] intervalValues, int metricTitleId, int imperialTitleId, int fillColor, int strokeColor, int fontSizeSmall, int fontSizeMedium) {
+ ChartValueSeries(Context context, int absoluteMin, int absoluteMax, int[] intervalValues, int metricTitleId, int imperialTitleId, int nauticalTitleId, int fillColor, int strokeColor, int fontSizeSmall, int fontSizeMedium) {
this.absoluteMin = absoluteMin;
this.absoluteMax = absoluteMax;
this.intervalValues = intervalValues;
this.metricTitleId = metricTitleId;
this.imperialTitleId = imperialTitleId;
+ this.nauticalTitleId = nauticalTitleId;
fillPaint = new Paint();
fillPaint.setStyle(Style.FILL);
@@ -224,39 +214,27 @@ abstract class ChartValueSeries {
return metricTitleId;
case IMPERIAL:
return imperialTitleId;
+ case NAUTICAL_IMPERIAL:
+ return nauticalTitleId;
default:
throw new RuntimeException("Not implemented");
}
}
- /**
- * Gets the title paint.
- */
Paint getTitlePaint() {
return titlePaint;
}
- /**
- * Gets the marker paint.
- */
Paint getMarkerPaint() {
return markerPaint;
}
- /**
- * Gets the largest marker.
- */
String getLargestMarker() {
String minMarker = numberFormat.format(getMinMarkerValue());
String maxMarker = numberFormat.format(getMaxMarkerValue());
return minMarker.length() >= maxMarker.length() ? minMarker : maxMarker;
}
- /**
- * Formats a marker value.
- *
- * @param value the value
- */
String formatMarker(int value) {
return numberFormat.format(value);
}
diff --git a/src/main/java/de/dennisguse/opentracks/chart/ChartView.java b/src/main/java/de/dennisguse/opentracks/chart/ChartView.java
index 3ed5e2188..2c1a4b3a9 100644
--- a/src/main/java/de/dennisguse/opentracks/chart/ChartView.java
+++ b/src/main/java/de/dennisguse/opentracks/chart/ChartView.java
@@ -203,6 +203,7 @@ public class ChartView extends View {
new int[]{5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000},
R.string.description_altitude_metric,
R.string.description_altitude_imperial,
+ R.string.description_altitude_imperial,
R.color.chart_altitude_fill,
R.color.chart_altitude_border,
fontSizeSmall,
@@ -224,6 +225,7 @@ public class ChartView extends View {
new int[]{1, 5, 10, 20, 50, 100},
R.string.description_speed_metric,
R.string.description_speed_imperial,
+ R.string.description_speed_nautical,
R.color.chart_speed_fill,
R.color.chart_speed_border,
fontSizeSmall,
@@ -246,6 +248,7 @@ public class ChartView extends View {
new int[]{1, 2, 5, 10, 15, 20, 30, 60, 120},
R.string.description_pace_metric,
R.string.description_pace_imperial,
+ R.string.description_pace_nautical,
R.color.chart_pace_fill,
R.color.chart_pace_border,
fontSizeSmall,
@@ -268,6 +271,7 @@ public class ChartView extends View {
new int[]{25, 50},
R.string.description_sensor_heart_rate,
R.string.description_sensor_heart_rate,
+ R.string.description_sensor_heart_rate,
R.color.chart_heart_rate_fill,
R.color.chart_heart_rate_border,
fontSizeSmall,
@@ -289,6 +293,7 @@ public class ChartView extends View {
new int[]{5, 10, 25, 50},
R.string.description_sensor_cadence,
R.string.description_sensor_cadence,
+ R.string.description_sensor_cadence,
R.color.chart_cadence_fill,
R.color.chart_cadence_border,
fontSizeSmall,
@@ -309,6 +314,7 @@ public class ChartView extends View {
new int[]{5, 50, 100, 200},
R.string.description_sensor_power,
R.string.description_sensor_power,
+ R.string.description_sensor_power,
R.color.chart_power_fill,
R.color.chart_power_border,
fontSizeSmall,
@@ -732,6 +738,8 @@ public class ChartView extends View {
return context.getString(R.string.unit_kilometer);
case IMPERIAL:
return context.getString(R.string.unit_mile);
+ case NAUTICAL_IMPERIAL:
+ return context.getString(R.string.unit_nautical_mile);
default:
throw new RuntimeException("Not implemented");
}
diff --git a/src/main/java/de/dennisguse/opentracks/data/models/Distance.java b/src/main/java/de/dennisguse/opentracks/data/models/Distance.java
index 6f14452fc..bcb80d971 100644
--- a/src/main/java/de/dennisguse/opentracks/data/models/Distance.java
+++ b/src/main/java/de/dennisguse/opentracks/data/models/Distance.java
@@ -29,6 +29,10 @@ public class Distance {
return of(distance_mile * UnitConversions.MI_TO_M);
}
+ public static Distance ofNauticalMile(double distance_mile) {
+ return of(distance_mile * UnitConversions.NAUTICAL_MILE_TO_M);
+ }
+
public static Distance ofKilometer(double distance_km) {
return of(distance_km * UnitConversions.KM_TO_M);
}
@@ -51,6 +55,8 @@ public class Distance {
return Distance.ofKilometer(1);
case IMPERIAL:
return Distance.ofMile(1);
+ case NAUTICAL_IMPERIAL:
+ return Distance.ofNauticalMile(1);
default:
throw new RuntimeException("Not implemented");
}
@@ -114,12 +120,18 @@ public class Distance {
return toKM() * UnitConversions.KM_TO_MI;
}
+ public double toNauticalMiles() {
+ return toKM() * UnitConversions.KM_TO_NAUTICAL_MILE;
+ }
+
public double toKM_Miles(UnitSystem unitSystem) {
switch (unitSystem) {
case METRIC:
return toKM();
case IMPERIAL:
return toMI();
+ case NAUTICAL_IMPERIAL:
+ return toNauticalMiles();
default:
throw new RuntimeException("Not implemented");
}
@@ -129,6 +141,7 @@ public class Distance {
switch (unitSystem) {
case METRIC:
return toM();
+ case NAUTICAL_IMPERIAL:
case IMPERIAL:
return toFT();
default:
diff --git a/src/main/java/de/dennisguse/opentracks/data/models/DistanceFormatter.java b/src/main/java/de/dennisguse/opentracks/data/models/DistanceFormatter.java
index 717858890..b22747619 100644
--- a/src/main/java/de/dennisguse/opentracks/data/models/DistanceFormatter.java
+++ b/src/main/java/de/dennisguse/opentracks/data/models/DistanceFormatter.java
@@ -46,6 +46,7 @@ public class DistanceFormatter {
case METRIC:
return new Pair<>(null, resources.getString(R.string.unit_meter));
case IMPERIAL:
+ case NAUTICAL_IMPERIAL:
return new Pair<>(null, resources.getString(R.string.unit_feet));
default:
throw new RuntimeException("Not implemented");
@@ -65,6 +66,12 @@ public class DistanceFormatter {
} 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))) {
+ 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));
+ }
default:
throw new RuntimeException("Not implemented");
}
diff --git a/src/main/java/de/dennisguse/opentracks/data/models/Speed.java b/src/main/java/de/dennisguse/opentracks/data/models/Speed.java
index f6decb183..0aaf47b80 100644
--- a/src/main/java/de/dennisguse/opentracks/data/models/Speed.java
+++ b/src/main/java/de/dennisguse/opentracks/data/models/Speed.java
@@ -93,6 +93,10 @@ public class Speed {
return toKMH() * UnitConversions.KM_TO_MI;
}
+ public double toKnots() {
+ return toKMH() * UnitConversions.KM_TO_NAUTICAL_MILE;
+ }
+
public Duration toPace(UnitSystem unitSystem) {
if (isZero()) {
return Duration.ofSeconds(0);
@@ -106,6 +110,9 @@ public class Speed {
case IMPERIAL:
distance *= UnitConversions.M_TO_MI;
break;
+ case NAUTICAL_IMPERIAL:
+ distance *= UnitConversions.M_TO_NAUTICAL_MILE;
+ break;
default:
throw new RuntimeException("Not implemented");
}
@@ -119,6 +126,8 @@ public class Speed {
return toKMH();
case IMPERIAL:
return toMPH();
+ case NAUTICAL_IMPERIAL:
+ return toKnots();
default:
throw new RuntimeException("Not implemented");
}
diff --git a/src/main/java/de/dennisguse/opentracks/data/models/SpeedFormatter.java b/src/main/java/de/dennisguse/opentracks/data/models/SpeedFormatter.java
index e33975f11..61b473960 100644
--- a/src/main/java/de/dennisguse/opentracks/data/models/SpeedFormatter.java
+++ b/src/main/java/de/dennisguse/opentracks/data/models/SpeedFormatter.java
@@ -47,6 +47,9 @@ public class SpeedFormatter {
case IMPERIAL:
unitId = reportSpeedOrPace ? R.string.unit_mile_per_hour : R.string.unit_minute_per_mile;
break;
+ case NAUTICAL_IMPERIAL:
+ unitId = reportSpeedOrPace ? R.string.unit_knots : R.string.unit_minute_per_nautical_mile;
+ break;
default:
throw new RuntimeException("Not implemented");
}
diff --git a/src/main/java/de/dennisguse/opentracks/data/models/UnitConversions.java b/src/main/java/de/dennisguse/opentracks/data/models/UnitConversions.java
index c9355fbf7..eee25ea63 100644
--- a/src/main/java/de/dennisguse/opentracks/data/models/UnitConversions.java
+++ b/src/main/java/de/dennisguse/opentracks/data/models/UnitConversions.java
@@ -53,6 +53,9 @@ public class UnitConversions {
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
diff --git a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtils.java b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtils.java
index 861190804..d2a8767ef 100644
--- a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtils.java
+++ b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtils.java
@@ -57,6 +57,13 @@ class VoiceAnnouncementUtils {
unitDistanceTTS = "mile";
unitSpeedTTS = "mile per hour";
break;
+ case NAUTICAL_IMPERIAL:
+ perUnitStringId = R.string.voice_per_nautical_mile;
+ distanceId = R.plurals.voiceDistanceNauticalMiles;
+ speedId = R.plurals.voiceSpeedMKnots;
+ unitDistanceTTS = "nautical mile";
+ unitSpeedTTS = "knots";
+ break;
default:
throw new RuntimeException("Not implemented");
}
diff --git a/src/main/java/de/dennisguse/opentracks/settings/DefaultsSettingsFragment.java b/src/main/java/de/dennisguse/opentracks/settings/DefaultsSettingsFragment.java
index 66208a964..92b37fa69 100644
--- a/src/main/java/de/dennisguse/opentracks/settings/DefaultsSettingsFragment.java
+++ b/src/main/java/de/dennisguse/opentracks/settings/DefaultsSettingsFragment.java
@@ -74,6 +74,7 @@ public class DefaultsSettingsFragment extends PreferenceFragmentCompat implement
entriesId = R.array.stats_rate_metric_options;
break;
case IMPERIAL:
+ case NAUTICAL_IMPERIAL:
entriesId = R.array.stats_rate_imperial_options;
break;
default:
diff --git a/src/main/java/de/dennisguse/opentracks/settings/PreferencesUtils.java b/src/main/java/de/dennisguse/opentracks/settings/PreferencesUtils.java
index 0615259d0..6a102eea1 100644
--- a/src/main/java/de/dennisguse/opentracks/settings/PreferencesUtils.java
+++ b/src/main/java/de/dennisguse/opentracks/settings/PreferencesUtils.java
@@ -214,7 +214,6 @@ public class PreferencesUtils {
//TODO Check if actually needed or can be superseeded by a flexible default in getUnit()
public static void applyDefaultUnit() {
if (getString(R.string.stats_units_key, "").equals("")) {
-
if (!Locale.US.equals(Locale.getDefault())) {
setUnit(UnitSystem.METRIC);
} else {
@@ -324,7 +323,7 @@ public class PreferencesUtils {
UnitSystem unitSystem = getUnitSystem();
DistanceFormatter formatter = DistanceFormatter.Builder()
- .setDecimalCount(0)
+ .setDecimalCount(1)
.setUnit(unitSystem)
.build(resources);
for (int i = 0; i < values.length; i++) {
@@ -418,7 +417,7 @@ public class PreferencesUtils {
DistanceFormatter formatter = DistanceFormatter.Builder()
.setUnit(unitSystem)
- .setDecimalCount(0)
+ .setDecimalCount(1)
.build(resources);
for (int i = 0; i < entryValues.length; i++) {
int value = Integer.parseInt(entryValues[i]);
@@ -434,6 +433,7 @@ public class PreferencesUtils {
}
break;
case IMPERIAL:
+ case NAUTICAL_IMPERIAL:
if (value == recordingDistanceIntervalDefault) {
entries[i] = resources.getString(R.string.value_integer_feet_recommended, (int) distance.toFT());
} else {
@@ -461,7 +461,7 @@ public class PreferencesUtils {
UnitSystem unitSystem = getUnitSystem();
DistanceFormatter formatter = DistanceFormatter.Builder()
- .setDecimalCount(0)
+ .setDecimalCount(1)
.setUnit(unitSystem)
.build(resources);
for (int i = 0; i < entryValues.length; i++) {
@@ -478,6 +478,7 @@ public class PreferencesUtils {
}
break;
case IMPERIAL:
+ case NAUTICAL_IMPERIAL:
if (value == maxRecordingDistanceDefault) {
entries[i] = resources.getString(R.string.value_integer_feet_recommended, (int) distance.toFT());
} else {
@@ -533,7 +534,7 @@ public class PreferencesUtils {
UnitSystem unitSystem = getUnitSystem();
DistanceFormatter formatter = DistanceFormatter.Builder()
- .setDecimalCount(0)
+ .setDecimalCount(1)
.setUnit(unitSystem)
.build(resources);
@@ -555,6 +556,7 @@ public class PreferencesUtils {
}
break;
case IMPERIAL:
+ case NAUTICAL_IMPERIAL:
if (value == recordingGPSAccuracyDefault) {
entries[i] = resources.getString(R.string.value_integer_feet_recommended, (int) distance.toFT());
} else if (value == recordingGPSAccuracyExcellent) {
@@ -606,6 +608,14 @@ public class PreferencesUtils {
entries[i] = resources.getString(R.string.value_float_mile_hour, valueMPH);
}
break;
+ case NAUTICAL_IMPERIAL:
+ double valueKnots = Speed.ofKMH(value).toKnots();
+ if (value == idleSpeedDefault) {
+ entries[i] = resources.getString(R.string.value_float_knots_recommended, valueKnots);
+ } else {
+ entries[i] = resources.getString(R.string.value_float_knots, valueKnots);
+ }
+ break;
default:
throw new RuntimeException("Not implemented");
}
diff --git a/src/main/java/de/dennisguse/opentracks/settings/UnitSystem.java b/src/main/java/de/dennisguse/opentracks/settings/UnitSystem.java
index 1c73de145..2cdeff1e6 100644
--- a/src/main/java/de/dennisguse/opentracks/settings/UnitSystem.java
+++ b/src/main/java/de/dennisguse/opentracks/settings/UnitSystem.java
@@ -4,7 +4,8 @@ import de.dennisguse.opentracks.R;
public enum UnitSystem {
METRIC(R.string.stats_units_metric),
- IMPERIAL(R.string.stats_units_imperial);
+ IMPERIAL(R.string.stats_units_imperial),
+ NAUTICAL_IMPERIAL(R.string.stats_units_nautical); // Nautical miles with feet
private final int preferenceIdentifier;
diff --git a/src/main/res/values/settings.xml b/src/main/res/values/settings.xml
index 2dd63380d..ab2cd1818 100644
--- a/src/main/res/values/settings.xml
+++ b/src/main/res/values/settings.xml
@@ -204,15 +204,20 @@
statsRate
@string/stats_rate_speed_or_pace_default
+
+ - @string/description_default_speed_or_pace
+ - @string/description_speed_metric
+ - @string/description_pace_metric
+
- @string/description_default_speed_or_pace
- @string/description_speed_imperial
- @string/description_pace_imperial
-
+
- @string/description_default_speed_or_pace
- - @string/description_speed_metric
- - @string/description_pace_metric
+ - @string/description_speed_nautical
+ - @string/description_pace_imperial
ACTIVITY_TYPE
@@ -229,12 +234,15 @@
- @string/stats_units_metric
- @string/stats_units_imperial
+ - @string/stats_units_nautical
METRIC
IMPERIAL
+ NAUTICAL
- @string/settings_stats_units_metric
- @string/settings_stats_units_imperial
+ - @string/settings_stats_units_nautical
trackName
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 42a6caa5d..5274ec704 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -187,6 +187,7 @@ limitations under the License.
Min elevation: %1$d m (%2$d ft)
Moving time: %1$s
Pace (min/mi)
+ Pace (min/NM)
Pace (min/km)
Recorded: %1$s
Speed (m/s)
@@ -195,6 +196,7 @@ limitations under the License.
Power (W)
By activity type
Speed (mi/hr)
+ Speed (knots)
Speed (km/hr)
Time
Total distance: %1$.2f km (%2$.1f mi)
@@ -435,6 +437,7 @@ limitations under the License.
Preferred rate
Imperial (mi, ft)
Metric (km, m)
+ Nautical (NM, ft)
Preferred units
@@ -513,8 +516,11 @@ limitations under the License.
m
mi
mph
+ NM
+ kn
min/km
min/mi
+ min/NM
%1$s°
%1$s, %2$s
@@ -529,8 +535,11 @@ limitations under the License.
%1$d m (poor GPS)
%1$d m (recommended)
%1$d mi/h
+ %1$d knots
%1$.1f mi/h
+ %1$.1f knots
%1$.1f mi/h (recommended)
+ %1$.1f knots (recommended)
%1$d min
%1$d s
None
@@ -557,8 +566,13 @@ limitations under the License.
- 1 mile per hour
- %1$.1f miles per hour
+
+ - 1 knot
+ - %1$.1f knots
+
per kilometer
per mile
+ per nautical mile
Lap time
Pace
Lap speed
@@ -572,6 +586,10 @@ limitations under the License.
- 1 mile
- %1$.2f miles
+
+ - 1 nautical mile
+ - %1$.2f nautical miles
+
Average heart rate
Current heart rate