diff options
| author | Bananeweizen <Bananeweizen@gmx.de> | 2011-09-12 07:47:59 -0700 |
|---|---|---|
| committer | Bananeweizen <Bananeweizen@gmx.de> | 2011-09-12 07:47:59 -0700 |
| commit | 0f41bea8b7358263bde23d5f4b0e62ba8671960e (patch) | |
| tree | c39c42daf1a0f4f41953963c70a4fd048dde9f42 /src | |
| parent | be0d0fde44d594fbef6a4cd27cb184ba7db86ffb (diff) | |
| parent | b3f1702e4e7e57e52402be69c10a84e5caa85f82 (diff) | |
| download | cgeo-0f41bea8b7358263bde23d5f4b0e62ba8671960e.zip cgeo-0f41bea8b7358263bde23d5f4b0e62ba8671960e.tar.gz cgeo-0f41bea8b7358263bde23d5f4b0e62ba8671960e.tar.bz2 | |
Merge pull request #405 from samueltardieu/distance-parser
Factor distance parser into its own class and static method
Diffstat (limited to 'src')
| -rw-r--r-- | src/cgeo/geocaching/cgBase.java | 34 | ||||
| -rw-r--r-- | src/cgeo/geocaching/cgeopoint.java | 44 | ||||
| -rw-r--r-- | src/cgeo/geocaching/cgeowaypointadd.java | 44 | ||||
| -rw-r--r-- | src/cgeo/geocaching/geopoint/DistanceParser.java | 47 | ||||
| -rw-r--r-- | src/cgeo/geocaching/geopoint/Geopoint.java | 1 | ||||
| -rw-r--r-- | src/cgeo/geocaching/mapcommon/cgOverlayScale.java | 2 |
6 files changed, 70 insertions, 102 deletions
diff --git a/src/cgeo/geocaching/cgBase.java b/src/cgeo/geocaching/cgBase.java index 775b267..72743b9 100644 --- a/src/cgeo/geocaching/cgBase.java +++ b/src/cgeo/geocaching/cgBase.java @@ -71,6 +71,7 @@ import android.util.Log; import android.widget.EditText; import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.files.LocParser; +import cgeo.geocaching.geopoint.DistanceParser; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.utils.CollectionUtils; @@ -172,7 +173,9 @@ public class cgBase { private static final Pattern patternViewstateFieldCount = Pattern.compile("id=\"__VIEWSTATEFIELDCOUNT\"[^(value)]+value=\"(\\d+)\"[^>]+>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); private static final Pattern patternViewstates = Pattern.compile("id=\"__VIEWSTATE(\\d*)\"[^(value)]+value=\"([^\"]+)\"[^>]+>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); private static final Pattern patternIsPremium = Pattern.compile("<span id=\"ctl00_litPMLevel\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); - public static final double kmInMiles = 1 / 1.609344; + public static final double miles2km = 1.609344; + public static final double feet2km = 0.0003048; + public static final double yards2km = 0.0009144; public static final double deg2rad = Math.PI / 180; public static final double rad2deg = 180 / Math.PI; public static final float erad = 6371.0f; @@ -2172,7 +2175,12 @@ public class cgBase { try { final Matcher matcherDistance = PATTERN_TRACKABLE_Distance.matcher(page); if (matcherDistance.find() && matcherDistance.groupCount() > 0) { - trackable.distance = parseDistance(matcherDistance.group(1)); + try { + trackable.distance = DistanceParser.parseDistance(matcherDistance.group(1), settings.units); + } catch (NumberFormatException e) { + trackable.distance = null; + throw e; + } } } catch (Exception e) { // failed to parse trackable distance @@ -2407,24 +2415,6 @@ public class cgBase { return text.trim(); } - public static Double parseDistance(String dst) { - Double distance = null; - - final Pattern pattern = Pattern.compile("([0-9\\.,]+)[ ]*(km|mi)", Pattern.CASE_INSENSITIVE); - final Matcher matcher = pattern.matcher(dst); - while (matcher.find()) { - if (matcher.groupCount() > 1) { - if (matcher.group(2).equalsIgnoreCase("km")) { - distance = Double.valueOf(matcher.group(1)); - } else { - distance = Double.valueOf(matcher.group(1)) / kmInMiles; - } - } - } - - return distance; - } - public static double getDistance(final Geopoint coords1, final Geopoint coords2) { if (coords1 == null || coords2 == null) { return 0; @@ -2455,7 +2445,7 @@ public class cgBase { } if (settings.units == cgSettings.unitsImperial) { - distance *= kmInMiles; + distance /= miles2km; if (distance > 100) { return String.format(Locale.getDefault(), "%.0f", Double.valueOf(Math.round(distance))) + " mi"; } else if (distance > 0.5) { @@ -2491,7 +2481,7 @@ public class cgBase { String unit = "km/h"; if (this.settings.units == cgSettings.unitsImperial) { - kph *= kmInMiles; + kph /= miles2km; unit = "mph"; } diff --git a/src/cgeo/geocaching/cgeopoint.java b/src/cgeo/geocaching/cgeopoint.java index 240636e..bb817b5 100644 --- a/src/cgeo/geocaching/cgeopoint.java +++ b/src/cgeo/geocaching/cgeopoint.java @@ -2,8 +2,6 @@ package cgeo.geocaching; import java.util.List; import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; @@ -32,6 +30,7 @@ import android.widget.ListView; import android.widget.TextView; import cgeo.geocaching.activity.AbstractActivity; import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; +import cgeo.geocaching.geopoint.DistanceParser; import cgeo.geocaching.geopoint.Geopoint; public class cgeopoint extends AbstractActivity { @@ -519,43 +518,10 @@ public class cgeopoint extends AbstractActivity { return null; } - Double distance = null; // km - - final Pattern patternA = Pattern.compile("^([0-9\\.\\,]+)[ ]*m$", Pattern.CASE_INSENSITIVE); // m - final Pattern patternB = Pattern.compile("^([0-9\\.\\,]+)[ ]*km$", Pattern.CASE_INSENSITIVE); // km - final Pattern patternC = Pattern.compile("^([0-9\\.\\,]+)[ ]*ft$", Pattern.CASE_INSENSITIVE); // ft - 0.3048m - final Pattern patternD = Pattern.compile("^([0-9\\.\\,]+)[ ]*yd$", Pattern.CASE_INSENSITIVE); // yd - 0.9144m - final Pattern patternE = Pattern.compile("^([0-9\\.\\,]+)[ ]*mi$", Pattern.CASE_INSENSITIVE); // mi - 1609.344m - - Matcher matcherA = patternA.matcher(distanceText); - Matcher matcherB = patternB.matcher(distanceText); - Matcher matcherC = patternC.matcher(distanceText); - Matcher matcherD = patternD.matcher(distanceText); - Matcher matcherE = patternE.matcher(distanceText); - - if (matcherA.find() && matcherA.groupCount() > 0) { - distance = (new Double(matcherA.group(1))) * 0.001; - } else if (matcherB.find() && matcherB.groupCount() > 0) { - distance = new Double(matcherB.group(1)); - } else if (matcherC.find() && matcherC.groupCount() > 0) { - distance = (new Double(matcherC.group(1))) * 0.0003048; - } else if (matcherD.find() && matcherD.groupCount() > 0) { - distance = (new Double(matcherD.group(1))) * 0.0009144; - } else if (matcherE.find() && matcherE.groupCount() > 0) { - distance = (new Double(matcherE.group(1))) * 1.609344; - } else { - try { - if (settings.units == cgSettings.unitsImperial) { - distance = (new Double(distanceText)) * 0.0003048; // considering it feet - } else { - distance = (new Double(distanceText)) * 0.001; // considering it meters - } - } catch (Exception e) { - // probably not a number - } - } - - if (distance == null) { + double distance; + try { + distance = DistanceParser.parseDistance(distanceText, settings.units); + } catch (NumberFormatException e) { showToast(res.getString(R.string.err_parse_dist)); return null; } diff --git a/src/cgeo/geocaching/cgeowaypointadd.java b/src/cgeo/geocaching/cgeowaypointadd.java index 9cac3a5..eefe2fd 100644 --- a/src/cgeo/geocaching/cgeowaypointadd.java +++ b/src/cgeo/geocaching/cgeowaypointadd.java @@ -3,8 +3,6 @@ package cgeo.geocaching; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; @@ -21,6 +19,7 @@ import android.widget.Button; import android.widget.EditText; import cgeo.geocaching.activity.AbstractActivity; import cgeo.geocaching.activity.ActivityMixin; +import cgeo.geocaching.geopoint.DistanceParser; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.GeopointFormatter; @@ -298,43 +297,10 @@ public class cgeowaypointadd extends AbstractActivity { return; } - Double distance = null; // km - - final Pattern patternA = Pattern.compile("^([0-9\\.\\,]+)[ ]*m$", Pattern.CASE_INSENSITIVE); // m - final Pattern patternB = Pattern.compile("^([0-9\\.\\,]+)[ ]*km$", Pattern.CASE_INSENSITIVE); // km - final Pattern patternC = Pattern.compile("^([0-9\\.\\,]+)[ ]*ft$", Pattern.CASE_INSENSITIVE); // ft - 0.3048m - final Pattern patternD = Pattern.compile("^([0-9\\.\\,]+)[ ]*yd$", Pattern.CASE_INSENSITIVE); // yd - 0.9144m - final Pattern patternE = Pattern.compile("^([0-9\\.\\,]+)[ ]*mi$", Pattern.CASE_INSENSITIVE); // mi - 1609.344m - - Matcher matcherA = patternA.matcher(distanceText); - Matcher matcherB = patternB.matcher(distanceText); - Matcher matcherC = patternC.matcher(distanceText); - Matcher matcherD = patternD.matcher(distanceText); - Matcher matcherE = patternE.matcher(distanceText); - - if (matcherA.find() && matcherA.groupCount() > 0) { - distance = (new Double(matcherA.group(1))) * 0.001; - } else if (matcherB.find() && matcherB.groupCount() > 0) { - distance = new Double(matcherB.group(1)); - } else if (matcherC.find() && matcherC.groupCount() > 0) { - distance = (new Double(matcherC.group(1))) * 0.0003048; - } else if (matcherD.find() && matcherD.groupCount() > 0) { - distance = (new Double(matcherD.group(1))) * 0.0009144; - } else if (matcherE.find() && matcherE.groupCount() > 0) { - distance = (new Double(matcherE.group(1))) * 1.609344; - } else { - try { - if (settings.units == cgSettings.unitsImperial) { - distance = (new Double(distanceText)) * 1.609344; // considering it miles - } else { - distance = (new Double(distanceText)) * 0.001; // considering it meters - } - } catch (Exception e) { - // probably not a number - } - } - - if (distance == null) { + double distance; + try { + distance = DistanceParser.parseDistance(distanceText, settings.units); + } catch (NumberFormatException e) { showToast(res.getString(R.string.err_parse_dist)); return; } diff --git a/src/cgeo/geocaching/geopoint/DistanceParser.java b/src/cgeo/geocaching/geopoint/DistanceParser.java new file mode 100644 index 0000000..3578902 --- /dev/null +++ b/src/cgeo/geocaching/geopoint/DistanceParser.java @@ -0,0 +1,47 @@ +package cgeo.geocaching.geopoint; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import cgeo.geocaching.cgBase; +import cgeo.geocaching.cgSettings; + +public final class DistanceParser { + + private static final Pattern pattern = Pattern.compile("^([0-9\\.\\,]+)[ ]*(m|km|ft|yd|mi|)?$", Pattern.CASE_INSENSITIVE); + + /** + * Parse a distance string composed by a number and an optional suffix + * (such as "1.2km"). + * + * @param distanceText the string to analyze + * @return the distance in kilometers + * + * @throws NumberFormatException if the given number is invalid + */ + public static double parseDistance(String distanceText, final int defaultUnit) { + final Matcher matcher = pattern.matcher(distanceText); + + if (!matcher.find()) { + throw new NumberFormatException(distanceText); + } + + final double value = Double.parseDouble(matcher.group(1)); + final String unit = matcher.group(2).toLowerCase(); + + if (unit.equals("m") || (unit.length() == 0 && defaultUnit == cgSettings.unitsMetric)) { + return value / 1000; + } + if (unit.equals("km")) { + return value; + } + if (unit.equals("yd")) { + return value * cgBase.yards2km; + } + if (unit.equals("mi")) { + return value * cgBase.miles2km; + } + return value * cgBase.feet2km; + } + +} diff --git a/src/cgeo/geocaching/geopoint/Geopoint.java b/src/cgeo/geocaching/geopoint/Geopoint.java index 4cea883..8f3d521 100644 --- a/src/cgeo/geocaching/geopoint/Geopoint.java +++ b/src/cgeo/geocaching/geopoint/Geopoint.java @@ -7,7 +7,6 @@ import android.location.Location; */ public final class Geopoint { - public static final double kmInMiles = 1 / 1.609344; public static final double deg2rad = Math.PI / 180; public static final double rad2deg = 180 / Math.PI; public static final float erad = 6371.0f; diff --git a/src/cgeo/geocaching/mapcommon/cgOverlayScale.java b/src/cgeo/geocaching/mapcommon/cgOverlayScale.java index fcd5bf5..e4db67c 100644 --- a/src/cgeo/geocaching/mapcommon/cgOverlayScale.java +++ b/src/cgeo/geocaching/mapcommon/cgOverlayScale.java @@ -64,7 +64,7 @@ public class cgOverlayScale implements OverlayBase { distanceRound = 0d; if(settings.units == cgSettings.unitsImperial) { - distance *= cgBase.kmInMiles; + distance /= cgBase.miles2km; if (distance > 100) { // 100+ mi > 1xx mi distanceRound = Math.floor(distance / 100) * 100; |
