diff --git a/docs/config.md b/docs/config.md
index a3bc757..1bffa19 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -71,6 +71,7 @@ window.owntracks.config = {};
- [`selectedUser`](#selecteduser)
- [`showDistanceTravelled`](#showdistancetravelled)
- [`startDateTime`](#startdatetime)
+- [`units`](#units)
- [`verbose`](#verbose)
### `api.baseUrl`
@@ -565,6 +566,20 @@ Initial start date and time (browser timezone) for fetched data.
};
```
+### `units`
+
+Allows the configuration of the units of measurement to use for the user interface.
+
+Available options:
+
+- `metric`
+- `imperial`
+
+Choosing anything other than one of these options will fall back to metric.
+
+- Type: [`String`]
+- Default: `"metric"`
+
### `verbose`
Whether to enable verbose mode or not.
diff --git a/src/components/LDeviceLocationPopup.vue b/src/components/LDeviceLocationPopup.vue
index cf113fa..2564b5c 100644
--- a/src/components/LDeviceLocationPopup.vue
+++ b/src/components/LDeviceLocationPopup.vue
@@ -26,7 +26,8 @@
{{ lon }}
- {{ alt }}m
+ {{ $config.units == "imperial" ? Math.round(alt * 3.28084) : alt }}
+ {{ $config.units == "imperial" ? " ft" : " m" }}
@@ -38,7 +39,12 @@
- {{ speed }} km/h
+ {{
+ $config.units == "imperial"
+ ? Math.round((speed / 1.609) * 10) / 10
+ : speed
+ }}
+ {{ $config.units == "imperial" ? " mph" : " km/h" }}
diff --git a/src/config.js b/src/config.js
index 38c0e73..aa2e73a 100644
--- a/src/config.js
+++ b/src/config.js
@@ -87,6 +87,7 @@ const DEFAULT_CONFIG = {
selectedUser: null,
showDistanceTravelled: true,
startDateTime,
+ units: "metric",
verbose: false,
};
diff --git a/src/util.js b/src/util.js
index c92af42..65bbf00 100644
--- a/src/util.js
+++ b/src/util.js
@@ -67,20 +67,31 @@ export const distanceBetweenCoordinates = (c1, c2) => {
/**
* Format a distance in meters into a human-readable string with unit.
*
- * This only supports m / km for now, but could read a config option and return
- * ft / mi.
- *
* @param {Number} distance Distance in meters
* @returns {String} Formatted string including unit
*/
export const humanReadableDistance = (distance) => {
let unit = "m";
- if (Math.abs(distance) >= 1000) {
- distance = distance / 1000;
- unit = "km";
+ let digits = 1;
+
+ if (config.units == "imperial") {
+ unit = "ft";
+ digits = 0; // We don't need anything after decimal when working with feet.
+ distance = distance * 3.28084; // convert meters to feet.
+ if (Math.abs(distance) >= 1500) {
+ // Most mapping apps switch to fractions of a mile above 1,500 ft
+ distance = distance / 5280;
+ unit = "mi";
+ digits = 2;
+ }
+ } else {
+ if (Math.abs(distance) >= 1000) {
+ distance = distance / 1000;
+ unit = "km";
+ }
}
return `${distance.toLocaleString(config.locale, {
- maximumFractionDigits: 1,
+ maximumFractionDigits: digits,
})} ${unit}`;
};
diff --git a/tests/util.test.js b/tests/util.test.js
index 09afe2a..d0406a4 100644
--- a/tests/util.test.js
+++ b/tests/util.test.js
@@ -129,5 +129,21 @@ describe("humanReadableDistance", () => {
expect(humanReadableDistance(9999.9999)).toBe("10 km");
expect(humanReadableDistance(100000)).toBe("100 km");
expect(humanReadableDistance(-42)).toBe("-42 m");
+
+ config.units = "imperial";
+ expect(humanReadableDistance(0)).toBe("0 ft");
+ expect(humanReadableDistance(1)).toBe("3 ft");
+ expect(humanReadableDistance(123)).toBe("404 ft");
+ expect(humanReadableDistance(123.4567)).toBe("405 ft");
+ expect(humanReadableDistance(999)).toBe("0.62 mi");
+ expect(humanReadableDistance(1000)).toBe("0.62 mi");
+ expect(humanReadableDistance(9000)).toBe("5.59 mi");
+ expect(humanReadableDistance(9900)).toBe("6.15 mi");
+ expect(humanReadableDistance(9990)).toBe("6.21 mi");
+ expect(humanReadableDistance(9999)).toBe("6.21 mi");
+ expect(humanReadableDistance(9999.0)).toBe("6.21 mi");
+ expect(humanReadableDistance(9999.9999)).toBe("6.21 mi");
+ expect(humanReadableDistance(100000)).toBe("62.14 mi");
+ expect(humanReadableDistance(-42)).toBe("-137.80 ft");
});
});