kungfoo / geohash-java

Implementation of GeoHashes in java. We try to be/stay compliant to the spec, as far as possible.
Other
981 stars 310 forks source link

GeoHash is not divisible by 5 #49

Closed loridigia closed 2 years ago

loridigia commented 4 years ago

Hi, first of all, there is a little grammatical error in GeoHash class: " IllegalStateException("precision of GeoHash is not divisble by 5: " + this); ".

But my question is: if i have a bounding box and i want to know all geohashes, in base32, where it fits how should i do? Because i always get GeoHash : Cannot convert a geohash to base32 if the precision is not a multiple of 5. Is there a workaround? Thanks

kungfoo commented 3 years ago

When you create all the hashes covering a certain bounding box, it may be the case that they have a bit precision that is not a multiple of 5 since the code tries to find the smallest hashes covering said bounding boxes. If you need them in base32 to query against something, you can however truncate the hashes and still use them to query. You will get results from the larger (expanded) bounding box however:

// script.groovy
@Grab(group='ch.hsr', module='geohash', version='1.4.0')

import ch.hsr.geohash.queries.GeoHashBoundingBoxQuery
import ch.hsr.geohash.*

bbox = new BoundingBox(8.87686, 9.017861, -2.323223, -1.7868678)
query = new GeoHashBoundingBoxQuery(bbox)

result = []
// truncate hashes to 5 characters precision
println("Non-truncated hashes (potentially non-multiples of 5)")
query.searchHashes.forEach { println(it) }
query.searchHashes.forEach { hash ->
    truncatedBits = (int)(hash.significantBits() / 5) * 5
    result << GeoHash.fromLongValue(hash.longValue(), truncatedBits)
}

println("Truncated hashes (multiples of 5 precision)")
result.forEach { println(it) }

Run with groovy script.groovy to see the result.