diff --git a/src/main/java/com/esri/core/geometry/Geohash.java b/src/main/java/com/esri/core/geometry/Geohash.java index aa348357..20f8aebf 100644 --- a/src/main/java/com/esri/core/geometry/Geohash.java +++ b/src/main/java/com/esri/core/geometry/Geohash.java @@ -91,6 +91,7 @@ public static String toGeohash(Point2D pt, int characterLength) { double[] lonRange = new double[] { -180, 180 }; double lat = pt.x; double lon = pt.y; + String latBitStr = convertToBinary(lat, latRange, precision); String lonBitStr = convertToBinary(lon, lonRange, precision); @@ -103,7 +104,13 @@ public static String toGeohash(Point2D pt, int characterLength) { return binaryToBase32(interwovenBin.toString()); } - static String binaryToBase32(String binStr) { + /** + * Computes the base32 value of the binary string given + * @param binStr Binary string with "0" || "1" that is to be converted to a base32 string + * @return base32 string of the binStr in chunks of 5 binary digits + */ + + public static String binaryToBase32(String binStr) { StringBuilder base32Str = new StringBuilder(); for (int i = 0; i < binStr.length(); i += 5) { String chunk = binStr.substring(i, i + 5); @@ -113,7 +120,19 @@ static String binaryToBase32(String binStr) { return base32Str.toString(); } - static String convertToBinary(double value, double[] range, int precision) { + /** + * Converts the value given to a binary string with the given precision and range + * @param value The value to be converted to a binString + * @param range The range at which the value is to be compared with + * @param precision The Precision (number of bits) that the binary string needs + * @return A binary string representation of the value with the given range and precision + */ + + public static String convertToBinary( + double value, + double[] range, + int precision + ) { StringBuilder binString = new StringBuilder(); for (int i = 0; i < precision; i++) { double mid = (range[0] + range[1]) / 2; diff --git a/src/test/java/com/esri/core/geometry/TestGeohash.java b/src/test/java/com/esri/core/geometry/TestGeohash.java index a853405b..6e11c7a4 100644 --- a/src/test/java/com/esri/core/geometry/TestGeohash.java +++ b/src/test/java/com/esri/core/geometry/TestGeohash.java @@ -5,71 +5,96 @@ import org.junit.Test; public class TestGeohash { - - /** - * Check if the center of the new envelope is well placed - */ - @Test - public void testGeohashToEnvelopeWellCentered(){ - double delta = 0.00000001; - - String geohash1 = "ghgh"; - - double lat1 = 72.50976563; - double lon1 = -40.60546875; - Envelope2D env1 = Geohash.geohashToEnvelope(geohash1); - double centerX1 = (env1.xmax + env1.xmin)*0.5; - double centerY1 = (env1.ymax + env1.ymin)*0.5; - - assertEquals(lon1, centerX1, delta); - assertEquals(lat1, centerY1, delta); - - String geohash2 = "p"; - - double lat2 = -67.50000000; - double lon2 = 157.50000000; - Envelope2D env2 = Geohash.geohashToEnvelope(geohash2); - double centerX2 = (env2.xmax + env2.xmin)*0.5; - double centerY2 = (env2.ymax + env2.ymin)*0.5; - - assertEquals(lon2, centerX2, delta); - assertEquals(lat2, centerY2, delta); - } - - /** - * Check if the dimension of the new envelope is correct for low precision - */ - @Test - public void testGeohashToEnvelopeGoodDimensions(){ - double delta = 0.00000001; - - double latDiff = 180/4; - double lonDiff = 360/8; - - String geohash = "h"; - - Envelope2D env = Geohash.geohashToEnvelope(geohash); - - assertEquals(lonDiff, env.xmax-env.xmin, delta); - assertEquals(latDiff, env.ymax-env.ymin, delta); - } - - /** - * Check if the dimension of the new envelope is correct for higher precision - */ - @Test - public void testGeohashToEnvelopeGoodDimensions2(){ - double delta = 0.00000001; - - double latDiff = 180.0/32768; - double lonDiff = 360.0/32768; - - String geohash = "hggggg"; - - Envelope2D env = Geohash.geohashToEnvelope(geohash); - - assertEquals(lonDiff, env.xmax-env.xmin, delta); - assertEquals(latDiff, env.ymax-env.ymin, delta); - } + /** + * Check if the center of the new envelope is well placed + */ + @Test + public void testGeohashToEnvelopeWellCentered() { + double delta = 0.00000001; + + String geohash1 = "ghgh"; + + double lat1 = 72.50976563; + double lon1 = -40.60546875; + Envelope2D env1 = Geohash.geohashToEnvelope(geohash1); + double centerX1 = (env1.xmax + env1.xmin) * 0.5; + double centerY1 = (env1.ymax + env1.ymin) * 0.5; + + assertEquals(lon1, centerX1, delta); + assertEquals(lat1, centerY1, delta); + + String geohash2 = "p"; + + double lat2 = -67.50000000; + double lon2 = 157.50000000; + Envelope2D env2 = Geohash.geohashToEnvelope(geohash2); + double centerX2 = (env2.xmax + env2.xmin) * 0.5; + double centerY2 = (env2.ymax + env2.ymin) * 0.5; + + assertEquals(lon2, centerX2, delta); + assertEquals(lat2, centerY2, delta); + } + + /** + * Check if the dimension of the new envelope is correct for low precision + */ + @Test + public void testGeohashToEnvelopeGoodDimensions() { + double delta = 0.00000001; + + double latDiff = 180 / 4; + double lonDiff = 360 / 8; + + String geohash = "h"; + + Envelope2D env = Geohash.geohashToEnvelope(geohash); + + assertEquals(lonDiff, env.xmax - env.xmin, delta); + assertEquals(latDiff, env.ymax - env.ymin, delta); + } + + /** + * Check if the dimension of the new envelope is correct for higher precision + */ + @Test + public void testGeohashToEnvelopeGoodDimensions2() { + double delta = 0.00000001; + + double latDiff = 180.0 / 32768; + double lonDiff = 360.0 / 32768; + + String geohash = "hggggg"; + + Envelope2D env = Geohash.geohashToEnvelope(geohash); + + assertEquals(lonDiff, env.xmax - env.xmin, delta); + assertEquals(latDiff, env.ymax - env.ymin, delta); + } + + /** + * Check if BinaryToBase32 work as intended with a normal binary string + */ + @Test + public void testBinaryToBase32() { + String testStr = "011011111111011"; + assertEquals("ezv", Geohash.binaryToBase32(testStr)); + } + + @Test + public void testConvertToBinary() { + double lat = 40.7128; + double lon = -74.0060; + assertEquals( + "1011100111", + Geohash.convertToBinary(lat, new double[] { -90, 90 }, 10) + ); + assertEquals( + "0100101101", + Geohash.convertToBinary(lon, new double[] { -180, 180 }, 10) + ); + } + + @Test + public void testToGeoHash() {} }