# `gno.land/p/moul/x/daily/geohash/v0` **Geohash: a latitude/longitude pair as a short base32 string** with `Encode`, `Decode`, `DecodeBox`, `Neighbor`, `Neighbors`, `Box` and `Direction`. ```go import "gno.land/p/moul/x/daily/geohash/v0" h, _ := geohash.Encode(42.6, -5.6, 5) // "ezs42" b, _ := geohash.DecodeBox(h) // the cell, not a point n, _ := geohash.Neighbor(h, geohash.North) // "ezs48" ``` **A geohash is a prefix code, and that is the whole point of storing one.** Every character narrows the box by five bits, so a prefix is a valid geohash of the same place, zoomed out, and two places that share a long prefix are close together. An avl tree keyed by geohash therefore answers "everything near here" with a range scan over a prefix, storing no geometry and computing no distance. **A hash names a box, never a point.** `Decode` returns the centre because the centre is the best single point a box can give; `DecodeBox` returns the box itself with `HeightDeg` and `WidthDeg`, which is what you want before claiming two coordinates are "the same place". **Longitude wraps and latitude does not.** The cell east of `z` is `b`: the antimeridian is a line on a map, not an edge of the world. The classic border/neighbour lookup-table implementations report nothing there, which is a property of the tables rather than of the globe, so this package differs from them on purpose and the tests pin both behaviours. A step past a pole is genuinely impossible and returns `ErrNoNeighbor`; `Neighbors` returns a short list there rather than padding it with empty strings a caller has to filter. **Deterministic by construction.** Both world ranges are powers of two over powers of two, so every box bound is exactly representable in a float64, the one-cell step `Neighbor` takes lands on another centre rather than near one, and nothing is rounded or iterated out of a map. Two identical calls cannot disagree, which is the bar a `Render` has to clear. The alphabet is the standard one and drops `a`, `i`, `l` and `o`, so a hash survives being read aloud. Anything outside it is refused rather than skipped, and so is a hash longer than `MaxPrecision` (12 characters, 60 bits). Not included: distances, `Encode` from a radius, or the 3x3 prefix search a proximity query would build on top. The box and its neighbours are the primitives those need. **Live demo:** [`r/moul/x/daily/geohashdemo`](https://github.com/moul/gno-contracts/tree/main/r/moul/x/daily/geohashdemo) · render it at [`/r/moul/x/daily/geohashdemo/v0`](https://gno.land/r/moul/x/daily/geohashdemo/v0). --- Part of **[moul/gno-contracts](https://github.com/moul/gno-contracts)** — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage. > 🧪 **Highly experimental — potentially vibe-coded.** Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: [DISCLAIMER](https://github.com/moul/gno-contracts/blob/main/DISCLAIMER.md).