GeoHash { public static int hashLengthToCoverBoundingBox(double topLeftLat, double topLeftLon, double bottomRightLat, double bottomRightLon) { boolean isEven = true; double minLat = -90.0, maxLat = 90; double minLon = -180.0, maxLon = 180.0; for (int bits = 0; bits < MAX_HASH_LENGTH * 5; bits++) { if (isEven) { double mid = (minLon + maxLon) / 2; if (topLeftLon >= mid) { if (bottomRightLon < mid) return bits / 5; minLon = mid; } else { if (bottomRightLon >= mid) return bits / 5; maxLon = mid; } } else { double mid = (minLat + maxLat) / 2; if (topLeftLat >= mid) { if (bottomRightLat < mid) return bits / 5; minLat = mid; } else { if (bottomRightLat >= mid) return bits / 5; maxLat = mid; } } isEven = !isEven; } return MAX_HASH_LENGTH; } 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 public void testGeoHashLengthAcrossLongitude180() { assertEquals(0, hashLengthToCoverBoundingBox(71.676351, 178.389963, 70.633291, -177.116629)); }
@Test public void testGeoHashLengthAcrossEcuador() { assertEquals(0, hashLengthToCoverBoundingBox(2.935289, -82.751538, -5.623710, -74.753492)); }
@Test public void testGeoHashLengthAcrossSouthPole() { assertEquals(0, hashLengthToCoverBoundingBox(-80, 10, 80, 20)); }
@Test public void testHashLengthToEncloseBoundingBoxReturns0IfBoxTooBig() { assertEquals(0, GeoHash.hashLengthToCoverBoundingBox(80, -170, -80, 170)); }