package cgeo.geocaching.location; import static org.assertj.core.api.Assertions.offset; import static org.assertj.core.api.Java6Assertions.assertThat; import junit.framework.TestCase; public class GeoPointParserTest extends TestCase { private static final double refLongitude = 8.0 + 38.564 / 60.0; private static final double refLatitude = 49.0 + 56.031 / 60.0; public static void testParseLatitude() { assertEquals(refLatitude, GeopointParser.parseLatitude("N 49° 56.031"), 1e-8); } public static void testParseLongitude() { assertEquals(refLongitude, GeopointParser.parseLongitude("E 8° 38.564"), 1e-8); } public static void testFullCoordinates() { final Geopoint goal = new Geopoint(refLatitude, refLongitude); assertGeopointEquals(goal, GeopointParser.parse("N 49° 56.031 | E 8° 38.564"), 1e-6f); } private static void assertGeopointEquals(final Geopoint expected, final Geopoint actual, final float tolerance) { assertThat(expected).isNotNull(); assertThat(actual).isNotNull(); assertThat(expected.distanceTo(actual)).isLessThanOrEqualTo(tolerance); } private static void assertParsingFails(final String geopointToParse) { try { GeopointParser.parse(geopointToParse); fail(); } catch (final Geopoint.ParseException e) { // expected } } public static void testCoordinateMissingPart() { // we are trying to parse a _point_, but have only a latitude. Don't accept the numerical part as longitude! assertParsingFails("N 49° 56.031"); } public static void testCoordinateMissingDegree() { // Some home coordinates on geocaching.com lack the degree part. final Geopoint point = GeopointParser.parse("N 51° 23.123' W ° 17.123"); assertThat(point).isEqualTo(new Geopoint("N", "51", "23", "123", "W", "0", "17", "123")); } public static void testSouth() { assertThat(GeopointParser.parseLatitude("S 49° 56.031")).isEqualTo(-refLatitude, offset(1e-8)); } public static void testWest() { assertThat(GeopointParser.parseLongitude("W 8° 38.564")).isEqualTo(-refLongitude, offset(1e-8)); } public static void testLowerCase() { assertThat(GeopointParser.parseLongitude("e 8° 38.564")).isEqualTo(refLongitude, offset(1e-8)); } public static void testVariousFormats() { final Geopoint goal1 = GeopointParser.parse("N 49° 43' 57\" | E 2 12' 35"); final Geopoint goal2 = GeopointParser.parse("N 49 43.95 E2°12.5833333333"); assertGeopointEquals(goal1, goal2, 1e-6f); } public static void testParseOurOwnSeparator() { final Geopoint separator = GeopointParser.parse("N 49° 43' 57\" · E 2 12' 35"); final Geopoint noSeparator = GeopointParser.parse("N 49 43.95 E2°12.5833333333"); assertGeopointEquals(separator, noSeparator, 1e-6f); } public static void testInSentence() { final Geopoint p1 = GeopointParser.parse("Station3: N51 21.523 / E07 02.680"); final Geopoint p2 = GeopointParser.parse("N51 21.523 E07 02.680"); assertThat(p1).isNotNull(); assertThat(p2).isNotNull(); assertThat(p2).isEqualTo(p1); } public static void testUnrelatedParts() { assertParsingFails("N51 21.523 and some words in between, so there is no relation E07 02.680"); } public static void testComma() { final Geopoint pointComma = GeopointParser.parse("N 46° 27' 55,65''\n" + "E 15° 53' 41,68''"); final Geopoint pointDot = GeopointParser.parse("N 46° 27' 55.65''\n" + "E 15° 53' 41.68''"); assertThat(pointComma).isNotNull(); assertThat(pointDot).isNotNull(); assertThat(pointDot).isEqualTo(pointComma); } public static void testBlankAddedByAutocorrectionDot() { assertThat(GeopointParser.parseLatitude("N 49° 56. 031")).isEqualTo(refLatitude, offset(1e-8)); } public static void testBlankAddedByAutocorrectionComma() { assertThat(GeopointParser.parseLatitude("N 49° 56, 031")).isEqualTo(refLatitude, offset(1e-8)); } public static void testNonTrimmed() { assertThat(GeopointParser.parseLatitude(" N 49° 56, 031 ")).isEqualTo(refLatitude, offset(1e-8)); } public static void testEquatorGC53() { assertThat(GeopointParser.parse("00° 00.000 E 036° 00.000")).isEqualTo(new Geopoint(0, 36)); } public static void testMeridian() { assertThat(GeopointParser.parse("N 23° 00.000 00° 00.000")).isEqualTo(new Geopoint(23, 0)); } public static void testEquatorMeridian() { assertThat(GeopointParser.parse("00° 00.000 00° 00.000")).isEqualTo(Geopoint.ZERO); } public static void testFloatingPointLatitude() { assertThat(GeopointParser.parseLatitude("47.648883")).isEqualTo(GeopointParser.parseLatitude("N 47° 38.933"), offset(1e-6)); } public static void testFloatingPointNegativeLatitudeMeansSouth() { assertThat(GeopointParser.parseLatitude("-47.648883")).isEqualTo(GeopointParser.parseLatitude("S 47° 38.933"), offset(1e-6)); } public static void testFloatingPointBoth() { assertGeopointEquals(GeopointParser.parse("47.648883 122.348067"), GeopointParser.parse("N 47° 38.933 E 122° 20.884"), 1e-4f); assertGeopointEquals(GeopointParser.parse("47.648883 -122.348067"), GeopointParser.parse("N 47° 38.933 W 122° 20.884"), 1e-4f); } public static void testFloatingPointNbsp() { assertGeopointEquals(GeopointParser.parse("47.648883 122.348067\u00a0"), GeopointParser.parse("N 47° 38.933 E 122° 20.884"), 1e-4f); } public static void testDoubleComma() { assertThat(GeopointParser.parse("47.648883,122.348067").equals(GeopointParser.parse("47.648883 122.348067"))); } public static void testGerman() { assertThat(GeopointParser.parse("N 47° 38.933 O 122° 20.884")).isEqualTo(GeopointParser.parse("N 47° 38.933 E 122° 20.884")); } public static void testNoSpace() { assertThat(GeopointParser.parse("N47°38.933E122°20.884")).isEqualTo(GeopointParser.parse("N 47° 38.933 E 122° 20.884")); } public static void testUTM() { GeopointParser.parse("54S E 293848 N 3915114"); } public static void testZero() { GeopointParser.parse("00° 00.000′ 000° 00.00′"); GeopointParser.parse("00° 00′ 00.00″ 000° 00′ 00.00″"); GeopointParser.parse("00° 00′ 000° 00′"); GeopointParser.parse("00° E 000°"); assertParsingFails("00° 00.001′ 000° 00.01′"); assertParsingFails("00° 00′ 00.01″ 000° 00′ 00.01″"); assertParsingFails("00° 01′ 000° 01′"); assertParsingFails("01° E 000°"); } public static void testFormula() { assertParsingFails("N 12° 23.345′ E 123° 34.5AB′"); assertParsingFails("N 12° 23′ E 123° 3A′"); assertParsingFails("N 12° E 12A°"); assertParsingFails("N 12° 23′ 34″ E 123° 34′ 5A″"); assertParsingFails("N 12° 23′ 34.56″ E 123° 34′ 56.7A″"); assertParsingFails("-12.345678° 23.4ABCDE°"); } public static void testInvalidCombinations() { assertParsingFails("N 07° 59.999′ W 059° 42′ 17.12″"); assertParsingFails("S 59° 42′ 17.12″ -0.497234"); assertParsingFails("0.497234 E 007° 59.999′"); } public static void testDMSBounds() { GeopointParser.parse("S 90° 00′ 00.00″ W 180° 00′ 00.00″"); GeopointParser.parse("S 89° 59′ 59.99″ W 179° 59′ 59.99″"); assertParsingFails("S 90° 00′ 00.01″ W 180° 00′ 00.00″"); assertParsingFails("S 90° 00′ 00.00″ W 180° 00′ 00.01″"); assertParsingFails("S 89° 59′ 60.00″ W 179° 59′ 59.99″"); assertParsingFails("S 89° 59′ 59.99″ W 179° 59′ 60.00″"); assertParsingFails("S 89° 60′ 00.00″ W 179° 59′ 59.99″"); assertParsingFails("S 89° 59′ 59.99″ W 179° 60′ 00.00″"); } public static void testMinBounds() { GeopointParser.parse("S 90° 00′ W 180° 00′"); GeopointParser.parse("S 89° 59′ W 179° 59′"); assertParsingFails("S 90° 01′ W 180° 00′"); assertParsingFails("S 90° 00′ W 180° 01′"); assertParsingFails("S 89° 60′ W 180° 00′"); assertParsingFails("S 90° 00′ W 179° 60′"); } public static void testMinDecBounds() { GeopointParser.parse("S 90° 00.000′ W 180° 00.000′"); GeopointParser.parse("S 89° 59.999′ W 179° 59.999′"); assertParsingFails("S 90° 00.001′ W 180° 00.000′"); assertParsingFails("S 90° 00.000′ W 180° 00.001′"); assertParsingFails("S 89° 60.000′ W 180° 00.000′"); assertParsingFails("S 90° 00.000′ W 179° 60.000′"); } public static void testNull() { try { GeopointParser.parseLatitude(null); fail(); } catch (final Geopoint.ParseException e) { // expected } try { GeopointParser.parseLongitude(null); fail(); } catch (final Geopoint.ParseException e) { // expected } } public static void test922() { assertParsingFails("L 12\n M 13\n N 14\n O 15"); } public static void test5538() { assertParsingFails("A=6 B=0 C=5 D=4 E=13\n" + "N 48° 53.(A*C*E)+194 E 009° 11.((D*71)-0)-1\n" + "N 48° 53.(6*5*13)+194 E 009° 11.((4*71)-0)-1\n" + "N 48° 53.(390)+194 E 009° 11.((284)-0)-1"); assertParsingFails("S1: N 49 27.253"); } public static void test5790() { GeopointParser.parse("N 52° 36.123 E 010° 06.456'"); GeopointParser.parse("N52° 36.123 E010°06.456"); GeopointParser.parse("N52 36.123 E010 06.456"); GeopointParser.parse("52° 10°"); GeopointParser.parse("52° -10°"); GeopointParser.parse("52.55123 10,56789"); GeopointParser.parse("52.55123° 10.56789°"); } public static void test6090() { // Issue #6090 final Geopoint ref = new Geopoint(12.576117, -1.390933); final Geopoint gp1 = GeopointParser.parse("N12 34. 567\nW001 23.456"); assertGeopointEquals(gp1, ref, 1e-4f); final Geopoint gp2 = GeopointParser.parse("N12 34.567\nW001 23. 456"); assertGeopointEquals(gp2, ref, 1e-4f); final Geopoint gp3 = GeopointParser.parse("N12 34. 567\nW001 23. 456"); assertGeopointEquals(gp3, ref, 1e-4f); } }