]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - tim/prune/data/Coordinate.java
Version 17.2, February 2015
[GpsPrune.git] / tim / prune / data / Coordinate.java
index 40853ebc62505983b132abb71c85afcc041bc115..e30fa4ac357d89a68041fa07eee2f76bf5e8ee22 100644 (file)
@@ -32,6 +32,11 @@ public abstract class Coordinate
        static {
                if (EIGHT_DP instanceof DecimalFormat) ((DecimalFormat) EIGHT_DP).applyPattern("0.00000000");
        }
+       /** Number formatter for fixed decimals with forced decimal point */
+       private static final NumberFormat FIVE_DP = NumberFormat.getNumberInstance(Locale.UK);
+       static {
+               if (FIVE_DP instanceof DecimalFormat) ((DecimalFormat) FIVE_DP).applyPattern("0.00000");
+       }
 
        // Instance variables
        private boolean _valid = false;
@@ -79,7 +84,7 @@ public abstract class Coordinate
 
                        // count numeric fields - 1=d, 2=dm, 3=dm.m/dms, 4=dms.s
                        int numFields = 0;
-                       boolean inNumeric = false;
+                       boolean isNumeric = false;
                        char currChar;
                        long[] fields = new long[4]; // needs to be long for lengthy decimals
                        long[] denoms = new long[4];
@@ -92,9 +97,9 @@ public abstract class Coordinate
                                        currChar = inString.charAt(i);
                                        if (currChar >= '0' && currChar <= '9')
                                        {
-                                               if (!inNumeric)
+                                               if (!isNumeric)
                                                {
-                                                       inNumeric = true;
+                                                       isNumeric = true;
                                                        numFields++;
                                                        denoms[numFields-1] = 1;
                                                }
@@ -106,7 +111,7 @@ public abstract class Coordinate
                                        }
                                        else
                                        {
-                                               inNumeric = false;
+                                               isNumeric = false;
                                                // Remember delimiters
                                                if (currChar != ',' && currChar != '.') {otherDelims[numFields] = true;}
                                        }
@@ -121,7 +126,7 @@ public abstract class Coordinate
                        // parse fields according to number found
                        _degrees = (int) fields[0];
                        _asDouble = _degrees;
-                       _originalFormat = hasCardinal?FORMAT_DEG:FORMAT_DEG_WITHOUT_CARDINAL;
+                       _originalFormat = hasCardinal ? FORMAT_DEG : FORMAT_DEG_WITHOUT_CARDINAL;
                        _fracDenom = 10;
                        if (numFields == 2)
                        {
@@ -145,6 +150,19 @@ public abstract class Coordinate
                                        _asDouble = 1.0 * _degrees + (_minutes / 60.0);
                                }
                        }
+                       // Check for exponential degrees like 1.3E-6
+                       else if (numFields == 3 && !otherDelims[1] && otherDelims[2] && isJustNumber(inString))
+                       {
+                               _originalFormat = FORMAT_DEG;
+                               _asDouble = Math.abs(Double.parseDouble(inString)); // must succeed if isJustNumber has given true
+                               // now we can ignore the fields and just use this double
+                               _degrees = (int) _asDouble;
+                               double numMins = (_asDouble - _degrees) * 60.0;
+                               _minutes = (int) numMins;
+                               double numSecs = (numMins - _minutes) * 60.0;
+                               _seconds = (int) numSecs;
+                               _fracs = (int) ((numSecs - _seconds) * 10);
+                       }
                        // Differentiate between d-m.f and d-m-s using . or ,
                        else if (numFields == 3 && !otherDelims[2])
                        {
@@ -170,7 +188,8 @@ public abstract class Coordinate
                        if (_cardinal == WEST || _cardinal == SOUTH || inString.charAt(0) == '-')
                                _asDouble = -_asDouble;
                        // validate fields
-                       _valid = _valid && (_degrees <= getMaxDegrees() && _minutes < 60 && _seconds < 60 && _fracs < _fracDenom);
+                       _valid = _valid && (_degrees <= getMaxDegrees() && _minutes < 60 && _seconds < 60 && _fracs < _fracDenom)
+                               && Math.abs(_asDouble) <= getMaxDegrees();
                }
                else _valid = false;
        }
@@ -178,10 +197,10 @@ public abstract class Coordinate
 
        /**
         * Get the cardinal from the given character
-        * @param inFirstChar first character from file
-        * @param inLastChar last character from file
+        * @param inFirstChar first character from string
+        * @param inLastChar last character from string
         */
-       protected int getCardinal(char inFirstChar, char inLastChar)
+       private int getCardinal(char inFirstChar, char inLastChar)
        {
                // Try leading character first
                int cardinal = getCardinal(inFirstChar);
@@ -298,7 +317,7 @@ public abstract class Coordinate
                                case FORMAT_DEG_MIN:
                                {
                                        answer = "" + PRINTABLE_CARDINALS[_cardinal] + threeDigitString(_degrees) + "\u00B0"
-                                               + (_minutes + _seconds / 60.0 + _fracs / 60.0 / _fracDenom) + "'";
+                                               + FIVE_DP.format((Math.abs(_asDouble) - _degrees) * 60.0) + "'";
                                        break;
                                }
                                case FORMAT_DEG_WHOLE_MIN:
@@ -314,8 +333,11 @@ public abstract class Coordinate
                                case FORMAT_DEG:
                                case FORMAT_DEG_WITHOUT_CARDINAL:
                                {
-                                       answer = (_asDouble<0.0?"-":"")
-                                               + (_degrees + _minutes / 60.0 + _seconds / 3600.0 + _fracs / 3600.0 / _fracDenom);
+                                       if (_originalFormat != FORMAT_DEG_WITHOUT_CARDINAL)
+                                       {
+                                               answer = (_asDouble<0.0?"-":"")
+                                                       + (_degrees + _minutes / 60.0 + _seconds / 3600.0 + _fracs / 3600.0 / _fracDenom);
+                                       }
                                        break;
                                }
                                case FORMAT_DECIMAL_FORCE_POINT:
@@ -415,7 +437,7 @@ public abstract class Coordinate
                double startValue = inStart.getDouble();
                double endValue = inEnd.getDouble();
                double newValue = startValue + (endValue - startValue) * inFraction;
-               Coordinate answer = inStart.makeNew(newValue, inStart._originalFormat);
+               Coordinate answer = inStart.makeNew(newValue, Coordinate.FORMAT_DECIMAL_FORCE_POINT);
                return answer;
        }