I am trying to write a geohashing function that takes a latitude/longitude pair and returns its base2 (geohash once converted to base32) string. However, this is giving me incorrect results. What is wrong with it?
public static void main(String[] args) {
float latitude = 45.512794f;
float longitude = -122.679565f;
System.out.println(geoHash(latitude, longitude));
}
private static String geoHash(float lat, float lng) {
float lowLat = -90.0f;
float highLat = 90.0f;
float lowLng = -180.0f;
float highLng = 180.0f;
return geoHash(lowLng, highLng, lowLat, highLat, lat, lng, "");
}
private static String geoHash(float lowLng, float highLng, float lowLat, float highLat, float lat, float lng, String hash) {
if (hash.length() == 30)
return hash;
float midLat = (lowLat + highLat) / 2;
float midLng = (lowLng + highLng) / 2;
if (lng <= midLng && lat <= midLat) {
return geoHash(lowLng, midLng, lowLat, midLat, lat, lng, hash + "00");
} else if (lng > midLng && lat <= midLat) {
return geoHash(midLng, highLng, lowLat, midLat, lat, lng, hash + "01");
} else if (lng <= midLng && lat > midLat) {
return geoHash(lowLng, midLng, midLat, highLat, lat, lng, hash + "10");
} else {
return geoHash(midLng, highLng, midLat, highLat, lat, lng, hash + "11");
}
}
I am geting 101001000100000011011010100011 which converts to kh0dl3 base32, and I am expecting 11000001000000011110101110110 which converts to c20fbm.
what i don't understand is the first two pairs of bits are the same in the result that I get from my function (1010), meaning it hit the same quadrant twice. In the actual converted geohash I found online they are two different quadrants (1100).
Edit: Upon further debugging, and with the selected answer's help, I found that I was decoding the base 32 incorrectly (I was using 4 bits, instead of 5). I also should have used the table found at https://en.wikipedia.org/wiki/Geohash. There is also an error in my code, fixed below:
private static String geoHash(float lowLng, float highLng, float lowLat, float highLat, float lat, float lng, String hash) {
if (hash.length() == 30)
return hash;
float midLng = (lowLng + highLng) / 2.0f;
float midLat = (lowLat + highLat) / 2.0f;
if (lng <= midLng && lat <= midLat) {
return geoHash(lowLng, midLng, lowLat, midLat, lat, lng, hash + "00");
} else if (lng <= midLng && lat > midLat) {
return geoHash(lowLng, midLng, midLat, highLat, lat, lng, hash + "01");
} else if (lng > midLng && lat <= midLat) {
return geoHash(midLng, highLng, lowLat, midLat, lat, lng, hash + "10");
} else {
return geoHash(midLng, highLng, midLat, highLat, lat, lng, hash + "11");
}
}