NMEA { static double parseDegreesMinutes(@NonNull String dm, @NonNull String nsew) { if (dm.isEmpty()) { return Double.NaN; } else { final int index = dm.indexOf('.') - 2; if (index < 0) { Exceptions.report(new NMEAException("NMEA lat/lon parse error missing decimal: " + dm + " " + nsew)); return Double.NaN; } else { try { final double m = Double.parseDouble(dm.substring(index)); final int d = (index == 0) ? 0 : Integer.parseInt(dm.substring(0, index)); final double degrees = d + m / 60.0; if (nsew.equalsIgnoreCase("S") || nsew.equalsIgnoreCase("W")) return -degrees; else return degrees; } catch (Exception e) { Exceptions.report(new NMEAException("NMEA lat/lon parse error: " + dm + " " + nsew)); return Double.NaN; } } } }    }
@Test public void parseDegreesMinutes() { assertEquals(123.761315, NMEA.parseDegreesMinutes("12345.6789", "N"), 0.01); assertEquals(-123.761315, NMEA.parseDegreesMinutes("12345.6789", "S"), 0.01); assertEquals(Double.NaN, NMEA.parseDegreesMinutes("", ""), 0.01); assertEquals(Double.NaN, NMEA.parseDegreesMinutes("X", ""), 0.01); assertEquals(Double.NaN, NMEA.parseDegreesMinutes("XX.YY", ""), 0.01); assertEquals(Double.NaN, NMEA.parseDegreesMinutes("12345", ""), 0.01); }