geokit/geohash

Niemeyer geohash encoding and decoding.

A geohash is a short alphanumeric string identifying a rectangular cell on the Earth’s surface. Longer hashes pinpoint smaller cells. The alphabet is base32 (10 digits + 22 letters, omitting a, i, l, o to avoid visual ambiguity); each character contributes 5 bits, alternating between longitude and latitude.

See http://geohash.org/ for the original specification.

Types

Compass direction used by neighbor.

pub type Direction {
  North
  South
  East
  West
  NorthEast
  NorthWest
  SouthEast
  SouthWest
}

Constructors

  • North
  • South
  • East
  • West
  • NorthEast
  • NorthWest
  • SouthEast
  • SouthWest

Errors returned by encode, decode, decode_bounds, and neighbor.

pub type GeohashError {
  PrecisionOutOfRange(precision: Int)
  EmptyHash
  InvalidCharacter(char: String, position: Int)
}

Constructors

  • PrecisionOutOfRange(precision: Int)

    encode was called with precision outside the supported range [1, 12].

  • EmptyHash

    decode was called with an empty string.

  • InvalidCharacter(char: String, position: Int)

    A character outside the base32 alphabet appeared in a hash passed to decode.

The eight neighbours of a geohash cell. See neighbors.

pub type Neighbors {
  Neighbors(
    north: String,
    south: String,
    east: String,
    west: String,
    north_east: String,
    north_west: String,
    south_east: String,
    south_west: String,
  )
}

Constructors

  • Neighbors(
      north: String,
      south: String,
      east: String,
      west: String,
      north_east: String,
      north_west: String,
      south_east: String,
      south_west: String,
    )

Values

pub fn decode(
  hash hash: String,
) -> Result(latlng.LatLng, GeohashError)

Decode a geohash to the centre of the cell it identifies.

The input is case-insensitive: upper-case characters are folded to lower-case before lookup.

import geokit/geohash

let assert Ok(centre) = geohash.decode("xn76urx4")
// centre ≈ (35.6812, 139.7671)
pub fn decode_bounds(
  hash hash: String,
) -> Result(#(latlng.LatLng, latlng.LatLng), GeohashError)

Decode a geohash to the south-west and north-east corners of its cell, returned as a tuple #(sw, ne).

The input is case-insensitive: upper-case characters are folded to lower-case before lookup. This matches chrisveness/latlon-geohash and ngeohash.

pub fn encode(
  point point: latlng.LatLng,
  precision precision: Int,
) -> Result(String, GeohashError)

Encode a LatLng as a base32 geohash of the requested precision. Precision is the number of output characters and must be in [1, 12]. Each additional character shrinks the cell width by a factor of ~5.6.

import geokit/geohash
import geokit/latlng

let assert Ok(tokyo) = latlng.new(lat: 35.6812, lng: 139.7671)
let assert Ok(hash) = geohash.encode(point: tokyo, precision: 8)
// hash == "xn76urx4"
pub fn neighbor(
  hash hash: String,
  direction direction: Direction,
) -> Result(String, GeohashError)

The neighbour of hash in the given Direction.

Returns EmptyHash when called on the empty string. Wraps across the antimeridian for east / west, returns EmptyHash when a polar neighbour would cross the pole (north of the northernmost row or south of the southernmost row).

The input is case-insensitive: upper-case characters are folded to lower-case before lookup, matching chrisveness/latlon-geohash and ngeohash.

pub fn neighbors(
  hash hash: String,
) -> Result(Neighbors, GeohashError)

All eight neighbours of hash, returned as a Neighbors record.

Search Document