From 9d4a6dd4ac5e894e513df24b998ce2e382f3eec6 Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Wed, 2 May 2018 11:59:22 +0200 Subject: [PATCH 1/7] Cleans up code after running strict inspections in IDEA --- README.md | 4 ++ pom.xml | 10 ++--- src/main/java/com/mapcode/Alphabet.java | 13 ------ src/main/java/com/mapcode/Boundary.java | 2 +- src/main/java/com/mapcode/CheckArgs.java | 3 +- src/main/java/com/mapcode/Common.java | 5 ++- src/main/java/com/mapcode/Data.java | 3 +- src/main/java/com/mapcode/DataModel.java | 3 +- src/main/java/com/mapcode/Decoder.java | 37 +++++++++++------ src/main/java/com/mapcode/Encoder.java | 11 ++--- src/main/java/com/mapcode/Mapcode.java | 2 +- src/main/java/com/mapcode/MapcodeCodec.java | 15 ++++--- src/main/java/com/mapcode/Point.java | 3 +- src/main/java/com/mapcode/Rectangle.java | 2 - src/main/java/com/mapcode/Territory.java | 11 +++-- .../com/mapcode/UnknownMapcodeException.java | 1 + src/test/java/com/mapcode/AlphabetTest.java | 13 +++++- src/test/java/com/mapcode/CheckArgsTest.java | 19 +++++---- src/test/java/com/mapcode/DataModelTest.java | 1 + src/test/java/com/mapcode/DecoderTest.java | 2 +- .../java/com/mapcode/EncodeDecodeTest.java | 18 ++++---- src/test/java/com/mapcode/EncoderTest.java | 2 +- src/test/java/com/mapcode/PointTest.java | 10 ++--- .../java/com/mapcode/ReferenceFileTest.java | 30 +++++++------- src/test/java/com/mapcode/TerritoryTest.java | 41 ++++++++++--------- 25 files changed, 142 insertions(+), 119 deletions(-) diff --git a/README.md b/README.md index aab7942..c30b8d1 100644 --- a/README.md +++ b/README.md @@ -461,6 +461,10 @@ Normally, one of our developers should be able to comment on them and fix. These are the release notes for the Java library for mapcodes. +### 2.4.6 + +* General cleanup after running stricter IntelliJ inspections profile. + ### 2.4.5 * Remove hard reference to `log4j` for production. Left only for unit tests. diff --git a/pom.xml b/pom.xml index 37ddbbb..7d65789 100644 --- a/pom.xml +++ b/pom.xml @@ -73,18 +73,18 @@ 4.3.0 - 0.7.9 + 0.8.1 3.7.0 - 2.10.4 + 3.0.0 1.6 2.9 - 3.6 + 3.7.1 3.0.1 - 2.20.1 + 2.21.0 1.6.8 - 2.8.2 + 2.8.4 3.0.2 4.12 1.2.17 diff --git a/src/main/java/com/mapcode/Alphabet.java b/src/main/java/com/mapcode/Alphabet.java index cfd18fb..777398e 100644 --- a/src/main/java/com/mapcode/Alphabet.java +++ b/src/main/java/com/mapcode/Alphabet.java @@ -101,17 +101,4 @@ public static Alphabet fromString(@Nonnull final String alphaCode) throws Unknow throw new UnknownAlphabetException(trimmed); } } - - /** - * Static consistency check of internal data structures. - */ - static { - int i = 0; - for (final Alphabet alphabet : Alphabet.values()) { - if (Alphabet.values()[i].number != i) { - throw new ExceptionInInitializerError("Incorrect alphabet number: " + alphabet + ".number should be " + i); - } - ++i; - } - } } diff --git a/src/main/java/com/mapcode/Boundary.java b/src/main/java/com/mapcode/Boundary.java index 6fa3ab8..4663d59 100644 --- a/src/main/java/com/mapcode/Boundary.java +++ b/src/main/java/com/mapcode/Boundary.java @@ -25,7 +25,7 @@ * * This class handles territory rectangles for mapcodes. */ -class Boundary { +final class Boundary { private int latMicroDegMin; // Minimum latitude (in microdegrees). Inclusive. private int lonMicroDegMin; // Minimum longitude (in microdegrees). Inclusive. private int latMicroDegMax; // Minimum latitude (in microdegrees). Exclusive. diff --git a/src/main/java/com/mapcode/CheckArgs.java b/src/main/java/com/mapcode/CheckArgs.java index 5bd9f6d..5d28768 100644 --- a/src/main/java/com/mapcode/CheckArgs.java +++ b/src/main/java/com/mapcode/CheckArgs.java @@ -28,8 +28,7 @@ * * This class provides a number of helper methods to check (runtime) arguments. */ -@SuppressWarnings("OverlyBroadThrowsClause") -class CheckArgs { +final class CheckArgs { private CheckArgs() { // Prevent instantiation. diff --git a/src/main/java/com/mapcode/Common.java b/src/main/java/com/mapcode/Common.java index 270f6a5..c9ac629 100644 --- a/src/main/java/com/mapcode/Common.java +++ b/src/main/java/com/mapcode/Common.java @@ -26,7 +26,8 @@ * * This class contains common data structures and methods used by the Mapcode implementation. */ -class Common { +@SuppressWarnings("MagicNumber") +final class Common { private static final Logger LOG = LoggerFactory.getLogger(Common.class); // TODO: Need better name and explanation. @@ -76,7 +77,6 @@ private Common() { // Some of the methods (and tests) take considerably longer with assertions checking, so it's useful // to have this information in the log file. - //noinspection UnusedAssignment boolean debug = false; //noinspection AssertWithSideEffects assert debug = true; @@ -90,6 +90,7 @@ private Common() { // This method returns a divider for longitude (multiplied by 4), for a given latitude. // TODO: Need better names for minY and maxY. + @SuppressWarnings("ConstantConditions") static int xDivider(final int latMin, final int latMax) { assert latMin < latMax; if (latMin >= 0) { diff --git a/src/main/java/com/mapcode/Data.java b/src/main/java/com/mapcode/Data.java index b389b0f..209924e 100644 --- a/src/main/java/com/mapcode/Data.java +++ b/src/main/java/com/mapcode/Data.java @@ -25,7 +25,8 @@ * * This class the data class for Mapcode codex items. */ -class Data { +@SuppressWarnings("MagicNumber") +final class Data { // TODO: Need explanation what this is and how this is used. static final char[] ENCODE_CHARS = { diff --git a/src/main/java/com/mapcode/DataModel.java b/src/main/java/com/mapcode/DataModel.java index 14ec522..00f674f 100644 --- a/src/main/java/com/mapcode/DataModel.java +++ b/src/main/java/com/mapcode/DataModel.java @@ -31,6 +31,7 @@ * * This class contains the module that reads the Mapcode areas into memory and processes them. */ +@SuppressWarnings("MagicNumber") class DataModel { private static final Logger LOG = LoggerFactory.getLogger(DataModel.class); @@ -81,7 +82,6 @@ private static int readLongLoHi(final int lo, final int mid1, final int mid2, fi private final int[] index; private final int[] data; - @SuppressWarnings("StaticNonFinalField") private static volatile DataModel instance = null; private static final Object mutex = new Object(); @@ -97,6 +97,7 @@ public static DataModel getInstance() { return instance; } + @SuppressWarnings("NestedTryStatement") DataModel(@Nonnull final String fileName) throws IncorrectDataModelException { // Read data only once in static initializer. LOG.info("DataModel: reading regions from file: {}", fileName); diff --git a/src/main/java/com/mapcode/Decoder.java b/src/main/java/com/mapcode/Decoder.java index 96efff0..f86089a 100644 --- a/src/main/java/com/mapcode/Decoder.java +++ b/src/main/java/com/mapcode/Decoder.java @@ -30,7 +30,8 @@ * * This class contains decoder for mapcodes. */ -class Decoder { +@SuppressWarnings({"MagicNumber", "StringConcatenationMissingWhitespace"}) +final class Decoder { private static final Logger LOG = LoggerFactory.getLogger(Decoder.class); // Get direct access to the data model singleton. @@ -225,12 +226,12 @@ static MapcodeZone decodeToMapcodeZone(@Nonnull final String argMapcode, private static class Unicode2Ascii { - public final char min; - public final char max; + final char min; + final char max; @Nonnull - public final String convert; + final String convert; - public Unicode2Ascii(final char min, final char max, @Nonnull final String convert) { + Unicode2Ascii(final char min, final char max, @Nonnull final String convert) { this.min = min; this.max = max; this.convert = convert; @@ -243,7 +244,8 @@ public Unicode2Ascii(final char min, final char max, @Nonnull final String conve // Special character '?' indicating missing character in alphabet. private static final char MISSCODE = '?'; - private final static char[][] ASCII2LANGUAGE = { + // @formatter:off + @SuppressWarnings("LongLine") private final static char[][] ASCII2LANGUAGE = { // Character: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 /* Roman */ {'\u0041', '\u0042', '\u0043', '\u0044', '\u0045', '\u0046', '\u0047', '\u0048', '\u0049', '\u004a', '\u004b', '\u004c', '\u004d', '\u004e', '\u004f', '\u0050', '\u0051', '\u0052', '\u0053', '\u0054', '\u0055', '\u0056', '\u0057', '\u0058', '\u0059', '\u005a', '\u0030', '\u0031', '\u0032', '\u0033', '\u0034', '\u0035', '\u0036', '\u0037', '\u0038', '\u0039'}, // Roman /* Greek */ {'\u0391', '\u0392', '\u039e', '\u0394', '\u0388', '\u0395', '\u0393', '\u0397', '\u0399', '\u03a0', '\u039a', '\u039b', '\u039c', '\u039d', '\u039f', '\u03a1', '\u0398', '\u03a8', '\u03a3', '\u03a4', '\u0389', '\u03a6', '\u03a9', '\u03a7', '\u03a5', '\u0396', '\u0030', '\u0031', '\u0032', '\u0033', '\u0034', '\u0035', '\u0036', '\u0037', '\u0038', '\u0039'}, // Greek @@ -274,8 +276,10 @@ public Unicode2Ascii(final char min, final char max, @Nonnull final String conve /* Kannada */ {'\u0C92', '\u0C95', '\u0C96', '\u0C97', '\u0C8E', '\u0C99', '\u0C9A', '\u0C9B', '\u0C85', '\u0C9C', '\u0CA0', '\u0CA1', '\u0CA3', '\u0CA4', '\u0C89', '\u0CA6', '\u0CA7', '\u0CA8', '\u0CAA', '\u0CAB', '\u0C87', '\u0CAC', '\u0CAD', '\u0CB0', '\u0CB2', '\u0CB5', '\u0030', '\u0031', '\u0032', '\u0033', '\u0034', '\u0035', '\u0036', '\u0037', '\u0038', '\u0039'}, // Kannada /* Gujarati */ {'\u0AB3', '\u0A97', '\u0A9C', '\u0AA1', '\u0A87', '\u0AA6', '\u0AAC', '\u0A95', '\u0A8F', '\u0A9A', '\u0A9F', '\u0AA4', '\u0AAA', '\u0AA0', '\u0A8D', '\u0AB0', '\u0AB5', '\u0A9E', '\u0AAE', '\u0AAB', '\u0A89', '\u0AB7', '\u0AA8', '\u0A9D', '\u0AA2', '\u0AAD', '\u0030', '\u0031', '\u0032', '\u0033', '\u0034', '\u0035', '\u0036', '\u0037', '\u0038', '\u0039'} // Gujarati }; + // @formatter:on - private final static Unicode2Ascii[] UNICODE2ASCII = { + // @formatter:off + @SuppressWarnings("LongLine") private final static Unicode2Ascii[] UNICODE2ASCII = { /* Roman */ new Unicode2Ascii('\u0041', '\u005a', "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), // Roman /* Greek */ new Unicode2Ascii('\u0388', '\u03a9', "EU???????ABGDFZHQIKLMNCOJP?STYVXRW"), // Greek /* Cyrillic */ new Unicode2Ascii('\u0410', '\u042f', "AZBGDEFNI?KLMHOJPCTYQXSVW????U?R"), // Cyrillic @@ -322,6 +326,7 @@ public Unicode2Ascii(final char min, final char max, @Nonnull final String conve /* Georgian */ new Unicode2Ascii('\u10d0', '\u10ef', "AB?CE?D?UF?GHOJ?KLMINPQRSTVW?XYZ"), /* Armenian */ new Unicode2Ascii('\u0562', '\u0586', "BCDE??FGHI?J?KLM?N?U?PQ?R??STVWXYZ?OA") }; + // @formatter:on @Nonnull private static MapcodeZone decodeGrid( @@ -981,19 +986,25 @@ private static String convertFromAbjad(@Nonnull final String mapcode) { } else if (form == 35) { final int c = ((DECODE_CHARS[(int) s.charAt(2)] * 8) + (DECODE_CHARS[(int) s.charAt(6)] - 18)); if ((c >= 32) && (c < 63)) { - newstr = s.substring(0, 2) + Data.ENCODE_CHARS[c - 32] + s.charAt(4) + '.' + s.charAt(5) + s.charAt(7) + s.charAt(8); + newstr = s.substring(0, 2) + Data.ENCODE_CHARS[c - 32] + s.charAt(4) + '.' + s.charAt(5) + s.charAt(7) + + s.charAt(8); } else if ((c >= 0) && (c < 31)) { - newstr = s.substring(0, 2) + Data.ENCODE_CHARS[c] + '.' + s.charAt(4) + s.charAt(5) + s.charAt(7) + s.charAt(8); + newstr = s.substring(0, 2) + Data.ENCODE_CHARS[c] + '.' + s.charAt(4) + s.charAt(5) + s.charAt(7) + + s.charAt(8); } } else if (form == 45) { - final int c = (DECODE_CHARS[(int) s.charAt(2)] * 100) + (DECODE_CHARS[(int) s.charAt(5)] * 10) + (DECODE_CHARS[(int) s.charAt(8)] - 39); + final int c = (DECODE_CHARS[(int) s.charAt(2)] * 100) + (DECODE_CHARS[(int) s.charAt(5)] * 10) + + (DECODE_CHARS[(int) s.charAt(8)] - 39); if ((c >= 0) && (c < 961)) { - newstr = s.substring(0, 2) + Data.ENCODE_CHARS[c / 31] + s.charAt(3) + '.' + s.charAt(6) + s.charAt(7) + s.charAt(9) + Data.ENCODE_CHARS[c % 31]; + newstr = s.substring(0, 2) + Data.ENCODE_CHARS[c / 31] + s.charAt(3) + '.' + s.charAt(6) + s.charAt(7) + + s.charAt(9) + Data.ENCODE_CHARS[c % 31]; } } else if (form == 55) { - final int c = (DECODE_CHARS[(int) s.charAt(2)] * 100) + (DECODE_CHARS[(int) s.charAt(6)] * 10) + (DECODE_CHARS[(int) s.charAt(9)] - 39); + final int c = (DECODE_CHARS[(int) s.charAt(2)] * 100) + (DECODE_CHARS[(int) s.charAt(6)] * 10) + + (DECODE_CHARS[(int) s.charAt(9)] - 39); if ((c >= 0) && (c < 961)) { - newstr = s.substring(0, 2) + Data.ENCODE_CHARS[c / 31] + s.charAt(3) + s.charAt(4) + '.' + s.charAt(7) + s.charAt(8) + s.charAt(10) + Data.ENCODE_CHARS[c % 31]; + newstr = s.substring(0, 2) + Data.ENCODE_CHARS[c / 31] + s.charAt(3) + s.charAt(4) + '.' + s.charAt(7) + + s.charAt(8) + s.charAt(10) + Data.ENCODE_CHARS[c % 31]; } } diff --git a/src/main/java/com/mapcode/Encoder.java b/src/main/java/com/mapcode/Encoder.java index 8e9638a..38083e3 100644 --- a/src/main/java/com/mapcode/Encoder.java +++ b/src/main/java/com/mapcode/Encoder.java @@ -34,7 +34,8 @@ * * This class contains encoder for mapcodes. */ -class Encoder { +@SuppressWarnings({"MagicNumber", "StringConcatenationMissingWhitespace"}) +final class Encoder { private static final Logger LOG = LoggerFactory.getLogger(Encoder.class); // Get direct access to data model singleton. @@ -130,16 +131,16 @@ private static List encode( final Mapcode newResult = new Mapcode(mapcode, encodeTerritory); // The result should not be stored yet. - if (!results.contains(newResult)) { + if (results.contains(newResult)) { + LOG.error("encode: Duplicate results found, newResult={}, results={} items", + newResult.getCodeWithTerritory(), results.size()); + } else { // Remove existing results (if there was a parent territory). if (limitToOneResult) { results.clear(); } results.add(newResult); - } else { - LOG.error("encode: Duplicate results found, newResult={}, results={} items", - newResult.getCodeWithTerritory(), results.size()); } lastBaseSubTerritoryNumber = lastSubTerritoryRecord; diff --git a/src/main/java/com/mapcode/Mapcode.java b/src/main/java/com/mapcode/Mapcode.java index f7ef818..e0e4c96 100644 --- a/src/main/java/com/mapcode/Mapcode.java +++ b/src/main/java/com/mapcode/Mapcode.java @@ -422,7 +422,7 @@ public boolean equals(@Nullable final Object obj) { return false; } final Mapcode that = (Mapcode) obj; - return this.territory.equals(that.territory) && + return (this.territory == that.territory) && this.codePrecision8.equals(that.codePrecision8); } } diff --git a/src/main/java/com/mapcode/MapcodeCodec.java b/src/main/java/com/mapcode/MapcodeCodec.java index 385d8ed..5dd8bc4 100644 --- a/src/main/java/com/mapcode/MapcodeCodec.java +++ b/src/main/java/com/mapcode/MapcodeCodec.java @@ -32,6 +32,7 @@ * * This class is the external Java interface for encoding and decoding mapcodes. */ +@SuppressWarnings("MagicNumber") public final class MapcodeCodec { // Get direct access to the data model. @@ -194,7 +195,6 @@ public static Mapcode encodeToInternational(@Nonnull final Point point) * @throws UnknownPrecisionFormatException Thrown if the precision format is incorrect. * @throws IllegalArgumentException Thrown if arguments are null, or if the syntax of the mapcode is incorrect. */ - @SuppressWarnings("DuplicateThrows") @Nonnull public static Point decode(@Nonnull final String mapcode) throws UnknownMapcodeException, IllegalArgumentException, UnknownPrecisionFormatException { @@ -217,7 +217,6 @@ public static Point decode(@Nonnull final String mapcode) * @throws UnknownPrecisionFormatException Thrown if the precision format is incorrect. * @throws IllegalArgumentException Thrown if arguments are null, or if the syntax of the mapcode is incorrect. */ - @SuppressWarnings("DuplicateThrows") @Nonnull public static Point decode(@Nonnull final String mapcode, @Nullable final Territory defaultTerritoryContext) throws UnknownMapcodeException, IllegalArgumentException, UnknownPrecisionFormatException { @@ -315,18 +314,14 @@ public static boolean isNearMultipleBorders(@Nonnull final Point point, @Nonnull @Nonnull private static MapcodeZone decodeToMapcodeZone(@Nonnull final String mapcode, @Nullable final Territory defaultTerritoryContext) - throws UnknownMapcodeException, IllegalArgumentException, UnknownPrecisionFormatException { + throws UnknownMapcodeException, IllegalArgumentException { checkNonnull("mapcode", mapcode); String mapcodeClean = Mapcode.convertStringToPlainAscii(mapcode.trim()).toUpperCase(); // Determine territory from mapcode. final Territory territory; final Matcher matcherTerritory = Mapcode.PATTERN_TERRITORY.matcher(mapcodeClean); - if (!matcherTerritory.find()) { - - // No territory code was supplied in the string, use specified territory context parameter. - territory = (defaultTerritoryContext != null) ? defaultTerritoryContext : Territory.AAA; - } else { + if (matcherTerritory.find()) { // Use the territory code from the string. final String territoryName = mapcodeClean.substring(matcherTerritory.start(), matcherTerritory.end()).trim(); @@ -338,6 +333,10 @@ private static MapcodeZone decodeToMapcodeZone(@Nonnull final String mapcode, @N // Cut off the territory part. mapcodeClean = mapcodeClean.substring(matcherTerritory.end()).trim(); + } else { + + // No territory code was supplied in the string, use specified territory context parameter. + territory = (defaultTerritoryContext != null) ? defaultTerritoryContext : Territory.AAA; } // Throws an exception if the format is incorrect. diff --git a/src/main/java/com/mapcode/Point.java b/src/main/java/com/mapcode/Point.java index 2d6e408..b789fe5 100644 --- a/src/main/java/com/mapcode/Point.java +++ b/src/main/java/com/mapcode/Point.java @@ -32,7 +32,8 @@ * It represent the fractions in pairs of integers, the first integer * representing 1/1,000,000th of degrees, the second representing the remainder. */ -public class Point { +@SuppressWarnings("MagicNumber") +public final class Point { // Latitude and longitude ranges. public static final double LON_DEG_MIN = -180.0; diff --git a/src/main/java/com/mapcode/Rectangle.java b/src/main/java/com/mapcode/Rectangle.java index 426a89a..ccb71a7 100644 --- a/src/main/java/com/mapcode/Rectangle.java +++ b/src/main/java/com/mapcode/Rectangle.java @@ -63,13 +63,11 @@ public String toString() { return "[" + southWest + ", " + northEast + ']'; } - @SuppressWarnings("NonFinalFieldReferencedInHashCode") @Override public int hashCode() { return Arrays.hashCode(new Object[]{southWest, northEast}); } - @SuppressWarnings("NonFinalFieldReferenceInEquals") @Override public boolean equals(final Object obj) { if (this == obj) { diff --git a/src/main/java/com/mapcode/Territory.java b/src/main/java/com/mapcode/Territory.java index a39042d..be7af23 100644 --- a/src/main/java/com/mapcode/Territory.java +++ b/src/main/java/com/mapcode/Territory.java @@ -569,7 +569,6 @@ public enum Territory { CPT(530, "Clipperton Island"), AAA(532, "International", null, null, null, new String[]{"Worldwide", "Earth"}); - @SuppressWarnings("PublicStaticCollectionField") @Nonnull public static final Set PARENT_TERRITORIES = Collections.unmodifiableSet( EnumSet.of(USA, IND, CAN, AUS, MEX, BRA, RUS, CHN, ATA)); @@ -795,25 +794,25 @@ public boolean hasSubdivisions() { /** * Private constructors to create a territory code. */ - private Territory(final int number, + Territory(final int number, @Nonnull final String fullName) { this(number, fullName, null, null, null, null); } - private Territory(final int number, + Territory(final int number, @Nonnull final String fullName, @Nullable final Alphabet[] alphabets) { this(number, fullName, alphabets, null, null, null); } - private Territory(final int number, + Territory(final int number, @Nonnull final String fullName, @Nullable final Alphabet[] alphabets, @Nullable final Territory parentTerritory) { this(number, fullName, alphabets, parentTerritory, null, null); } - private Territory(final int number, + Territory(final int number, @Nonnull final String fullName, @Nullable final Alphabet[] alphabets, @Nullable final Territory parentTerritory, @@ -821,7 +820,7 @@ private Territory(final int number, this(number, fullName, alphabets, parentTerritory, aliases, null); } - private Territory(final int number, + Territory(final int number, @Nonnull final String fullName, @Nullable final Alphabet[] alphabets, @Nullable final Territory parentTerritory, diff --git a/src/main/java/com/mapcode/UnknownMapcodeException.java b/src/main/java/com/mapcode/UnknownMapcodeException.java index 792cd48..ad39916 100644 --- a/src/main/java/com/mapcode/UnknownMapcodeException.java +++ b/src/main/java/com/mapcode/UnknownMapcodeException.java @@ -24,6 +24,7 @@ * Note that for syntactically incorrect mapcodes, normally {@link IllegalArgumentException}s are thrown, * not {@link UnknownMapcodeException}. */ +@SuppressWarnings("CheckedExceptionClass") public final class UnknownMapcodeException extends Exception { private static final long serialVersionUID = 1L; diff --git a/src/test/java/com/mapcode/AlphabetTest.java b/src/test/java/com/mapcode/AlphabetTest.java index 728c020..65e7eb4 100644 --- a/src/test/java/com/mapcode/AlphabetTest.java +++ b/src/test/java/com/mapcode/AlphabetTest.java @@ -77,6 +77,15 @@ public class AlphabetTest { "" }; + @Test + public void testOrderOfValues() { + int i = 0; + for (final Alphabet alphabet : Alphabet.values()) { + assertEquals("Incorrect alphabet number: " + alphabet + ".number should be " + i, i, Alphabet.values()[i].getNumber()); + ++i; + } + } + @Test public void testConvertToAlphabet() throws Exception { @@ -105,7 +114,7 @@ public void testConvertToAlphabet() throws Exception { } @Test - public void testFromString() throws Exception { + public void testFromString() { LOG.info("testFromString"); assertEquals(Alphabet.ROMAN, Alphabet.fromString("ROMAN")); assertEquals(Alphabet.ROMAN, Alphabet.fromString("roman")); @@ -116,7 +125,7 @@ public void testFromString() throws Exception { } @Test(expected = UnknownAlphabetException.class) - public void testFromStringNumeric() throws Exception { + public void testFromStringNumeric() { LOG.info("testFromStringNumeric"); assertEquals(Alphabet.ROMAN, Alphabet.fromString("0")); } diff --git a/src/test/java/com/mapcode/CheckArgsTest.java b/src/test/java/com/mapcode/CheckArgsTest.java index 8169eb3..8d105be 100644 --- a/src/test/java/com/mapcode/CheckArgsTest.java +++ b/src/test/java/com/mapcode/CheckArgsTest.java @@ -20,39 +20,44 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@SuppressWarnings({"OverlyBroadThrowsClause", "ProhibitedExceptionDeclared"}) public class CheckArgsTest { private static final Logger LOG = LoggerFactory.getLogger(CheckArgsTest.class); - public void testCheckNonnullOK() throws Exception { + @SuppressWarnings("JUnitTestMethodWithNoAssertions") + @Test + public void testCheckNonnullOK() { LOG.info("testCheckNonnullOK"); CheckArgs.checkNonnull("test", this); } @Test(expected = IllegalArgumentException.class) - public void testCheckNonnullError() throws Exception { + public void testCheckNonnullError() { LOG.info("testCheckNonnullError"); CheckArgs.checkNonnull("test", null); } - public void testCheckDefinedOK() throws Exception { + @SuppressWarnings("JUnitTestMethodWithNoAssertions") + @Test + public void testCheckDefinedOK() { LOG.info("testCheckDefinedOK"); CheckArgs.checkDefined("test", Point.fromDeg(0.0, 0.0)); } @Test(expected = IllegalArgumentException.class) - public void testCheckDefinedError() throws Exception { + public void testCheckDefinedError() { LOG.info("testCheckDefinedError"); CheckArgs.checkDefined("test", Point.undefined()); } - public void testMapcodeCodeOK() throws Exception { + @SuppressWarnings("JUnitTestMethodWithNoAssertions") + @Test + public void testMapcodeCodeOK() { LOG.info("testCheckMapcodeCodeOK"); CheckArgs.checkMapcodeCode("test", "XX.XX"); } @Test(expected = IllegalArgumentException.class) - public void testMapcodeCodeError() throws Exception { + public void testMapcodeCodeError() { LOG.info("testCheckMapcodeCodeError"); CheckArgs.checkMapcodeCode("test", "XX.XX-"); } diff --git a/src/test/java/com/mapcode/DataModelTest.java b/src/test/java/com/mapcode/DataModelTest.java index 5df8def..16d37e2 100644 --- a/src/test/java/com/mapcode/DataModelTest.java +++ b/src/test/java/com/mapcode/DataModelTest.java @@ -24,6 +24,7 @@ public class DataModelTest { private static final Logger LOG = LoggerFactory.getLogger(DataModelTest.class); + @Test public void testFileOK() { LOG.info("testFileOK"); final DataModel dataModel = new DataModel("/com/mapcode/mminfo_ok.dat"); diff --git a/src/test/java/com/mapcode/DecoderTest.java b/src/test/java/com/mapcode/DecoderTest.java index e8ad7d8..06e002b 100644 --- a/src/test/java/com/mapcode/DecoderTest.java +++ b/src/test/java/com/mapcode/DecoderTest.java @@ -22,7 +22,7 @@ import static org.junit.Assert.assertEquals; -@SuppressWarnings({"OverlyBroadThrowsClause", "ProhibitedExceptionDeclared"}) +@SuppressWarnings({"OverlyBroadThrowsClause", "ProhibitedExceptionDeclared", "MagicNumber"}) public class DecoderTest { private static final Logger LOG = LoggerFactory.getLogger(DecoderTest.class); diff --git a/src/test/java/com/mapcode/EncodeDecodeTest.java b/src/test/java/com/mapcode/EncodeDecodeTest.java index 273d546..c1ed663 100644 --- a/src/test/java/com/mapcode/EncodeDecodeTest.java +++ b/src/test/java/com/mapcode/EncodeDecodeTest.java @@ -16,6 +16,7 @@ package com.mapcode; +import org.junit.Assert; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,10 +28,9 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import static junit.framework.TestCase.assertFalse; import static org.junit.Assert.assertEquals; -@SuppressWarnings({"OverlyBroadThrowsClause", "ProhibitedExceptionDeclared"}) +@SuppressWarnings({"OverlyBroadThrowsClause", "ProhibitedExceptionDeclared", "MagicNumber"}) public class EncodeDecodeTest { private static final Logger LOG = LoggerFactory.getLogger(EncodeDecodeTest.class); @@ -75,7 +75,7 @@ private static void doEncodeDecode(final long seed) throws InterruptedException // Check encodeToShortest and encodeToInternational. final List resultsAll = MapcodeCodec.encode(latDeg, lonDeg); - assertFalse(resultsAll.isEmpty()); + Assert.assertFalse(resultsAll.isEmpty()); assertEquals("encodeToInternational failed, result=" + resultsAll, resultsAll.get(resultsAll.size() - 1), mapcodeInternational); @@ -103,7 +103,7 @@ public void run() { try { decodeLocation = MapcodeCodec.decode(codePrecision, territory); } catch (final UnknownMapcodeException e) { - LOG.error("FAILED {} Decode({} {}) generated from ({}, {}) in {}", count, territory, codePrecision, latDeg, lonDeg); + LOG.error("FAILED {} Decode({} {}) generated from ({}, {})", count, codePrecision, territory, latDeg, lonDeg); LOG.error("encodeDecodeTest: Unknown mapcode exception", e); errors.getAndIncrement(); continue; @@ -111,7 +111,8 @@ public void run() { final double distance = Point.distanceInMeters(encode, decodeLocation); if (distance >= Mapcode.getSafeMaxOffsetInMeters(nrDigits)) { - LOG.error("encodeDecodeTest: " + mapcode + " digits = " + nrDigits + " distance = " + distance + " >= " + Mapcode.getSafeMaxOffsetInMeters(nrDigits)); + LOG.error("encodeDecodeTest: {} digits = {} distance = {} >= {}", mapcode, nrDigits, distance, + Mapcode.getSafeMaxOffsetInMeters(nrDigits)); errors.getAndIncrement(); } else { // check that decode can be encoded back to original @@ -138,7 +139,8 @@ public void run() { } if (!found) { if (!MapcodeCodec.isNearMultipleBorders(decodeLocation, territory)) { // but should be found! - LOG.error("Re-encode{} of {} failed for {} {} from ({},{})", nrDigits, decodeLocation, territory, codePrecision, latDeg, lonDeg); + LOG.error("Re-encode{} of {} failed for {} {} from ({},{})", nrDigits, decodeLocation, territory, + codePrecision, latDeg, lonDeg); errors.getAndIncrement(); for (final Mapcode candidate : recodedMapcodes) { LOG.info(" * candidate: {}", candidate.getCode(nrDigits)); @@ -155,8 +157,8 @@ public void run() { final String mapcodeAlphabet = mapcode.getCode(alphabet); final String mapcodeAscii = Mapcode.convertStringToPlainAscii(mapcodeAlphabet); if (!mapcode.getCode(0).equals(mapcodeAscii)) { - LOG.error("encodeDecodeTest: " + mapcode + " alphabet=" + alphabet + ", original=" + mapcode.getCode(0) + - ", mapcodeAlphabet=" + mapcodeAlphabet + ", mapcodeAscii=" + mapcodeAscii); + LOG.error("encodeDecodeTest: {} alphabet={}, original={}, mapcodeAlphabet={}, mapcodeAscii={}", + mapcode, alphabet, mapcode.getCode(0), mapcodeAlphabet, mapcodeAscii); errors.incrementAndGet(); } } diff --git a/src/test/java/com/mapcode/EncoderTest.java b/src/test/java/com/mapcode/EncoderTest.java index 2b8d5a2..85ab629 100644 --- a/src/test/java/com/mapcode/EncoderTest.java +++ b/src/test/java/com/mapcode/EncoderTest.java @@ -25,7 +25,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -@SuppressWarnings({"OverlyBroadThrowsClause", "ProhibitedExceptionDeclared", "ValueOfIncrementOrDecrementUsed"}) +@SuppressWarnings({"OverlyBroadThrowsClause", "ProhibitedExceptionDeclared", "ValueOfIncrementOrDecrementUsed", "MagicNumber"}) public class EncoderTest { private static final Logger LOG = LoggerFactory.getLogger(EncoderTest.class); diff --git a/src/test/java/com/mapcode/PointTest.java b/src/test/java/com/mapcode/PointTest.java index bcfda6e..b5e1ef5 100644 --- a/src/test/java/com/mapcode/PointTest.java +++ b/src/test/java/com/mapcode/PointTest.java @@ -20,9 +20,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; +@SuppressWarnings("MagicNumber") public class PointTest { private static final Logger LOG = LoggerFactory.getLogger(PointTest.class); private static final double DELTA = 0.000001; @@ -31,14 +31,14 @@ public class PointTest { public void invalidPoint() { LOG.info("invalidPoint"); final Point point = Point.undefined(); - assertEquals("Undefined point", false, point.isDefined()); + assertFalse("Undefined point", point.isDefined()); } @Test public void validPoint() { LOG.info("validPoint"); final Point point = Point.fromMicroDeg(2, 1); - assertEquals("Valid point", true, point.isDefined()); + assertTrue("Valid point", point.isDefined()); assertEquals(0, Point.fromDeg(0, 0).getLatMicroDeg()); assertEquals(0, Point.fromDeg(0, 0).getLonMicroDeg()); @@ -55,7 +55,7 @@ public void invalidatedPoint() { LOG.info("invalidatedPoint"); final Point point = Point.fromMicroDeg(2, 1); point.setUndefined(); - assertEquals("Cleared point", false, point.isDefined()); + assertFalse("Cleared point", point.isDefined()); } @Test diff --git a/src/test/java/com/mapcode/ReferenceFileTest.java b/src/test/java/com/mapcode/ReferenceFileTest.java index b98a7b5..0596b2f 100644 --- a/src/test/java/com/mapcode/ReferenceFileTest.java +++ b/src/test/java/com/mapcode/ReferenceFileTest.java @@ -18,6 +18,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import org.junit.Assert; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,12 +32,12 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; +import java.util.regex.Pattern; -import static junit.framework.TestCase.assertFalse; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -@SuppressWarnings({"ProhibitedExceptionDeclared", "OverlyBroadThrowsClause"}) +@SuppressWarnings({"ProhibitedExceptionDeclared", "OverlyBroadThrowsClause", "MagicNumber"}) public class ReferenceFileTest { private static final Logger LOG = LoggerFactory.getLogger(ReferenceFileTest.class); private static final Gson GSON = new GsonBuilder().serializeSpecialFloatingPointValues().create(); @@ -52,6 +53,7 @@ public class ReferenceFileTest { private static final int PRECISION_MAX = 8; private static final int LOG_LINE_EVERY = 10000; + private static final Pattern PATTERN_SPACE = Pattern.compile(" "); @Test public void checkRandomReferenceRecords() throws Exception { @@ -104,6 +106,7 @@ private static void checkFile( // Open data file. final ChunkedFile chunkedFile = new ChunkedFile(baseFileName); + //noinspection CatchMayIgnoreException try { //noinspection InfiniteLoopStatement @@ -137,7 +140,7 @@ public void run() { reference.point.getLatDeg(), reference.point.getLonDeg()); final Mapcode expectedInternational = results.get(results.size() - 1); if (!resultInternational.equals(expectedInternational)) { - LOG.error("checkFile: encodeToInternational fails, expected={}, got={} for reference", + LOG.error("checkFile: encodeToInternational fails, expected={}, got={}, reference={}", expectedInternational, resultInternational, reference); errors.incrementAndGet(); } @@ -169,7 +172,7 @@ public void run() { for (final MapcodeRec referenceMapcodeRec : reference.mapcodes) { // Check if the territory corresponds. - if (referenceMapcodeRec.territory.equals(result.getTerritory())) { + if (referenceMapcodeRec.territory == result.getTerritory()) { // Check if the mapcode corresponds; use only the specified precision. final int indexOfDash = referenceMapcodeRec.mapcode.lastIndexOf('-'); @@ -212,7 +215,7 @@ public void run() { for (final Mapcode result : results) { // Check if the territory corresponds. - if (referenceMapcodeRec.territory.equals(result.getTerritory())) { + if (referenceMapcodeRec.territory == result.getTerritory()) { // Check if the mapcode corresponds; use only the specified precision. if (referenceMapcode.equals(result.getCode(precision))) { @@ -303,7 +306,7 @@ private static class MapcodeRec { @Nonnull private final Territory territory; - public MapcodeRec(@Nonnull final String mapcode, @Nonnull final Territory territory) { + MapcodeRec(@Nonnull final String mapcode, @Nonnull final Territory territory) { this.mapcode = mapcode; this.territory = territory; } @@ -315,7 +318,7 @@ private static class ReferenceRec { @Nonnull private final ArrayList mapcodes; - public ReferenceRec(@Nonnull final Point point, @Nonnull final ArrayList mapcodes) { + ReferenceRec(@Nonnull final Point point, @Nonnull final ArrayList mapcodes) { this.point = point; this.mapcodes = mapcodes; } @@ -327,7 +330,7 @@ private static ReferenceRec getNextReferenceRecord(@Nonnull final ChunkedFile ch // Read first line of data file: final String firstLine = chunkedFile.readNonEmptyLine(); - final String[] args = firstLine.split(" "); + final String[] args = PATTERN_SPACE.split(firstLine); assertTrue("Expecting 3 or 6 elements, not " + args.length + " in line: " + firstLine, (args.length == 3) || (args.length == 6)); @@ -345,9 +348,9 @@ private static ReferenceRec getNextReferenceRecord(@Nonnull final ChunkedFile ch final ArrayList mapcodeRecs = new ArrayList(); for (int i = 0; i < count; ++i) { final String line = chunkedFile.readNonEmptyLine(); - assertFalse("Line should not be empty", line.isEmpty()); + Assert.assertFalse("Line should not be empty", line.isEmpty()); - final String[] mapcodeLine = line.split(" "); + final String[] mapcodeLine = PATTERN_SPACE.split(line); assertTrue("Expecting 1 or 2 elements, territory and mapcode, got: " + mapcodeLine.length + ", " + line, mapcodeLine.length <= 2); @@ -373,7 +376,7 @@ private static ReferenceRec getNextReferenceRecord(@Nonnull final ChunkedFile ch * like '.a', '.b', etc. This class provides reading lines from such files and moving * to next chunks when needed. */ - private static class ChunkedFile { + private static final class ChunkedFile { final private String baseFileName; private String fileName; private char fileExt; @@ -390,11 +393,10 @@ private ChunkedFile(final String baseFileName) throws IOException { LOG.info("ChunkedFile: Reading {}...", fileName); this.bufferedReader = new BufferedReader(new InputStreamReader(this.inputStream)); } else { - throw new IOException(); + throw new IOException("getResourceAsStream() returned null"); } } - @SuppressWarnings("OverlyBroadThrowsClause") @Nonnull private String readNonEmptyLine() throws IOException { String line = null; @@ -430,7 +432,7 @@ private void nextChunk() throws EOFException { bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); } else { LOG.debug("nextChunk: End of chunked file found (chunk {} not found)", fileName); - throw new EOFException(); + throw new EOFException("getResourceAsStream() returned null"); } } diff --git a/src/test/java/com/mapcode/TerritoryTest.java b/src/test/java/com/mapcode/TerritoryTest.java index 6b406d4..c693391 100644 --- a/src/test/java/com/mapcode/TerritoryTest.java +++ b/src/test/java/com/mapcode/TerritoryTest.java @@ -24,7 +24,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; -@SuppressWarnings({"OverlyBroadThrowsClause", "ProhibitedExceptionDeclared"}) +@SuppressWarnings("MagicNumber") public class TerritoryTest { private static final Logger LOG = LoggerFactory.getLogger(TerritoryTest.class); @@ -48,20 +48,20 @@ public void checkFullName() { @Test public void checkAlphabets() { LOG.info("checkAlphabets"); - assertEquals(Territory.VAT.getAlphabets().length, 1); - assertEquals(Territory.PRI.getAlphabets().length, 1); - assertEquals(Territory.AAA.getAlphabets().length, 1); - assertEquals(Territory.CN_XZ.getAlphabets().length, 3); - assertEquals(Territory.IN_LD.getAlphabets().length, 3); - assertEquals(Territory.VAT.getAlphabets()[0], Alphabet.ROMAN); - assertEquals(Territory.PRI.getAlphabets()[0], Alphabet.ROMAN); - assertEquals(Territory.CPT.getAlphabets()[0], Alphabet.ROMAN); - assertEquals(Territory.CN_XZ.getAlphabets()[0], Alphabet.TIBETAN); - assertEquals(Territory.CN_XZ.getAlphabets()[1], Alphabet.CHINESE); - assertEquals(Territory.CN_XZ.getAlphabets()[2], Alphabet.ROMAN); - assertEquals(Territory.IN_LD.getAlphabets()[0], Alphabet.MALAYALAM); - assertEquals(Territory.IN_LD.getAlphabets()[1], Alphabet.ROMAN); - assertEquals(Territory.IN_LD.getAlphabets()[2], Alphabet.DEVANAGARI); + assertEquals(1, Territory.VAT.getAlphabets().length); + assertEquals(1, Territory.PRI.getAlphabets().length); + assertEquals(1, Territory.AAA.getAlphabets().length); + assertEquals(3, Territory.CN_XZ.getAlphabets().length); + assertEquals(3, Territory.IN_LD.getAlphabets().length); + assertEquals(Alphabet.ROMAN, Territory.VAT.getAlphabets()[0]); + assertEquals(Alphabet.ROMAN, Territory.PRI.getAlphabets()[0]); + assertEquals(Alphabet.ROMAN, Territory.CPT.getAlphabets()[0]); + assertEquals(Alphabet.TIBETAN, Territory.CN_XZ.getAlphabets()[0]); + assertEquals(Alphabet.CHINESE, Territory.CN_XZ.getAlphabets()[1]); + assertEquals(Alphabet.ROMAN, Territory.CN_XZ.getAlphabets()[2]); + assertEquals(Alphabet.MALAYALAM, Territory.IN_LD.getAlphabets()[0]); + assertEquals(Alphabet.ROMAN, Territory.IN_LD.getAlphabets()[1]); + assertEquals(Alphabet.DEVANAGARI, Territory.IN_LD.getAlphabets()[2]); } @Test @@ -96,7 +96,7 @@ public void disambiguateMNTest2() { } @Test - public void testTerritoryFromString() throws Exception { + public void testTerritoryFromString() { LOG.info("testTerritoryFromString"); // Accept ISO-style codes. @@ -124,7 +124,7 @@ public void testTerritoryFromString() throws Exception { } @Test(expected = UnknownTerritoryException.class) - public void testTerritoryFromStringIncorrectDash1() throws Exception { + public void testTerritoryFromStringIncorrectDash1() { LOG.info("testTerritoryFromStringIncorrectDash1"); // Issue: https://github.com/mapcode-foundation/mapcode-java/issues/23 @@ -132,13 +132,13 @@ public void testTerritoryFromStringIncorrectDash1() throws Exception { } @Test(expected = UnknownTerritoryException.class) - public void testTerritoryFromStringIncorrectDash2() throws Exception { + public void testTerritoryFromStringIncorrectDash2() { LOG.info("testTerritoryFromStringIncorrectDash2"); assertEquals(Territory.AAA, Territory.fromString("USA-NLD")); // Exception must be thrown. } @Test(expected = UnknownTerritoryException.class) - public void testTerritoryFromStringNumeric() throws Exception { + public void testTerritoryFromStringNumeric() { LOG.info("testTerritoryFromStringNumeric"); // No longer support: numeric codes. @@ -177,9 +177,10 @@ public void testFromStringError3() { Territory.fromString("999"); } + @Test public void testFromNumberOK() { LOG.info("testFromNumberOK"); - Territory.fromNumber(0); + assertEquals(Territory.VAT, Territory.fromNumber(0)); } @Test(expected = UnknownTerritoryException.class) From 786d23eb16a5aedabad9a5f49bb1eed993d395df Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Thu, 3 May 2018 14:03:56 +0200 Subject: [PATCH 2/7] Adds convenience methods for ISO2/3 codes --- README.md | 21 ++++++ src/main/java/com/mapcode/Boundary.java | 2 +- src/main/java/com/mapcode/Decoder.java | 8 +-- src/main/java/com/mapcode/Encoder.java | 2 +- src/main/java/com/mapcode/MapcodeCodec.java | 73 +++++++++++++++++++- src/main/java/com/mapcode/Territory.java | 45 ++++++++++++ src/test/java/com/mapcode/EncoderTest.java | 36 ++++++++++ src/test/java/com/mapcode/MapcodeTest.java | 2 +- src/test/java/com/mapcode/TerritoryTest.java | 52 ++++++++++++++ 9 files changed, 231 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index c30b8d1..ce6e1aa 100644 --- a/README.md +++ b/README.md @@ -295,6 +295,22 @@ This resticts encoding to a specific territory and produces a potentially empty Again, if encoding succeeded, the first mapcode is the shortest one and the last mapcode in the list is the globally unique international mapcode. +**`List encodeRestrictToCountryISO2/ISO3(double latitude, double longitude, String countryISO2/ISO3)`** encodes a (latitude, +longitude) pair, where encoding is restricted to a specific country, provided as an ISO 3166-2 or -3 country code. + +Example: + + List results = MapcodeCodec.encodeRestrictToCountryISO2(lat, lon, "BR"); + // Returns a list of mapcodes retricted to Brazil (not: IN-BR). + + List results = MapcodeCodec.encodeRestrictToCountryISO3(lat, lon, "MEX"); + // Returns a list of mapcodes retricted to Mexico. + +**Important notice:** The codes used in these methods asume the ISO conversion, +not the `fromString` conversion from `Territory`. For example, `Territory.fromString("BR")` +produce the territory `IN-BR`, whereas `Territory.fromCountryISO2("BR")` produces +the territory `BRA`. + Both `encode()` methods are also offered as a `encodeToShortest()` method, which essentially returns only the first result of the previous methods (if there are any results). @@ -381,6 +397,9 @@ smaller areas, so mapcodes can remain fairly short: Rather than using the 3-letter territory code for mapcodes in these territories, you'd probably want to use the `TT-XXX` form, where `XXX` defines the subterritory (state, province, etc.) +Two convenience methods are provided to create a territory code from an ISO 3166-2 or -3 code: +`Territory.fromCountryISO2(String)` and `Territory.fromCountryISO3(String)`. + ## Enum `Alphabet` @@ -465,6 +484,8 @@ These are the release notes for the Java library for mapcodes. * General cleanup after running stricter IntelliJ inspections profile. +* Added convenience methods to restrict encoded mapcodes to specific ISO 3166-2 or 3 country codes. + ### 2.4.5 * Remove hard reference to `log4j` for production. Left only for unit tests. diff --git a/src/main/java/com/mapcode/Boundary.java b/src/main/java/com/mapcode/Boundary.java index 4663d59..060ed71 100644 --- a/src/main/java/com/mapcode/Boundary.java +++ b/src/main/java/com/mapcode/Boundary.java @@ -82,7 +82,7 @@ Boundary extendBoundary(final int latMicroDegExtension, final int lonMicroDegExt * Note: Points at the exact North pole with latitude 90 are never part of a boundary. * * @param p Point to check. - * @return True if the points falls within the boudary. + * @return True if the points falls within the boundary. */ boolean containsPoint(@Nonnull final Point p) { if (!p.isDefined()) { diff --git a/src/main/java/com/mapcode/Decoder.java b/src/main/java/com/mapcode/Decoder.java index f86089a..d0d2450 100644 --- a/src/main/java/com/mapcode/Decoder.java +++ b/src/main/java/com/mapcode/Decoder.java @@ -342,7 +342,7 @@ private static MapcodeZone decodeGrid( int relx; int rely; final int codexlen = result.length() - 1; // length ex dot - int prelen = result.indexOf('.'); // dotposition + int prelen = result.indexOf('.'); // dot position if ((prelen == 1) && (codexlen == 5)) { prelen++; @@ -389,7 +389,7 @@ private static MapcodeZone decodeGrid( String rest = result.substring(prelen + 1); - // decoderelative (postfix vs rely,relx) + // decode relative (postfix vs rely, relx) final int difx; int dify; @@ -682,7 +682,7 @@ private static String aeuUnpack(@Nonnull final String argStr) { if (DECODE_CHARS[i] < 0) { return ""; // bad char! } else if (voweled && (DECODE_CHARS[(int) str.charAt(v)] > 9)) { - return ""; // nonodigit! + return ""; // no-nodigit! } } } @@ -923,7 +923,7 @@ private static boolean isAbjadScript(@Nonnull final String argStr) { return true; // Hebrew } if ((c >= 0x388) && (c <= 0x3C9)) { - return true; // Greek uppercase and lowecase + return true; // Greek uppercase and lowercase } if (((c >= 0x1100) && (c <= 0x1174)) || ((c >= 0xad6c) && (c <= 0xd314))) { return true; // Korean diff --git a/src/main/java/com/mapcode/Encoder.java b/src/main/java/com/mapcode/Encoder.java index 38083e3..21cf098 100644 --- a/src/main/java/com/mapcode/Encoder.java +++ b/src/main/java/com/mapcode/Encoder.java @@ -487,7 +487,7 @@ static String aeuPack( str = str.substring(0, d); rlen = d; } else { - return str; // not alldigit (or multiple dots) + return str; // not all-digit (or multiple dots) } } } diff --git a/src/main/java/com/mapcode/MapcodeCodec.java b/src/main/java/com/mapcode/MapcodeCodec.java index 5dd8bc4..1644c58 100644 --- a/src/main/java/com/mapcode/MapcodeCodec.java +++ b/src/main/java/com/mapcode/MapcodeCodec.java @@ -18,6 +18,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; @@ -106,12 +107,80 @@ public static List encode(final double latDeg, final double lonDeg, } @Nonnull - public static List encode(@Nonnull final Point point, @Nullable final Territory restrictToTerritory) + public static List encode(@Nonnull final Point point, + @Nullable final Territory restrictToTerritory) throws IllegalArgumentException { checkNonnull("point", point); return encode(point.getLatDeg(), point.getLonDeg(), restrictToTerritory); } + /** + * Encode a lat/lon pair to a list of mapcodes, like {@link #encode(double, double)}. + * The result list is limited to those mapcodes that belong to the provided ISO 3166-2 country code. + * For example, if you wish to restrict the list to Mexican mapcodes, use "MX". This would + * produce a result list of mapcodes with territories that start with "MX-" (note that a + * mapcode that starts with "MEX" is not returned in that case.) + * + * @param latDeg Latitude, accepted range: -90..90. + * @param lonDeg Longitude, accepted range: -180..180. + * @param countryISO2 ISO 3166-2 country code. + * @return Possibly empty, ordered list of mapcode information records, see {@link Mapcode}. + * @throws IllegalArgumentException Thrown if latitude or longitude are out of range, or if the ISO code is invalid. + */ + @Nonnull + public static List encodeRestrictToCountryISO2(final double latDeg, final double lonDeg, + @Nonnull final String countryISO2) + throws IllegalArgumentException { + checkNonnull("countryISO2", countryISO2); + final String prefix = countryISO2.toUpperCase() + '-'; + final List mapcodes = encode(latDeg, lonDeg); + final List filtered = new ArrayList(); + for (final Mapcode mapcode : mapcodes) { + if (mapcode.getTerritory().toString().startsWith(prefix)) { + filtered.add(mapcode); + } + } + return filtered; + } + + @Nonnull + public static List encodeRestrictToCountryISO2(@Nonnull final Point point, + @Nonnull final String countryISO2) + throws IllegalArgumentException { + checkNonnull("point", point); + return encodeRestrictToCountryISO2(point.getLatDeg(), point.getLonDeg(), countryISO2); + } + + /** + * Encode a lat/lon pair to a list of mapcodes, like {@link #encode(double, double)}. + * The result list is limited to those mapcodes that belong to the provided ISO 3166-3 country code. + * For example, if you wish to restrict the list to Mexican mapcodes, use "MEX". This would + * produce a result list of mapcodes with territories that start with "MEX" (note that + * mapcode that starts with "MX-" are not returned in that case.) + * + * @param latDeg Latitude, accepted range: -90..90. + * @param lonDeg Longitude, accepted range: -180..180. + * @param countryISO3 ISO 3166-3 country code. + * @return Possibly empty, ordered list of mapcode information records, see {@link Mapcode}. + * @throws IllegalArgumentException Thrown if latitude or longitude are out of range, or if the ISO code is invalid. + */ + @Nonnull + public static List encodeRestrictToCountryISO3(final double latDeg, final double lonDeg, + @Nonnull final String countryISO3) + throws IllegalArgumentException { + checkNonnull("countryISO3", countryISO3); + final Territory restrictToTerritory = Territory.fromCountryISO3(countryISO3); + return encode(latDeg, lonDeg, restrictToTerritory); + } + + @Nonnull + public static List encodeRestrictToCountryISO3(@Nonnull final Point point, + @Nonnull final String countryISO3) + throws IllegalArgumentException { + checkNonnull("point", point); + return encodeRestrictToCountryISO3(point.getLatDeg(), point.getLonDeg(), countryISO3); + } + /** * Encode a lat/lon pair to its shortest mapcode with territory information. * @@ -272,8 +341,6 @@ public static Rectangle decodeToRectangle(@Nonnull final String mapcode, @Nullab return rectangle; } - - // TODO: Explain when this method is needed/used. /** * Is coordinate near multiple territory borders? * diff --git a/src/main/java/com/mapcode/Territory.java b/src/main/java/com/mapcode/Territory.java index be7af23..a9eb6cd 100644 --- a/src/main/java/com/mapcode/Territory.java +++ b/src/main/java/com/mapcode/Territory.java @@ -704,6 +704,51 @@ public static Territory fromString(@Nonnull final String alphaCode, return createFromString(alphaCode, parentTerritory); } + // Keep a mapping from ISO3 to ISO2 codes. This map is used to make sure valid ISO3 codes are being used. + private static final Map MAP_ISO3_TO_ISO2; + + static { + final String[] countries = Locale.getISOCountries(); + MAP_ISO3_TO_ISO2 = new HashMap(countries.length); + for (final String countryISO2 : countries) { + final String countryISO3 = new Locale("", countryISO2).getISO3Country(); + MAP_ISO3_TO_ISO2.put(countryISO3.toUpperCase(), countryISO2.toUpperCase()); + } + } + + /** + * Create a Territory object from a valid ISO2 country code. + * + * @param countryISO2 ISO 3166-2 country code. + * @return Territory object for the country. + * @throws IllegalArgumentException Thrown if the country code is not a valid ISO 3166-2 code. + */ + @Nonnull + public static Territory fromCountryISO2(@Nonnull final String countryISO2) { + final Locale locale = new Locale("", countryISO2); + try { + final String countryISO3 = locale.getISO3Country().toUpperCase(); + return fromString(countryISO3); + } catch (final MissingResourceException ignored) { + throw new IllegalArgumentException("Parameter " + countryISO2 + " must be a valid ISO 3166-2 country code"); + } + } + + /** + * Create a Territory object from a valid ISO 3166-3 country code. + * + * @param countryISO3 ISO 3166-3 country code. + * @return Territory object for the country. + * @throws IllegalArgumentException Thrown if the country code is not a valid ISO 3166-3 code. + */ + @Nonnull + public static Territory fromCountryISO3(@Nonnull final String countryISO3) { + if (!MAP_ISO3_TO_ISO2.containsKey(countryISO3.toUpperCase())) { + throw new IllegalArgumentException("Parameter " + countryISO3 + " must be a valid ISO 3166-3 country code"); + } + return fromString(countryISO3); + } + /** * Return the international value of the territory name, with dashes rather than underscores. * This is the same as {@link #toAlphaCode(AlphaCodeFormat)} for {@link AlphaCodeFormat#INTERNATIONAL}. diff --git a/src/test/java/com/mapcode/EncoderTest.java b/src/test/java/com/mapcode/EncoderTest.java index 85ab629..3d8c9d4 100644 --- a/src/test/java/com/mapcode/EncoderTest.java +++ b/src/test/java/com/mapcode/EncoderTest.java @@ -261,4 +261,40 @@ public void legalArguments() { assertEquals(MapcodeCodec.encode(0, -181), MapcodeCodec.encode(0, 179)); assertEquals(MapcodeCodec.encode(0, 181), MapcodeCodec.encode(0, -179)); } + + private static final Point CIUDAD_JUAREZ = Point.fromDeg(31.7, -106.5); + + @Test + public void testEncodeCiudadJuarez() { + LOG.info("testEncodeCiudadJuarez"); + final List mapcodes = MapcodeCodec.encode(CIUDAD_JUAREZ); + assertEquals(13, mapcodes.size()); + assertEquals("MX-CHH 5S.0G", mapcodes.get(0).toString()); + } + + @Test + public void testEncodeRestrictToCountryISO2() { + LOG.info("testEncodeRestrictToCountryISO2"); + final Point ciudadJuarez = Point.fromDeg(31.7, -106.5); + final List mapcodesMX = MapcodeCodec.encodeRestrictToCountryISO2(ciudadJuarez, "MX"); + assertEquals(5, mapcodesMX.size()); + assertEquals("MX-CHH 5S.0G", mapcodesMX.get(0).toString()); + + final List mapcodesUS = MapcodeCodec.encodeRestrictToCountryISO2(ciudadJuarez, "us"); + assertEquals(4, mapcodesUS.size()); + assertEquals("US-NM T1DZ.338", mapcodesUS.get(0).toString()); + } + + @Test + public void testEncodeRestrictToCountryISO3() { + LOG.info("testEncodeRestrictToCountryISO3"); + final Point ciudadJuarez = Point.fromDeg(31.7, -106.5); + final List mapcodesMEX = MapcodeCodec.encodeRestrictToCountryISO3(ciudadJuarez, "MEX"); + assertEquals(2, mapcodesMEX.size()); + assertEquals("MEX 4CMT.DLX", mapcodesMEX.get(0).toString()); + + final List mapcodesUSA = MapcodeCodec.encodeRestrictToCountryISO3(ciudadJuarez, "usa"); + assertEquals(1, mapcodesUSA.size()); + assertEquals("USA NG4F.K745", mapcodesUSA.get(0).toString()); + } } diff --git a/src/test/java/com/mapcode/MapcodeTest.java b/src/test/java/com/mapcode/MapcodeTest.java index 8f44ddc..76a1582 100644 --- a/src/test/java/com/mapcode/MapcodeTest.java +++ b/src/test/java/com/mapcode/MapcodeTest.java @@ -86,7 +86,7 @@ public void checkInvalidPrecisionFormats() { assertFalse(Mapcode.isValidMapcodeFormat("NL- XX.XX")); assertFalse(Mapcode.isValidMapcodeFormat("US IN XX.XX")); - // Incorrect (nunber of) characters. + // Incorrect (number of) characters. assertFalse(Mapcode.isValidMapcodeFormat("P")); assertFalse(Mapcode.isValidMapcodeFormat("PQ")); assertFalse(Mapcode.isValidMapcodeFormat("PQ.")); diff --git a/src/test/java/com/mapcode/TerritoryTest.java b/src/test/java/com/mapcode/TerritoryTest.java index c693391..c112c2c 100644 --- a/src/test/java/com/mapcode/TerritoryTest.java +++ b/src/test/java/com/mapcode/TerritoryTest.java @@ -194,4 +194,56 @@ public void testFromNumberError2() { LOG.info("testFromNumberError2"); Territory.fromNumber(99999); } + + @Test(expected = IllegalArgumentException.class) + public void testFromStringCountryIso2Error1() { + LOG.info("testFromStringCountryIso2Error1"); + Territory.fromCountryISO2("US-IN"); + } + + @Test(expected = IllegalArgumentException.class) + public void testFromStringCountryIso2Error2() { + LOG.info("testFromStringCountryIso2Error2"); + Territory.fromCountryISO2("USA"); + } + + @Test(expected = IllegalArgumentException.class) + public void testFromStringCountryIso2Error3() { + LOG.info("testFromStringCountryIso2Error3"); + Territory.fromCountryISO2(""); + } + + @Test + public void testFromStringCountryIso2OK() { + LOG.info("testFromStringCountryIso2OK"); + assertEquals("NLD", Territory.fromCountryISO2("NL").toString()); + assertEquals("BRA", Territory.fromCountryISO2("br").toString()); + assertEquals("USA", Territory.fromCountryISO2("Us").toString()); + } + + @Test(expected = IllegalArgumentException.class) + public void testFromStringCountryIso3Error1() { + LOG.info("testFromStringCountryIso3Error1"); + Territory.fromCountryISO3("US-IN"); + } + + @Test(expected = IllegalArgumentException.class) + public void testFromStringCountryIso3Error2() { + LOG.info("testFromStringCountryIso3Error2"); + Territory.fromCountryISO3("US"); + } + + @Test(expected = IllegalArgumentException.class) + public void testFromStringCountryIso3Error3() { + LOG.info("testFromStringCountryIso3Error3"); + Territory.fromCountryISO3(""); + } + + @Test + public void testFromStringCountryIso3OK() { + LOG.info("testFromStringCountryIso3OK"); + assertEquals("NLD", Territory.fromCountryISO3("NLD").toString()); + assertEquals("BRA", Territory.fromCountryISO3("bra").toString()); + assertEquals("USA", Territory.fromCountryISO3("Usa").toString()); + } } From 4107da30522e67376042cde7e7956493176d26ed Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Thu, 3 May 2018 14:21:15 +0200 Subject: [PATCH 3/7] Fixes JavaDoc comments --- src/main/java/com/mapcode/Boundary.java | 8 ++--- src/main/java/com/mapcode/CheckArgs.java | 8 ++--- src/main/java/com/mapcode/Common.java | 8 ++--- src/main/java/com/mapcode/Data.java | 8 ++--- src/main/java/com/mapcode/DataModel.java | 10 +++--- src/main/java/com/mapcode/Decoder.java | 8 ++--- src/main/java/com/mapcode/Encoder.java | 8 ++--- src/main/java/com/mapcode/MapcodeCodec.java | 25 ++++++-------- src/main/java/com/mapcode/MapcodeZone.java | 8 ++--- src/main/java/com/mapcode/Point.java | 9 +++-- src/main/java/com/mapcode/Territory.java | 38 ++++++++++----------- 11 files changed, 67 insertions(+), 71 deletions(-) diff --git a/src/main/java/com/mapcode/Boundary.java b/src/main/java/com/mapcode/Boundary.java index 060ed71..c62689d 100644 --- a/src/main/java/com/mapcode/Boundary.java +++ b/src/main/java/com/mapcode/Boundary.java @@ -18,11 +18,11 @@ import javax.annotation.Nonnull; +// ---------------------------------------------------------------------------------------------- +// Package private implementation class. For internal use within the mapcode implementation only. +//---------------------------------------------------------------------------------------------- + /** - * ---------------------------------------------------------------------------------------------- - * Package private implementation class. For internal use within the mapcode implementation only. - * ---------------------------------------------------------------------------------------------- - * * This class handles territory rectangles for mapcodes. */ final class Boundary { diff --git a/src/main/java/com/mapcode/CheckArgs.java b/src/main/java/com/mapcode/CheckArgs.java index 5d28768..6d9727f 100644 --- a/src/main/java/com/mapcode/CheckArgs.java +++ b/src/main/java/com/mapcode/CheckArgs.java @@ -21,11 +21,11 @@ import static com.mapcode.Mapcode.getPrecisionFormat; +// ---------------------------------------------------------------------------------------------- +// Package private implementation class. For internal use within the mapcode implementation only. +// ---------------------------------------------------------------------------------------------- + /** - * ---------------------------------------------------------------------------------------------- - * Package private implementation class. For internal use within the mapcode implementation only. - * ---------------------------------------------------------------------------------------------- - * * This class provides a number of helper methods to check (runtime) arguments. */ final class CheckArgs { diff --git a/src/main/java/com/mapcode/Common.java b/src/main/java/com/mapcode/Common.java index c9ac629..da5ed0e 100644 --- a/src/main/java/com/mapcode/Common.java +++ b/src/main/java/com/mapcode/Common.java @@ -19,11 +19,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +// ---------------------------------------------------------------------------------------------- +// Package private implementation class. For internal use within the Mapcode implementation only. +// ---------------------------------------------------------------------------------------------- + /** - * ---------------------------------------------------------------------------------------------- - * Package private implementation class. For internal use within the Mapcode implementation only. - * ---------------------------------------------------------------------------------------------- - * * This class contains common data structures and methods used by the Mapcode implementation. */ @SuppressWarnings("MagicNumber") diff --git a/src/main/java/com/mapcode/Data.java b/src/main/java/com/mapcode/Data.java index 209924e..36f28cf 100644 --- a/src/main/java/com/mapcode/Data.java +++ b/src/main/java/com/mapcode/Data.java @@ -18,11 +18,11 @@ import javax.annotation.Nonnull; +// ---------------------------------------------------------------------------------------------- +// Package private implementation class. For internal use within the Mapcode implementation only. +// ---------------------------------------------------------------------------------------------- + /** - * ---------------------------------------------------------------------------------------------- - * Package private implementation class. For internal use within the Mapcode implementation only. - * ---------------------------------------------------------------------------------------------- - * * This class the data class for Mapcode codex items. */ @SuppressWarnings("MagicNumber") diff --git a/src/main/java/com/mapcode/DataModel.java b/src/main/java/com/mapcode/DataModel.java index 00f674f..5b0252a 100644 --- a/src/main/java/com/mapcode/DataModel.java +++ b/src/main/java/com/mapcode/DataModel.java @@ -24,11 +24,11 @@ import java.io.IOException; import java.io.InputStream; +// ---------------------------------------------------------------------------------------------- +// Package private implementation class. For internal use within the Mapcode implementation only. +// ---------------------------------------------------------------------------------------------- + /** - * ---------------------------------------------------------------------------------------------- - * Package private implementation class. For internal use within the Mapcode implementation only. - * ---------------------------------------------------------------------------------------------- - * * This class contains the module that reads the Mapcode areas into memory and processes them. */ @SuppressWarnings("MagicNumber") @@ -204,7 +204,7 @@ int getNrTerritoryRecords() { } @SuppressWarnings("PointlessArithmeticExpression") - // TODO: Explain what this does exactly, why not return a Point or Rectangle? + // TODO: Explain what this does exactly, why not return a Point or Rectangle? int getLonMicroDegMin(final int territoryRecord) { return data[((territoryRecord * DATA_FIELDS_PER_REC) + POS_DATA_LON_MICRO_DEG_MIN)]; } diff --git a/src/main/java/com/mapcode/Decoder.java b/src/main/java/com/mapcode/Decoder.java index d0d2450..de46cb5 100644 --- a/src/main/java/com/mapcode/Decoder.java +++ b/src/main/java/com/mapcode/Decoder.java @@ -23,11 +23,11 @@ import static com.mapcode.Boundary.createBoundaryForTerritoryRecord; +// ---------------------------------------------------------------------------------------------- +// Package private implementation class. For internal use within the mapcode implementation only. +//---------------------------------------------------------------------------------------------- + /** - * ---------------------------------------------------------------------------------------------- - * Package private implementation class. For internal use within the Mapcode implementation only. - * ---------------------------------------------------------------------------------------------- - * * This class contains decoder for mapcodes. */ @SuppressWarnings({"MagicNumber", "StringConcatenationMissingWhitespace"}) diff --git a/src/main/java/com/mapcode/Encoder.java b/src/main/java/com/mapcode/Encoder.java index 21cf098..6c3cbf9 100644 --- a/src/main/java/com/mapcode/Encoder.java +++ b/src/main/java/com/mapcode/Encoder.java @@ -27,11 +27,11 @@ import static com.mapcode.Boundary.createBoundaryForTerritoryRecord; import static com.mapcode.Common.*; + // ---------------------------------------------------------------------------------------------- + // Package private implementation class. For internal use within the Mapcode implementation only. + // ---------------------------------------------------------------------------------------------- + /** - * ---------------------------------------------------------------------------------------------- - * Package private implementation class. For internal use within the Mapcode implementation only. - * ---------------------------------------------------------------------------------------------- - * * This class contains encoder for mapcodes. */ @SuppressWarnings({"MagicNumber", "StringConcatenationMissingWhitespace"}) diff --git a/src/main/java/com/mapcode/MapcodeCodec.java b/src/main/java/com/mapcode/MapcodeCodec.java index 1644c58..c721aed 100644 --- a/src/main/java/com/mapcode/MapcodeCodec.java +++ b/src/main/java/com/mapcode/MapcodeCodec.java @@ -26,11 +26,11 @@ import static com.mapcode.CheckArgs.checkNonnull; import static com.mapcode.Mapcode.getPrecisionFormat; +// ---------------------------------------------------------------------------------------------- +// Package private implementation class. For internal use within the mapcode implementation only. +//---------------------------------------------------------------------------------------------- + /** - * ---------------------------------------------------------------------------------------------- - * Mapcode public interface. - * ---------------------------------------------------------------------------------------------- - * * This class is the external Java interface for encoding and decoding mapcodes. */ @SuppressWarnings("MagicNumber") @@ -43,11 +43,9 @@ private MapcodeCodec() { // Prevent instantiation. } - /** - * ------------------------------------------------------------------------------------------ - * Encoding latitude, longitude to mapcodes. - * ------------------------------------------------------------------------------------------ - */ + // ------------------------------------------------------------------------------------------ + // Encoding latitude, longitude to mapcodes. + // ------------------------------------------------------------------------------------------ /** * Encode a lat/lon pair to a mapcode with territory information. This produces a non-empty list of mapcode, @@ -243,11 +241,10 @@ public static Mapcode encodeToInternational(@Nonnull final Point point) return encodeToInternational(point.getLatDeg(), point.getLonDeg()); } - /** - * ------------------------------------------------------------------------------------------ - * Decoding mapcodes back to latitude, longitude. - * ------------------------------------------------------------------------------------------ - */ + // ------------------------------------------------------------------------------------------ + // Decoding mapcodes back to latitude, longitude. + // ------------------------------------------------------------------------------------------ + // /** * Decode a mapcode to a Point. The decoding process may fail for local mapcodes, diff --git a/src/main/java/com/mapcode/MapcodeZone.java b/src/main/java/com/mapcode/MapcodeZone.java index 208da94..1d8e39c 100644 --- a/src/main/java/com/mapcode/MapcodeZone.java +++ b/src/main/java/com/mapcode/MapcodeZone.java @@ -18,11 +18,11 @@ import javax.annotation.Nonnull; +// ---------------------------------------------------------------------------------------------- +// Package private implementation class. For internal use within the Mapcode implementation only. +// ---------------------------------------------------------------------------------------------- + /** - * ---------------------------------------------------------------------------------------------- - * Package private implementation class. For internal use within the Mapcode implementation only. - * ---------------------------------------------------------------------------------------------- - * * Simple class to represent all the coordinates that would deliver a particular mapcode. */ class MapcodeZone { diff --git a/src/main/java/com/mapcode/Point.java b/src/main/java/com/mapcode/Point.java index b789fe5..07e939c 100644 --- a/src/main/java/com/mapcode/Point.java +++ b/src/main/java/com/mapcode/Point.java @@ -241,11 +241,10 @@ public boolean equals(final Object obj) { (this.defined == that.defined); } - /** - * ----------------------------------------------------------------------- - * (Package) private data and methods. - * ----------------------------------------------------------------------- - */ + // ----------------------------------------------------------------------- + // (Package) private data and methods. + // ----------------------------------------------------------------------- + // Constants to convert between Degrees, MicroDegrees and Fractions static final double MICRODEG_TO_DEG_FACTOR = 1000000.0; static final double MAX_PRECISION_FACTOR = 810000.0; diff --git a/src/main/java/com/mapcode/Territory.java b/src/main/java/com/mapcode/Territory.java index a9eb6cd..cf11c3b 100644 --- a/src/main/java/com/mapcode/Territory.java +++ b/src/main/java/com/mapcode/Territory.java @@ -22,11 +22,11 @@ import static com.mapcode.CheckArgs.checkNonnull; +// ---------------------------------------------------------------------------------------------- +// Mapcode public interface. +// ---------------------------------------------------------------------------------------------- + /** - * ---------------------------------------------------------------------------------------------- - * Mapcode public interface. - * ---------------------------------------------------------------------------------------------- - * * This class defines the available territory codes as used by mapcode. */ public enum Territory { @@ -840,37 +840,37 @@ public boolean hasSubdivisions() { * Private constructors to create a territory code. */ Territory(final int number, - @Nonnull final String fullName) { + @Nonnull final String fullName) { this(number, fullName, null, null, null, null); } Territory(final int number, - @Nonnull final String fullName, - @Nullable final Alphabet[] alphabets) { + @Nonnull final String fullName, + @Nullable final Alphabet[] alphabets) { this(number, fullName, alphabets, null, null, null); } Territory(final int number, - @Nonnull final String fullName, - @Nullable final Alphabet[] alphabets, - @Nullable final Territory parentTerritory) { + @Nonnull final String fullName, + @Nullable final Alphabet[] alphabets, + @Nullable final Territory parentTerritory) { this(number, fullName, alphabets, parentTerritory, null, null); } Territory(final int number, - @Nonnull final String fullName, - @Nullable final Alphabet[] alphabets, - @Nullable final Territory parentTerritory, - @Nullable final String[] aliases) { + @Nonnull final String fullName, + @Nullable final Alphabet[] alphabets, + @Nullable final Territory parentTerritory, + @Nullable final String[] aliases) { this(number, fullName, alphabets, parentTerritory, aliases, null); } Territory(final int number, - @Nonnull final String fullName, - @Nullable final Alphabet[] alphabets, - @Nullable final Territory parentTerritory, - @Nullable final String[] aliases, - @Nullable final String[] fullNameAliases) { + @Nonnull final String fullName, + @Nullable final Alphabet[] alphabets, + @Nullable final Territory parentTerritory, + @Nullable final String[] aliases, + @Nullable final String[] fullNameAliases) { assert number >= 0; this.number = number; this.fullName = fullName; From 3ed49d9379d507cdcbc00f995ce95613f4608723 Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Thu, 3 May 2018 14:24:48 +0200 Subject: [PATCH 4/7] New POM version 2.4.6 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7d65789..428773e 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ mapcode jar - 2.4.6-SNAPSHOT + 2.4.6 Mapcode Java Library From 94a41153a40bb6d3cd447d2b0d75b2df5581cf48 Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Thu, 3 May 2018 15:11:58 +0200 Subject: [PATCH 5/7] Returns ISO3 countries also when restricted to ISO2 --- src/main/java/com/mapcode/MapcodeCodec.java | 11 +++++ src/test/java/com/mapcode/EncoderTest.java | 46 ++++++++++++++++----- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/mapcode/MapcodeCodec.java b/src/main/java/com/mapcode/MapcodeCodec.java index c721aed..39c4d64 100644 --- a/src/main/java/com/mapcode/MapcodeCodec.java +++ b/src/main/java/com/mapcode/MapcodeCodec.java @@ -130,12 +130,23 @@ public static List encodeRestrictToCountryISO2(final double latDeg, fin @Nonnull final String countryISO2) throws IllegalArgumentException { checkNonnull("countryISO2", countryISO2); + final String countryISO3 = Territory.fromCountryISO2(countryISO2).toString(); final String prefix = countryISO2.toUpperCase() + '-'; final List mapcodes = encode(latDeg, lonDeg); final List filtered = new ArrayList(); for (final Mapcode mapcode : mapcodes) { + if (mapcode.getTerritory().toString().startsWith(prefix)) { + // If the mapcode starts with the ISO 2 code, it's OK. filtered.add(mapcode); + + } else if (mapcode.getTerritory().toString().equals(countryISO3)) { + + // Otherwise, if it's the correct country ISO 3 code, it's also OK. + filtered.add(mapcode); + } else { + + // Nothing. } } return filtered; diff --git a/src/test/java/com/mapcode/EncoderTest.java b/src/test/java/com/mapcode/EncoderTest.java index 3d8c9d4..85c3158 100644 --- a/src/test/java/com/mapcode/EncoderTest.java +++ b/src/test/java/com/mapcode/EncoderTest.java @@ -263,6 +263,7 @@ public void legalArguments() { } private static final Point CIUDAD_JUAREZ = Point.fromDeg(31.7, -106.5); + private static final Point VAALS = Point.fromDeg(50.8, 6.0); @Test public void testEncodeCiudadJuarez() { @@ -273,28 +274,51 @@ public void testEncodeCiudadJuarez() { } @Test - public void testEncodeRestrictToCountryISO2() { - LOG.info("testEncodeRestrictToCountryISO2"); - final Point ciudadJuarez = Point.fromDeg(31.7, -106.5); - final List mapcodesMX = MapcodeCodec.encodeRestrictToCountryISO2(ciudadJuarez, "MX"); - assertEquals(5, mapcodesMX.size()); + public void testEncodeRestrictToCountryISO2CountryWithSubdivision() { + LOG.info("testEncodeRestrictToCountryISO2CountryWithSubdivision"); + final List mapcodesMX = MapcodeCodec.encodeRestrictToCountryISO2(CIUDAD_JUAREZ, "MX"); + assertEquals(7, mapcodesMX.size()); assertEquals("MX-CHH 5S.0G", mapcodesMX.get(0).toString()); - final List mapcodesUS = MapcodeCodec.encodeRestrictToCountryISO2(ciudadJuarez, "us"); - assertEquals(4, mapcodesUS.size()); + final List mapcodesUS = MapcodeCodec.encodeRestrictToCountryISO2(CIUDAD_JUAREZ, "us"); + assertEquals(5, mapcodesUS.size()); assertEquals("US-NM T1DZ.338", mapcodesUS.get(0).toString()); } @Test - public void testEncodeRestrictToCountryISO3() { - LOG.info("testEncodeRestrictToCountryISO3"); + public void testEncodeRestrictToCountryISO2CountryWithoutSubdivision() { + LOG.info("testEncodeRestrictToCountryISO2CountryWithoutSubdivision"); + final List mapcodesNL = MapcodeCodec.encodeRestrictToCountryISO2(VAALS, "NL"); + assertEquals(2, mapcodesNL.size()); + assertEquals("NLD ZNV.W78", mapcodesNL.get(0).toString()); + + final List mapcodesBE = MapcodeCodec.encodeRestrictToCountryISO2(VAALS, "be"); + assertEquals(2, mapcodesBE.size()); + assertEquals("BEL DRQ.PNK", mapcodesBE.get(0).toString()); + } + + @Test + public void testEncodeRestrictToCountryISO3WithSubdivision() { + LOG.info("testEncodeRestrictToCountryISO3WithSubdivision"); final Point ciudadJuarez = Point.fromDeg(31.7, -106.5); - final List mapcodesMEX = MapcodeCodec.encodeRestrictToCountryISO3(ciudadJuarez, "MEX"); + final List mapcodesMEX = MapcodeCodec.encodeRestrictToCountryISO3(CIUDAD_JUAREZ, "MEX"); assertEquals(2, mapcodesMEX.size()); assertEquals("MEX 4CMT.DLX", mapcodesMEX.get(0).toString()); - final List mapcodesUSA = MapcodeCodec.encodeRestrictToCountryISO3(ciudadJuarez, "usa"); + final List mapcodesUSA = MapcodeCodec.encodeRestrictToCountryISO3(CIUDAD_JUAREZ, "usa"); assertEquals(1, mapcodesUSA.size()); assertEquals("USA NG4F.K745", mapcodesUSA.get(0).toString()); } + + @Test + public void testEncodeRestrictToCountryISO3CountryWithoutSubdivision() { + LOG.info("testEncodeRestrictToCountryISO3CountryWithoutSubdivision"); + final List mapcodesNLD = MapcodeCodec.encodeRestrictToCountryISO3(VAALS, "NLD"); + assertEquals(2, mapcodesNLD.size()); + assertEquals("NLD ZNV.W78", mapcodesNLD.get(0).toString()); + + final List mapcodesBEL = MapcodeCodec.encodeRestrictToCountryISO3(VAALS, "bel"); + assertEquals(2, mapcodesBEL.size()); + assertEquals("BEL DRQ.PNK", mapcodesBEL.get(0).toString()); + } } From 7be24cb0a49eacb1d76dba66b7c3d8e2f28915f0 Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Thu, 3 May 2018 15:59:10 +0200 Subject: [PATCH 6/7] Fixes issue with Clipperton Island CPT/CP --- README.md | 10 +- src/main/java/com/mapcode/MapcodeCodec.java | 11 +- src/main/java/com/mapcode/Territory.java | 112 ++++++++++++------- src/test/java/com/mapcode/EncoderTest.java | 58 +++++----- src/test/java/com/mapcode/TerritoryTest.java | 67 ++++++++--- 5 files changed, 165 insertions(+), 93 deletions(-) diff --git a/README.md b/README.md index ce6e1aa..3190798 100644 --- a/README.md +++ b/README.md @@ -296,15 +296,15 @@ Again, if encoding succeeded, the first mapcode is the shortest one and the last globally unique international mapcode. **`List encodeRestrictToCountryISO2/ISO3(double latitude, double longitude, String countryISO2/ISO3)`** encodes a (latitude, -longitude) pair, where encoding is restricted to a specific country, provided as an ISO 3166-2 or -3 country code. +longitude) pair, where encoding is restricted to a specific country, provided as an ISO 3166 2 or 3 characters country code. Example: List results = MapcodeCodec.encodeRestrictToCountryISO2(lat, lon, "BR"); - // Returns a list of mapcodes retricted to Brazil (not: IN-BR). + // Returns a list of mapcodes retricted to Brazil, so their territories start with BR- or BRA. List results = MapcodeCodec.encodeRestrictToCountryISO3(lat, lon, "MEX"); - // Returns a list of mapcodes retricted to Mexico. + // Returns a list of mapcodes retricted to Mexico, so their therritories start with MX- or MEX. **Important notice:** The codes used in these methods asume the ISO conversion, not the `fromString` conversion from `Territory`. For example, `Territory.fromString("BR")` @@ -397,7 +397,7 @@ smaller areas, so mapcodes can remain fairly short: Rather than using the 3-letter territory code for mapcodes in these territories, you'd probably want to use the `TT-XXX` form, where `XXX` defines the subterritory (state, province, etc.) -Two convenience methods are provided to create a territory code from an ISO 3166-2 or -3 code: +Two convenience methods are provided to create a territory code from an ISO 3166 2 or 3 character code: `Territory.fromCountryISO2(String)` and `Territory.fromCountryISO3(String)`. @@ -484,7 +484,7 @@ These are the release notes for the Java library for mapcodes. * General cleanup after running stricter IntelliJ inspections profile. -* Added convenience methods to restrict encoded mapcodes to specific ISO 3166-2 or 3 country codes. +* Added convenience methods to restrict encoded mapcodes to specific ISO 3166 2 or 3 character country codes. ### 2.4.5 diff --git a/src/main/java/com/mapcode/MapcodeCodec.java b/src/main/java/com/mapcode/MapcodeCodec.java index 39c4d64..c6c16cf 100644 --- a/src/main/java/com/mapcode/MapcodeCodec.java +++ b/src/main/java/com/mapcode/MapcodeCodec.java @@ -114,14 +114,14 @@ public static List encode(@Nonnull final Point point, /** * Encode a lat/lon pair to a list of mapcodes, like {@link #encode(double, double)}. - * The result list is limited to those mapcodes that belong to the provided ISO 3166-2 country code. + * The result list is limited to those mapcodes that belong to the provided ISO 3166 country code, 2 characters. * For example, if you wish to restrict the list to Mexican mapcodes, use "MX". This would * produce a result list of mapcodes with territories that start with "MX-" (note that a * mapcode that starts with "MEX" is not returned in that case.) * * @param latDeg Latitude, accepted range: -90..90. * @param lonDeg Longitude, accepted range: -180..180. - * @param countryISO2 ISO 3166-2 country code. + * @param countryISO2 ISO 3166 country code, 2 characters. * @return Possibly empty, ordered list of mapcode information records, see {@link Mapcode}. * @throws IllegalArgumentException Thrown if latitude or longitude are out of range, or if the ISO code is invalid. */ @@ -162,14 +162,14 @@ public static List encodeRestrictToCountryISO2(@Nonnull final Point poi /** * Encode a lat/lon pair to a list of mapcodes, like {@link #encode(double, double)}. - * The result list is limited to those mapcodes that belong to the provided ISO 3166-3 country code. + * The result list is limited to those mapcodes that belong to the provided ISO 3166 country code, 3 characters. * For example, if you wish to restrict the list to Mexican mapcodes, use "MEX". This would * produce a result list of mapcodes with territories that start with "MEX" (note that * mapcode that starts with "MX-" are not returned in that case.) * * @param latDeg Latitude, accepted range: -90..90. * @param lonDeg Longitude, accepted range: -180..180. - * @param countryISO3 ISO 3166-3 country code. + * @param countryISO3 ISO 3166 country code, 3 characters. * @return Possibly empty, ordered list of mapcode information records, see {@link Mapcode}. * @throws IllegalArgumentException Thrown if latitude or longitude are out of range, or if the ISO code is invalid. */ @@ -178,8 +178,7 @@ public static List encodeRestrictToCountryISO3(final double latDeg, fin @Nonnull final String countryISO3) throws IllegalArgumentException { checkNonnull("countryISO3", countryISO3); - final Territory restrictToTerritory = Territory.fromCountryISO3(countryISO3); - return encode(latDeg, lonDeg, restrictToTerritory); + return encodeRestrictToCountryISO2(latDeg, lonDeg, Territory.getCountryISO2FromISO3(countryISO3)); } @Nonnull diff --git a/src/main/java/com/mapcode/Territory.java b/src/main/java/com/mapcode/Territory.java index cf11c3b..ddefc70 100644 --- a/src/main/java/com/mapcode/Territory.java +++ b/src/main/java/com/mapcode/Territory.java @@ -655,10 +655,10 @@ public Alphabet[] getAlphabets() { */ @Nonnull static Territory fromNumber(final int number) throws UnknownTerritoryException { - if ((number < 0) || (number >= codeList.size())) { + if ((number < 0) || (number >= CODE_LIST.size())) { throw new UnknownTerritoryException(number); } - return codeList.get(number); + return CODE_LIST.get(number); } /** @@ -704,47 +704,66 @@ public static Territory fromString(@Nonnull final String alphaCode, return createFromString(alphaCode, parentTerritory); } - // Keep a mapping from ISO3 to ISO2 codes. This map is used to make sure valid ISO3 codes are being used. - private static final Map MAP_ISO3_TO_ISO2; + /** + * Create a Territory object from a valid ISO2 country code. + * + * @param countryISO2 ISO 3166 country code, 2 characters. + * @return Territory object for the country. + * @throws IllegalArgumentException Thrown if the country code is not a valid ISO 3166 code, 2 characters. + */ + @Nonnull + public static Territory fromCountryISO2(@Nonnull final String countryISO2) { + return fromString(getCountryISO3FromISO2(countryISO2)); + } - static { - final String[] countries = Locale.getISOCountries(); - MAP_ISO3_TO_ISO2 = new HashMap(countries.length); - for (final String countryISO2 : countries) { - final String countryISO3 = new Locale("", countryISO2).getISO3Country(); - MAP_ISO3_TO_ISO2.put(countryISO3.toUpperCase(), countryISO2.toUpperCase()); + /** + * Return the ISO 3166 2 character country code for a ISO 3166 3 character code. + * + * @param countryISO3 ISO 3166 country code, 3 characters. + * @return ISO 3166 country code, 2 characters. + */ + @Nonnull + public static String getCountryISO2FromISO3(@Nonnull final String countryISO3) { + final String countryISO2 = MAP_ISO3_TO_ISO2.get(countryISO3.toUpperCase()); + if (countryISO2 == null) { + throw new IllegalArgumentException("Parameter " + countryISO3 + " must be a valid ISO 3166 country code, 3 characters"); } + return countryISO2; } /** - * Create a Territory object from a valid ISO2 country code. + * Return the ISO 3166 3 character country code for a ISO 3166 2 character code. * - * @param countryISO2 ISO 3166-2 country code. - * @return Territory object for the country. - * @throws IllegalArgumentException Thrown if the country code is not a valid ISO 3166-2 code. + * @param countryISO2 ISO 3166 country code, 2 characters. + * @return ISO 3166 country code, characters. */ @Nonnull - public static Territory fromCountryISO2(@Nonnull final String countryISO2) { + public static String getCountryISO3FromISO2(@Nonnull final String countryISO2) { + // Clipperton Island not recognized by Java - treat separately. + if ("CP".equalsIgnoreCase(countryISO2)) { + return "CPT"; + } + + // Otherwise, use Java locales. final Locale locale = new Locale("", countryISO2); try { - final String countryISO3 = locale.getISO3Country().toUpperCase(); - return fromString(countryISO3); + return locale.getISO3Country().toUpperCase(); } catch (final MissingResourceException ignored) { - throw new IllegalArgumentException("Parameter " + countryISO2 + " must be a valid ISO 3166-2 country code"); + throw new IllegalArgumentException("Parameter " + countryISO2 + " must be a valid ISO 3166 country code, 2 characters"); } } /** - * Create a Territory object from a valid ISO 3166-3 country code. + * Create a Territory object from a valid ISO 3166 country code, 3 characters. * - * @param countryISO3 ISO 3166-3 country code. + * @param countryISO3 ISO 3166 country code, 3 characters. * @return Territory object for the country. - * @throws IllegalArgumentException Thrown if the country code is not a valid ISO 3166-3 code. + * @throws IllegalArgumentException Thrown if the country code is not a valid ISO 3166 code, 3 characters. */ @Nonnull public static Territory fromCountryISO3(@Nonnull final String countryISO3) { if (!MAP_ISO3_TO_ISO2.containsKey(countryISO3.toUpperCase())) { - throw new IllegalArgumentException("Parameter " + countryISO3 + " must be a valid ISO 3166-3 country code"); + throw new IllegalArgumentException("Parameter " + countryISO3 + " must be a valid ISO 3166 country code, 3 characters"); } return fromString(countryISO3); } @@ -798,7 +817,7 @@ public String toAlphaCode(@Nonnull final AlphaCodeFormat format, @Nullable final if (index != -1) { assert name().length() > (index + 1); final String shortName = name().substring(index + 1); - if ((format == AlphaCodeFormat.MINIMAL) || (nameMap.get(shortName).size() == 1)) { + if ((format == AlphaCodeFormat.MINIMAL) || (NAME_MAP.get(shortName).size() == 1)) { result = shortName; } } @@ -833,7 +852,7 @@ public boolean isSubdivision() { * @return True if this territory contains other territory subdivisions. */ public boolean hasSubdivisions() { - return parentList.contains(this); + return PARENT_LIST.contains(this); } /** @@ -880,21 +899,36 @@ public boolean hasSubdivisions() { this.fullNameAliases = (fullNameAliases == null) ? new String[]{} : fullNameAliases; } + // Keep a mapping from ISO3 to ISO2 codes. This map is used to make sure valid ISO3 codes are being used. @Nonnull - private static final List codeList; + private static final Map MAP_ISO3_TO_ISO2; @Nonnull - private static final Map> nameMap; + private static final List CODE_LIST; @Nonnull - private static final List parentList; + private static final Map> NAME_MAP; + @Nonnull + private static final List PARENT_LIST; + + static { + final String[] countries = Locale.getISOCountries(); + MAP_ISO3_TO_ISO2 = new HashMap(countries.length); + for (final String countryISO2 : countries) { + final String countryISO3 = new Locale("", countryISO2).getISO3Country(); + MAP_ISO3_TO_ISO2.put(countryISO3.toUpperCase(), countryISO2.toUpperCase()); + } + + // Add Clipperton Island (not recognized by Java). + MAP_ISO3_TO_ISO2.put("CPT", "CP"); + } /** * Static checking of the static data structures. */ static { final String errorPrefix = "Initializing error: "; - codeList = new ArrayList(); - nameMap = new HashMap>(); - parentList = new ArrayList(); + CODE_LIST = new ArrayList(); + NAME_MAP = new HashMap>(); + PARENT_LIST = new ArrayList(); int min = Integer.MAX_VALUE; int max = Integer.MIN_VALUE; final Set territoryNumbers = new HashSet(); @@ -915,13 +949,13 @@ public boolean hasSubdivisions() { } territoryNumbers.add(territory.getNumber()); - final int initialCodeListSize = codeList.size(); + final int initialCodeListSize = CODE_LIST.size(); for (int i = initialCodeListSize; i <= territory.number; i++) { - codeList.add(null); + CODE_LIST.add(null); } - codeList.set(territory.number, territory); - if ((territory.parentTerritory != null) && !parentList.contains(territory.parentTerritory)) { - parentList.add(territory.parentTerritory); + CODE_LIST.set(territory.number, territory); + if ((territory.parentTerritory != null) && !PARENT_LIST.contains(territory.parentTerritory)) { + PARENT_LIST.add(territory.parentTerritory); } // Check if territory name is unique. @@ -985,7 +1019,7 @@ private static Territory createFromString(@Nonnull final String alphaCode, alphaCode.trim().replace('_', '-')).toUpperCase(); // Try as alpha code. - final List territories = nameMap.get(trimmed); + final List territories = NAME_MAP.get(trimmed); if (territories != null) { if (parentTerritory == null) { return territories.get(0); @@ -1065,8 +1099,8 @@ private static void addNameWithSeperatorVariants(@Nonnull final String name, @No } private static void addName(@Nonnull final String name, @Nonnull final Territory territory) { - if (nameMap.containsKey(name)) { - final List territories = nameMap.get(name); + if (NAME_MAP.containsKey(name)) { + final List territories = NAME_MAP.get(name); // Add child territories in the order the parents are declared. // This results in consistent decoding of ambiguous territory names. @@ -1098,7 +1132,7 @@ private static void addName(@Nonnull final String name, @Nonnull final Territory } else { final ArrayList arrayList = new ArrayList(); arrayList.add(territory); - nameMap.put(name, arrayList); + NAME_MAP.put(name, arrayList); } } } diff --git a/src/test/java/com/mapcode/EncoderTest.java b/src/test/java/com/mapcode/EncoderTest.java index 85c3158..c3af740 100644 --- a/src/test/java/com/mapcode/EncoderTest.java +++ b/src/test/java/com/mapcode/EncoderTest.java @@ -22,8 +22,7 @@ import java.util.List; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; +import static org.junit.Assert.*; @SuppressWarnings({"OverlyBroadThrowsClause", "ProhibitedExceptionDeclared", "ValueOfIncrementOrDecrementUsed", "MagicNumber"}) public class EncoderTest { @@ -274,51 +273,56 @@ public void testEncodeCiudadJuarez() { } @Test - public void testEncodeRestrictToCountryISO2CountryWithSubdivision() { - LOG.info("testEncodeRestrictToCountryISO2CountryWithSubdivision"); + public void testEncodeRestrictToCountryISOCountryWithSubdivision() { + LOG.info("testEncodeRestrictToCountryISOCountryWithSubdivision"); final List mapcodesMX = MapcodeCodec.encodeRestrictToCountryISO2(CIUDAD_JUAREZ, "MX"); + final List mapcodesMEX = MapcodeCodec.encodeRestrictToCountryISO3(CIUDAD_JUAREZ, "MEX"); assertEquals(7, mapcodesMX.size()); + assertEquals(7, mapcodesMEX.size()); assertEquals("MX-CHH 5S.0G", mapcodesMX.get(0).toString()); + assertEquals("MX-CHH 5S.0G", mapcodesMEX.get(0).toString()); final List mapcodesUS = MapcodeCodec.encodeRestrictToCountryISO2(CIUDAD_JUAREZ, "us"); + final List mapcodesUSA = MapcodeCodec.encodeRestrictToCountryISO3(CIUDAD_JUAREZ, "usa"); assertEquals(5, mapcodesUS.size()); + assertEquals(5, mapcodesUSA.size()); assertEquals("US-NM T1DZ.338", mapcodesUS.get(0).toString()); + assertEquals("US-NM T1DZ.338", mapcodesUSA.get(0).toString()); } @Test - public void testEncodeRestrictToCountryISO2CountryWithoutSubdivision() { + public void testEncodeRestrictToCountryISOCountryWithoutSubdivision() { LOG.info("testEncodeRestrictToCountryISO2CountryWithoutSubdivision"); final List mapcodesNL = MapcodeCodec.encodeRestrictToCountryISO2(VAALS, "NL"); + final List mapcodesNLD = MapcodeCodec.encodeRestrictToCountryISO3(VAALS, "NLD"); assertEquals(2, mapcodesNL.size()); + assertEquals(2, mapcodesNLD.size()); assertEquals("NLD ZNV.W78", mapcodesNL.get(0).toString()); + assertEquals("NLD ZNV.W78", mapcodesNLD.get(0).toString()); final List mapcodesBE = MapcodeCodec.encodeRestrictToCountryISO2(VAALS, "be"); + final List mapcodesBEL = MapcodeCodec.encodeRestrictToCountryISO3(VAALS, "bel"); assertEquals(2, mapcodesBE.size()); + assertEquals(2, mapcodesBEL.size()); assertEquals("BEL DRQ.PNK", mapcodesBE.get(0).toString()); + assertEquals("BEL DRQ.PNK", mapcodesBEL.get(0).toString()); } @Test - public void testEncodeRestrictToCountryISO3WithSubdivision() { - LOG.info("testEncodeRestrictToCountryISO3WithSubdivision"); - final Point ciudadJuarez = Point.fromDeg(31.7, -106.5); - final List mapcodesMEX = MapcodeCodec.encodeRestrictToCountryISO3(CIUDAD_JUAREZ, "MEX"); - assertEquals(2, mapcodesMEX.size()); - assertEquals("MEX 4CMT.DLX", mapcodesMEX.get(0).toString()); - - final List mapcodesUSA = MapcodeCodec.encodeRestrictToCountryISO3(CIUDAD_JUAREZ, "usa"); - assertEquals(1, mapcodesUSA.size()); - assertEquals("USA NG4F.K745", mapcodesUSA.get(0).toString()); - } - - @Test - public void testEncodeRestrictToCountryISO3CountryWithoutSubdivision() { - LOG.info("testEncodeRestrictToCountryISO3CountryWithoutSubdivision"); - final List mapcodesNLD = MapcodeCodec.encodeRestrictToCountryISO3(VAALS, "NLD"); - assertEquals(2, mapcodesNLD.size()); - assertEquals("NLD ZNV.W78", mapcodesNLD.get(0).toString()); - - final List mapcodesBEL = MapcodeCodec.encodeRestrictToCountryISO3(VAALS, "bel"); - assertEquals(2, mapcodesBEL.size()); - assertEquals("BEL DRQ.PNK", mapcodesBEL.get(0).toString()); + public void testEncodeRestrictToCountryISOForAll() { + LOG.info("testEncodeRestrictToCountryISOForAll"); + for (final Territory territory : Territory.values()) { + if (!"AAA".equals(territory.toString())) { + final String countryISO3; + if (territory.getParentTerritory() == null) { + countryISO3 = territory.toString(); + } else { + countryISO3 = territory.getParentTerritory().toString(); + } + final String countryISO2 = Territory.getCountryISO2FromISO3(countryISO3); + assertNotNull(MapcodeCodec.encodeRestrictToCountryISO2(CIUDAD_JUAREZ, countryISO2)); + assertNotNull(MapcodeCodec.encodeRestrictToCountryISO3(CIUDAD_JUAREZ, countryISO3)); + } + } } } diff --git a/src/test/java/com/mapcode/TerritoryTest.java b/src/test/java/com/mapcode/TerritoryTest.java index c112c2c..4badc2c 100644 --- a/src/test/java/com/mapcode/TerritoryTest.java +++ b/src/test/java/com/mapcode/TerritoryTest.java @@ -196,54 +196,89 @@ public void testFromNumberError2() { } @Test(expected = IllegalArgumentException.class) - public void testFromStringCountryIso2Error1() { - LOG.info("testFromStringCountryIso2Error1"); + public void testFromStringCountryISO2Error1() { + LOG.info("testFromStringCountryISO2Error1"); Territory.fromCountryISO2("US-IN"); } @Test(expected = IllegalArgumentException.class) - public void testFromStringCountryIso2Error2() { - LOG.info("testFromStringCountryIso2Error2"); + public void testFromStringCountryISO2Error2() { + LOG.info("testFromStringCountryISO2Error2"); Territory.fromCountryISO2("USA"); } @Test(expected = IllegalArgumentException.class) - public void testFromStringCountryIso2Error3() { - LOG.info("testFromStringCountryIso2Error3"); + public void testFromStringCountryISO2Error3() { + LOG.info("testFromStringCountryISO2Error3"); Territory.fromCountryISO2(""); } @Test - public void testFromStringCountryIso2OK() { - LOG.info("testFromStringCountryIso2OK"); + public void testFromStringCountryISO2OK() { + LOG.info("testFromStringCountryISO2OK"); assertEquals("NLD", Territory.fromCountryISO2("NL").toString()); assertEquals("BRA", Territory.fromCountryISO2("br").toString()); assertEquals("USA", Territory.fromCountryISO2("Us").toString()); } @Test(expected = IllegalArgumentException.class) - public void testFromStringCountryIso3Error1() { - LOG.info("testFromStringCountryIso3Error1"); + public void testFromStringCountryISO3Error1() { + LOG.info("testFromStringCountryISO3Error1"); Territory.fromCountryISO3("US-IN"); } @Test(expected = IllegalArgumentException.class) - public void testFromStringCountryIso3Error2() { - LOG.info("testFromStringCountryIso3Error2"); + public void testFromStringCountryISO3Error2() { + LOG.info("testFromStringCountryISO3Error2"); Territory.fromCountryISO3("US"); } @Test(expected = IllegalArgumentException.class) - public void testFromStringCountryIso3Error3() { - LOG.info("testFromStringCountryIso3Error3"); + public void testFromStringCountryISO3Error3() { + LOG.info("testFromStringCountryISO3Error3"); Territory.fromCountryISO3(""); } + @Test(expected = IllegalArgumentException.class) + public void testFromStringCountryISO3Error4() { + LOG.info("testFromStringCountryISO3Error4"); + Territory.fromCountryISO3("AAA"); + } + @Test - public void testFromStringCountryIso3OK() { - LOG.info("testFromStringCountryIso3OK"); + public void testFromStringCountryISO3OK() { + LOG.info("testFromStringCountryISO3OK"); assertEquals("NLD", Territory.fromCountryISO3("NLD").toString()); assertEquals("BRA", Territory.fromCountryISO3("bra").toString()); assertEquals("USA", Territory.fromCountryISO3("Usa").toString()); } + + @Test + public void testGetCountryISO3FromISO2() { + LOG.info("testGetCountryISO3FromISO2"); + assertEquals("NLD", Territory.getCountryISO3FromISO2("NL")); + assertEquals("BRA", Territory.getCountryISO3FromISO2("br")); + assertEquals("USA", Territory.getCountryISO3FromISO2("Us")); + } + + @Test(expected = IllegalArgumentException.class) + public void testGetCountryISO3FromISO2Error() { + LOG.info("testGetCountryISO3FromISO2Error"); + Territory.getCountryISO3FromISO2("NLD"); + } + + @Test + public void testGetCountryISO2FromISO3() { + LOG.info("testGetCountryISO2FromISO3"); + assertEquals("NL", Territory.getCountryISO2FromISO3("NLD")); + assertEquals("BR", Territory.getCountryISO2FromISO3("bra")); + assertEquals("US", Territory.getCountryISO2FromISO3("Usa")); + } + + @Test(expected = IllegalArgumentException.class) + public void testGetCountryISO2FromISO3Error() { + LOG.info("testGetCountryISO2FromISO3Error"); + Territory.getCountryISO2FromISO3("NL"); + } + } From 3f93164fe78590244bff3adc5c86be709222b6c9 Mon Sep 17 00:00:00 2001 From: Rijn Buve Date: Thu, 3 May 2018 16:10:04 +0200 Subject: [PATCH 7/7] Removes empty else --- src/main/java/com/mapcode/MapcodeCodec.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/mapcode/MapcodeCodec.java b/src/main/java/com/mapcode/MapcodeCodec.java index c6c16cf..30b546e 100644 --- a/src/main/java/com/mapcode/MapcodeCodec.java +++ b/src/main/java/com/mapcode/MapcodeCodec.java @@ -144,9 +144,6 @@ public static List encodeRestrictToCountryISO2(final double latDeg, fin // Otherwise, if it's the correct country ISO 3 code, it's also OK. filtered.add(mapcode); - } else { - - // Nothing. } } return filtered;