GeoHash { public static String adjacentHash(String hash, Direction direction) { checkHash(hash); Preconditions.checkArgument(hash.length() > 0, "adjacent has no meaning for a zero length hash that covers the whole world"); String adjacentHashAtBorder = adjacentHashAtBorder(hash, direction); if (adjacentHashAtBorder != null) return adjacentHashAtBorder; String source = hash.toLowerCase(); char lastChar = source.charAt(source.length() - 1); Parity parity = (source.length() % 2 == 0) ? Parity.EVEN : Parity.ODD; String base = source.substring(0, source.length() - 1); if (BORDERS.get(direction).get(parity).indexOf(lastChar) != -1) base = adjacentHash(base, direction); return base + BASE32.charAt(NEIGHBOURS.get(direction).get(parity).indexOf(lastChar)); } private  GeoHash(); static String adjacentHash(String hash, Direction direction); static String right(String hash); static String left(String hash); static String top(String hash); static String bottom(String hash); static String adjacentHash(String hash, Direction direction, int steps); static List<String> neighbours(String hash); static String encodeHash(double latitude, double longitude); static String encodeHash(LatLong p, int length); static String encodeHash(LatLong p); static String encodeHash(double latitude, double longitude, int length); static LatLong decodeHash(String geohash); static int hashLengthToCoverBoundingBox(double topLeftLat, double topLeftLon,
            double bottomRightLat, double bottomRightLon); static boolean hashContains(String hash, double lat, double lon); static Coverage coverBoundingBox(double topLeftLat, final double topLeftLon,
            final double bottomRightLat, final double bottomRightLon); static Coverage coverBoundingBoxMaxHashes(double topLeftLat, final double topLeftLon,
            final double bottomRightLat, final double bottomRightLon, int maxHashes); static Coverage coverBoundingBox(double topLeftLat, final double topLeftLon,
            final double bottomRightLat, final double bottomRightLon, final int length); static double heightDegrees(int n); static double widthDegrees(int n); static String gridAsString(String hash, int size, Set<String> highlightThese); static String gridAsString(String hash, int fromRight, int fromBottom, int toRight,
            int toBottom); static String gridAsString(String hash, int fromRight, int fromBottom, int toRight,
            int toBottom, Set<String> highlightThese); static final int MAX_HASH_LENGTH; static final int DEFAULT_MAX_HASHES; }
@Test(expected = IllegalArgumentException.class) public void testAdjacentHashThrowsExceptionGivenNullHash() { GeoHash.adjacentHash(null, Direction.RIGHT); }
@Test(expected = IllegalArgumentException.class) public void testAdjacentHashThrowsExceptionGivenBlankHash() { GeoHash.adjacentHash("", Direction.RIGHT); }
@Test public void testAdjacentBottom() { assertEquals("u0zz", adjacentHash("u1pb", Direction.BOTTOM)); }
@Test public void testAdjacentTop() { assertEquals("u1pc", adjacentHash("u1pb", Direction.TOP)); }
@Test public void testAdjacentLeft() { assertEquals("u1p8", adjacentHash("u1pb", Direction.LEFT)); }
@Test public void testAdjacentRight() { assertEquals("u300", adjacentHash("u1pb", Direction.RIGHT)); }
@Test public void testRightNeighbourCloseTo180Longitude() { assertEquals("2", GeoHash.adjacentHash("r", Direction.RIGHT)); }
@Test public void testLeftNeighbourCloseToMinus180Longitude() { assertEquals("r", GeoHash.adjacentHash("2", Direction.LEFT)); }