Implementations/Libraries/Erlang
From Geo Hashing
[edit] Erlang Implementation
| This implementation IS FULLY 30W-compliant. |
Carl-Johan made a reference Erlang implementation. It should be fully 30W compliant even for retro hashes. Don't forget to run geohash:init() befor your first lookup.
-module(geohash).
-export([init/0
, lookup/1
]).
-record(meetup,
{lat
, lon
, date
, djiadate
, latdec
, londec
, latcoord
, loncoord
, djia
}).
url() ->
"http://carabiner.peeron.com/xkcd/map/data/~4.10.0b/~2.10.0b/~2.10.0b".
int_to_dec() ->
5.421010862427522e-20. %math:pow(2,-64).
init() ->
application:start(inets),
application:start(crypto).
lookup(Meetup = #meetup{lat=Lat, lon=Lon, date = {_Y, _M, _D}}) when
Lat > -90,
Lat < 90,
Lon > -180,
Lon < 180 ->
Meetup1 = w30(Meetup),
get_djia(Meetup1).
w30(Meetup = #meetup{lat=Lat, date = {Y, M, D}}) ->
case (Lat > -30) and
(calendar:date_to_gregorian_days(Y, M, D) >
calendar:date_to_gregorian_days(2008, 5, 26)) of
true -> Meetup#meetup{
djiadate =
calendar:gregorian_days_to_date(
calendar:date_to_gregorian_days(Y,M,D)-1)
};
false -> Meetup#meetup{
djiadate={Y, M, D}
}
end.
get_djia(Meetup = #meetup{djiadate = {Y, M, D}}) ->
Url = io_lib:format(url(), [Y, M, D]),
case httpc:request(Url) of
{ok, {{"HTTP/1.1",200,"OK"},
_,
Djia}} -> coords(Meetup#meetup{djia=Djia});
{ok, {{"HTTP/1.1",404,"Not Found"},
_,_}} -> Meetup
end.
coords(Meetup = #meetup{lat = Lat
, lon = Lon
, date = {Y, M, D}
, djia = Djia}) ->
Str = io_lib:format("~4.10.0b-~2.10.0b-~2.10.0b-~s",
[Y, M, D, Djia]),
<<LatInt:64,
LonInt:64>> = crypto:md5(Str),
LatDec = LatInt * int_to_dec(),
LonDec = LonInt * int_to_dec(),
Meetup#meetup{latdec = LatDec
, londec = LonDec
, latcoord = Lat + LatDec
, loncoord = Lon + LonDec
}.