-
Notifications
You must be signed in to change notification settings - Fork 269
Should GeoHashQuery include endValue or not? #155
Description
Hello! Thanks for nice library.
I have a question about the following methods from GeoHashQuery.java:
public static GeoHashQuery queryForGeoHash(GeoHash geohash, int bits) {
String hash = geohash.getGeoHashString();
int precision = (int)Math.ceil((double)bits/Base32Utils.BITS_PER_BASE32_CHAR);
if (hash.length() < precision) {
return new GeoHashQuery(hash, hash+"~");
}
hash = hash.substring(0, precision);
String base = hash.substring(0, hash.length() - 1);
int lastValue = Base32Utils.base32CharToValue(hash.charAt(hash.length() - 1));
int significantBits = bits - (base.length() * Base32Utils.BITS_PER_BASE32_CHAR);
int unusedBits = Base32Utils.BITS_PER_BASE32_CHAR - significantBits;
// delete unused bits
int startValue = (lastValue >> unusedBits) << unusedBits;
int endValue = startValue + (1 << unusedBits);
String startHash = base + Base32Utils.valueToBase32Char(startValue);
String endHash;
if (endValue > 31) {
endHash = base + "~";
} else {
endHash = base + Base32Utils.valueToBase32Char(endValue);
}
return new GeoHashQuery(startHash, endHash);
}
public static Set<GeoHashQuery> queriesAtLocation(GeoLocation location, double radius) {
...
}I don't fully understand this code, but I have an impression that endValue from queryForGeoHash is not supposed to be included into the query. I mean that the query should be interpreted as startValue <= geohash < endValue but in fact when the query is executed it's inclusive: startValue <= geohash <= endValue.
To fix that we could change the line:
int endValue = startValue + (1 << unusedBits);into:
int endValue = startValue + (1 << unusedBits) - 1;To illustrate this, look at my results with center in Caracas, Venezuela and radius=350km (the selected area is what's included into the query):
- Original version:
- My fixed version:
Note: actually I'm using a kotlin version of the code from here: https://github.com/imperiumlabs/GeoFirestore-Android/blob/34b935c534c583520a706c3388c57962122846bf/geofirestore/src/main/java/org/imperiumlabs/geofirestore/core/GeoHashQuery.kt
but the logic is exactly the same, so I think that the code in this repo is (or is closer to) the original.

