Ferricstore.Commands.Geo (ferricstore v0.3.2)

Copy Markdown View Source

Handles Redis geo commands: GEOADD, GEOPOS, GEODIST, GEOHASH, GEOSEARCH, GEOSEARCHSTORE.

Geo is implemented on top of Sorted Set. Members are stored with geohash-encoded float64 scores -- the same encoding Redis uses, making scores wire-compatible. No new data structure is needed. The storage format is {:zset, [{score, member}, ...]} serialized via :erlang.term_to_binary/1.

Geohash encoding

Coordinates are encoded as 52-bit interleaved geohashes stored as float64 scores. 26 bits for longitude (-180..180) and 26 bits for latitude (-90..90) gives ~0.6mm precision, matching Redis.

Supported commands

  • GEOADD key [NX|XX] [CH] longitude latitude member [lng lat member ...]
  • GEOPOS key member [member ...]
  • GEODIST key member1 member2 [M|KM|FT|MI]
  • GEOHASH key member [member ...]
  • GEOSEARCH key FROMLONLAT lng lat|FROMMEMBER member BYRADIUS radius unit|BYBOX width height unit [ASC|DESC] [COUNT count [ANY]] [WITHCOORD] [WITHDIST] [WITHHASH]
  • GEOSEARCHSTORE destination source [same GEOSEARCH options]

Summary

Functions

Decodes a geohash float64 score back to {longitude, latitude}.

Encodes longitude and latitude into a 52-bit geohash stored as a float64.

Handles a geo command.

Computes the haversine distance in meters between two points on Earth.

Functions

geohash_decode(score)

@spec geohash_decode(float()) :: {float(), float()}

Decodes a geohash float64 score back to {longitude, latitude}.

Parameters

  • score - Float64 geohash score

Returns

{longitude, latitude} tuple with ~0.6mm precision.

geohash_encode(longitude, latitude)

@spec geohash_encode(float(), float()) :: float()

Encodes longitude and latitude into a 52-bit geohash stored as a float64.

Interleaves bits of longitude and latitude ranges:

  • longitude: -180 to 180 (26 bits)
  • latitude: -90 to 90 (26 bits)

Parameters

  • longitude - Longitude in degrees (-180..180)
  • latitude - Latitude in degrees (-90..90)

Returns

A float64 representing the geohash score.

handle(cmd, args, store)

@spec handle(binary(), [binary()], map()) :: term()

Handles a geo command.

Parameters

  • cmd - Uppercased command name (e.g. "GEOADD", "GEODIST")
  • args - List of string arguments
  • store - Injected store map with get, put, delete, exists? callbacks

Returns

Plain Elixir term: integer, string, list, nil, or {:error, message}.

haversine(lat1, lng1, lat2, lng2)

@spec haversine(float(), float(), float(), float()) :: float()

Computes the haversine distance in meters between two points on Earth.

Parameters

  • lat1 - Latitude of point 1 in degrees
  • lng1 - Longitude of point 1 in degrees
  • lat2 - Latitude of point 2 in degrees
  • lng2 - Longitude of point 2 in degrees

Returns

Distance in meters as a float.