aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--main/src/cgeo/geocaching/geopoint/HumanDistance.java64
-rw-r--r--tests/src/cgeo/geocaching/geopoint/HumanDistanceTest.java37
2 files changed, 64 insertions, 37 deletions
diff --git a/main/src/cgeo/geocaching/geopoint/HumanDistance.java b/main/src/cgeo/geocaching/geopoint/HumanDistance.java
index 3c40555..25d1bb7 100644
--- a/main/src/cgeo/geocaching/geopoint/HumanDistance.java
+++ b/main/src/cgeo/geocaching/geopoint/HumanDistance.java
@@ -2,44 +2,48 @@ package cgeo.geocaching.geopoint;
import cgeo.geocaching.Settings;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+
public class HumanDistance {
- public static String getHumanDistance(final Float distanceKilometers) {
- if (distanceKilometers == null) {
- return "?";
- }
+ public static ImmutablePair<Double, String> scaleUnit(final double distanceKilometers) {
+ double distance;
+ String units;
if (Settings.isUseMetricUnits()) {
- if (distanceKilometers > 100) {
- return String.format("%d", Math.round(distanceKilometers)) + " km";
- } else if (distanceKilometers > 10) {
- return String.format("%.1f", Double.valueOf(Math.round(distanceKilometers * 10.0) / 10.0)) + " km";
- } else if (distanceKilometers > 1) {
- return String.format("%.2f", Double.valueOf(Math.round(distanceKilometers * 100.0) / 100.0)) + " km";
- } else if (distanceKilometers > 0.1) {
- return String.format("%d", Math.round(distanceKilometers * 1000.0)) + " m";
- } else if (distanceKilometers > 0.01) {
- return String.format("%.1f", Double.valueOf(Math.round(distanceKilometers * 1000.0 * 10.0) / 10.0)) + " m";
+ if (distanceKilometers >= 1) {
+ distance = distanceKilometers;
+ units = "km";
} else {
- return String.format("%.2f", Double.valueOf(Math.round(distanceKilometers * 1000.0 * 100.0) / 100.0)) + " m";
+ distance = distanceKilometers * 1000;
+ units = "m";
}
} else {
- final float miles = distanceKilometers / IConversion.MILES_TO_KILOMETER;
- if (miles > 100) {
- return String.format("%d", Math.round(miles)) + " mi";
- } else if (miles > 0.5) {
- return String.format("%.1f", Double.valueOf(Math.round(miles * 10.0) / 10.0)) + " mi";
- } else if (miles > 0.1) {
- return String.format("%.2f", Double.valueOf(Math.round(miles * 100.0) / 100.0)) + " mi";
- }
-
- final float feet = miles * 5280;
- if (feet >= 100) {
- return String.format("%d", Math.round(feet)) + " ft";
- } else if (feet >= 10) {
- return String.format("%.1f", Double.valueOf(Math.round(feet * 10.0) / 10.0)) + " ft";
+ distance = distanceKilometers / IConversion.MILES_TO_KILOMETER;
+ if (distance >= 0.1) {
+ units = "mi";
} else {
- return String.format("%.2f", Double.valueOf(Math.round(feet * 100.0) / 100.0)) + " ft";
+ distance *= 5280;
+ units = "ft";
}
}
+ return new ImmutablePair<Double, String>(distance, units);
+ }
+
+ public static String getHumanDistance(final Float distanceKilometers) {
+ if (distanceKilometers == null) {
+ return "?";
+ }
+
+ final ImmutablePair<Double, String> scaled = scaleUnit(distanceKilometers);
+ String formatString;
+ if (scaled.left >= 100) {
+ formatString = "%.0f";
+ } else if (scaled.left >= 10) {
+ formatString = "%.1f";
+ } else {
+ formatString = "%.2f";
+ }
+
+ return String.format(formatString + " %s", scaled.left, scaled.right);
}
}
diff --git a/tests/src/cgeo/geocaching/geopoint/HumanDistanceTest.java b/tests/src/cgeo/geocaching/geopoint/HumanDistanceTest.java
index 3c7cb98..0532495 100644
--- a/tests/src/cgeo/geocaching/geopoint/HumanDistanceTest.java
+++ b/tests/src/cgeo/geocaching/geopoint/HumanDistanceTest.java
@@ -4,16 +4,39 @@ import cgeo.geocaching.Settings;
import android.test.AndroidTestCase;
+import java.util.regex.Pattern;
+
public class HumanDistanceTest extends AndroidTestCase {
- public static void testHumanDistance() {
- assertEquals("?", HumanDistance.getHumanDistance(null));
- if (Settings.isUseMetricUnits()) {
- assertEquals("123 km", HumanDistance.getHumanDistance(123.456f));
- assertEquals("123 m", HumanDistance.getHumanDistance(0.123456f));
+ private static void assertMatch(final String ok, final float distance) {
+ final String humanDistance = HumanDistance.getHumanDistance(distance);
+ if (!Pattern.compile('^' + ok + '$').matcher(humanDistance).find()) {
+ fail("getHumanDistance(" + distance +
+ ") [metric: " + (Settings.isUseMetricUnits() ? "yes" : "no") +
+ "] fails to match " + ok + ": " + humanDistance);
}
- else {
- assertEquals("77 mi", HumanDistance.getHumanDistance(123.456f));
+ }
+
+ // Make method non-static so that Settings is initialized
+ @SuppressWarnings("static-method")
+ public void testHumanDistance() {
+ assertEquals("?", HumanDistance.getHumanDistance(null));
+ final boolean savedMetrics = Settings.isUseMetricUnits();
+ try {
+ Settings.setUseMetricUnits(true);
+ assertMatch("123 km", 122.782f);
+ assertMatch("123 km", 123.456f);
+ assertMatch("12.3 km", 12.3456f);
+ assertMatch("1.23 km", 1.23456f);
+ assertMatch("123 m", 0.123456f);
+ Settings.setUseMetricUnits(false);
+ assertMatch("76.7 mi", 123.456f);
+ assertMatch("7.67 mi", 12.3456f);
+ assertMatch("0.77 mi", 1.23456f);
+ assertMatch("405 ft", 0.123456f);
+ assertMatch("40.5 ft", 0.0123456f);
+ } finally {
+ Settings.setUseMetricUnits(savedMetrics);
}
}
}