JosmCoordinatesParser { @NonNull public static Result parseWithResult(@NonNull String input) throws IllegalArgumentException { Result result = new Result(); final LatLonHolder latLon = new LatLonHolder(); final Matcher mXml = P_XML.matcher(input); if (mXml.matches()) { setLatLonObj(latLon, Double.valueOf(mXml.group(1).replace(',', '.')), 0.0, 0.0, "N", Double.valueOf(mXml.group(2).replace(',', '.')), 0.0, 0.0, "E"); result.coordinates = new GeoPoint(latLon.lat, latLon.lon); return result; } final Matcher mUtm = P_UTM.matcher(input); if (mUtm.lookingAt()) { result.offset = mUtm.end(); if (mUtm.group(3) != null) { MGRSCoord mgrs = MGRSCoord.fromString(mUtm.group()); result.coordinates = new GeoPoint(mgrs.getLatitude().degrees, mgrs.getLongitude().degrees); return result; } else { int zone = Integer.valueOf(mUtm.group(1)); String hemisphere = mUtm.group(2); double easting, northing; if ("N".equals(hemisphere)) hemisphere = AVKey.NORTH; if ("S".equals(hemisphere)) hemisphere = AVKey.SOUTH; if (mUtm.group(6) != null) { easting = Double.valueOf(mUtm.group(5)); northing = Double.valueOf(mUtm.group(6)); } else { String en = mUtm.group(4); int l = en.length() >> 1; easting = Double.valueOf(en.substring(0, l)); northing = Double.valueOf(en.substring(l, en.length())); } UTMCoord utm = UTMCoord.fromUTM(zone, hemisphere, easting, northing); result.coordinates = new GeoPoint(utm.getLatitude().degrees, utm.getLongitude().degrees); return result; } } final Matcher m = P.matcher(input); final StringBuilder sb = new StringBuilder(); final List<Object> list = new ArrayList<>(); while (m.find()) { if (m.group(1) != null) { sb.append('R'); list.add(Double.valueOf(m.group(1).replace(',', '.'))); result.offset = m.end(); } else if (m.group(2) != null) { sb.append('Z'); list.add(Double.valueOf(m.group(2))); result.offset = m.end(); } else if (m.group(3) != null) { sb.append('o'); result.offset = m.end(); } else if (m.group(4) != null) { sb.append('\''); result.offset = m.end(); } else if (m.group(5) != null) { sb.append('"'); result.offset = m.end(); } else if (m.group(6) != null) { sb.append(','); result.offset = m.end(); } else if (m.group(7) != null) { sb.append('x'); String c = m.group(7).toUpperCase(Locale.ENGLISH); if ("N".equalsIgnoreCase(c) || "S".equalsIgnoreCase(c) || "E".equalsIgnoreCase(c) || "W".equalsIgnoreCase(c)) { list.add(c); } else { list.add(c.replace(N_TR, 'N').replace(S_TR, 'S') .replace(E_TR, 'E').replace(W_TR, 'W')); } result.offset = m.end(); } } final String pattern = sb.toString(); final Object[] params = list.toArray(); if (pattern.matches("Ro?,?Ro?")) { setLatLonObj(latLon, params[0], 0.0, 0.0, "N", params[1], 0.0, 0.0, "E"); } else if (pattern.matches("xRo?,?xRo?")) { setLatLonObj(latLon, params[1], 0.0, 0.0, params[0], params[3], 0.0, 0.0, params[2]); } else if (pattern.matches("Ro?x,?Ro?x")) { setLatLonObj(latLon, params[0], 0.0, 0.0, params[1], params[2], 0.0, 0.0, params[3]); } else if (pattern.matches("Zo[RZ]'?,?Zo[RZ]'?|Z[RZ],?Z[RZ]")) { setLatLonObj(latLon, params[0], params[1], 0.0, "N", params[2], params[3], 0.0, "E"); } else if (pattern.matches("xZo[RZ]'?,?xZo[RZ]'?|xZo?[RZ],?xZo?[RZ]")) { setLatLonObj(latLon, params[1], params[2], 0.0, params[0], params[4], params[5], 0.0, params[3]); } else if (pattern.matches("Zo[RZ]'?x,?Zo[RZ]'?x|Zo?[RZ]x,?Zo?[RZ]x")) { setLatLonObj(latLon, params[0], params[1], 0.0, params[2], params[3], params[4], 0.0, params[5]); } else if (pattern.matches("ZoZ'[RZ]\"?,?ZoZ'[RZ]\"?|ZZ[RZ],?ZZ[RZ]")) { setLatLonObj(latLon, params[0], params[1], params[2], "N", params[3], params[4], params[5], "E"); } else if (pattern.matches("ZoZ'[RZ]\"?x,?ZoZ'[RZ]\"?x|ZZ[RZ]x,?ZZ[RZ]x")) { setLatLonObj(latLon, params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7]); } else if (pattern.matches("xZoZ'[RZ]\"?,?xZoZ'[RZ]\"?|xZZ[RZ],?xZZ[RZ]")) { setLatLonObj(latLon, params[1], params[2], params[3], params[0], params[5], params[6], params[7], params[4]); } else if (pattern.matches("ZZ[RZ],?ZZ[RZ]")) { setLatLonObj(latLon, params[0], params[1], params[2], "N", params[3], params[4], params[5], "E"); } else { throw new IllegalArgumentException("invalid format: " + pattern); } result.coordinates = new GeoPoint(latLon.lat, latLon.lon); return result; } private  JosmCoordinatesParser(); @NonNull static Result parseWithResult(@NonNull String input); @NonNull static GeoPoint parse(@NonNull String input); static final String SOUTH; static final String NORTH; static final String WEST; static final String EAST; }
@Test public void testDescriptionParser() { JosmCoordinatesParser.Result result = JosmCoordinatesParser.parseWithResult("39.095973 -94.573414 Place description"); double testLatitude = 39.095973; double testLongitude = -94.573414; assertEquals("Failed to parse 39.095973 -94.573414 Place description", testLatitude, result.coordinates.getLatitude(), 0.000001); assertEquals("Failed to parse 39.095973 -94.573414 Place description", testLongitude, result.coordinates.getLongitude(), 0.000001); assertEquals("Failed to parse 39.095973 -94.573414 Place description", 20, result.offset); result = JosmCoordinatesParser.parseWithResult("39.095973 N, 94.573414 W Place 34 description"); assertEquals("Failed to parse 39.095973 N, 94.573414 W Place 34 description", testLatitude, result.coordinates.getLatitude(), 0.000001); assertEquals("Failed to parse 39.095973 N, 94.573414 W Place 34 description", testLongitude, result.coordinates.getLongitude(), 0.000001); assertEquals("Failed to parse 39.095973 N, 94.573414 W Place 34 description", 24, result.offset); result = JosmCoordinatesParser.parseWithResult("15N 363936 4328605 Place 34"); assertEquals("Failed to parse 15N 363936 4328605 Place 34", testLatitude, result.coordinates.getLatitude(), 0.000003); assertEquals("Failed to parse 15N 363936 4328605 Place 34", testLongitude, result.coordinates.getLongitude(), 0.000003); assertEquals("Failed to parse 15N 363936 4328605 Place 34", 18, result.offset); result = JosmCoordinatesParser.parseWithResult("39.095973 N, 94.573414 W"); assertEquals("Failed to parse 39.095973 N, 94.573414 W", testLatitude, result.coordinates.getLatitude(), 0.000001); assertEquals("Failed to parse 39.095973 N, 94.573414 W", testLongitude, result.coordinates.getLongitude(), 0.000001); assertEquals("Failed to parse 39.095973 N, 94.573414 W", 24, result.offset); }