Artifact 06c428174b0c19d8bb515d0f0b2835bc226dc10f672825a0429402abe6be665b:
- File
headsilose.erl
— part of check-in
[6807958aad]
at
2014-12-17 22:46:39
on branch refs/stash
— Add basic implementation for selecting between route geometries
Not a great implementation, but it works. If no route geometry choice is
made it defaults to the default "route_geometry". If
"alternative_geometries" is specified it uses the first one of the
alternatives (because as far as I can tell there is only ever one
alternative? I supposed at some point I could extend if needed, perhaps
use a tuple argument: {"alternative_geomtries", 1}). (user: base@atomicules.co.uk size: 10776) [more...]
0000: 2d 6d 6f 64 75 6c 65 28 68 65 61 64 73 69 6c 6f -module(headsilo
0010: 73 65 29 2e 0a 2d 65 78 70 6f 72 74 28 5b 67 65 se)..-export([ge
0020: 74 5f 6c 6f 63 61 74 69 6f 6e 73 2f 30 2c 20 67 t_locations/0, g
0030: 65 74 5f 6c 6f 63 61 74 69 6f 6e 73 2f 31 2c 20 et_locations/1,
0040: 68 65 61 64 73 69 6c 6f 73 65 2f 31 5d 29 2e 0a headsilose/1])..
0050: 2d 69 6e 63 6c 75 64 65 5f 6c 69 62 28 22 78 6d -include_lib("xm
0060: 65 72 6c 2f 69 6e 63 6c 75 64 65 2f 78 6d 65 72 erl/include/xmer
0070: 6c 2e 68 72 6c 22 29 2e 0a 2d 69 6d 70 6f 72 74 l.hrl")..-import
0080: 28 77 65 61 74 68 65 72 5f 74 79 70 65 73 2c 20 (weather_types,
0090: 5b 77 65 61 74 68 65 72 5f 74 79 70 65 2f 31 5d [weather_type/1]
00a0: 29 2e 0a 2d 69 6d 70 6f 72 74 28 70 6f 6c 79 6c )..-import(polyl
00b0: 69 6e 65 2c 20 5b 64 65 63 6f 64 65 2f 31 5d 29 ine, [decode/1])
00c0: 2e 0a 2d 69 6d 70 6f 72 74 28 6f 73 72 6d 2c 20 ..-import(osrm,
00d0: 5b 72 65 61 64 5f 72 6f 75 74 65 2f 31 5d 29 2e [read_route/1]).
00e0: 0a 0a 25 53 75 70 70 6c 79 20 61 20 64 69 72 65 ..%Supply a dire
00f0: 63 74 69 6f 6e 20 61 6e 64 20 6c 6f 63 61 74 69 ction and locati
0100: 6f 6e 20 61 6e 64 20 77 6f 72 6b 20 6f 75 74 20 on and work out
0110: 69 66 20 68 65 61 64 20 77 69 6e 64 20 6f 72 20 if head wind or
0120: 6e 6f 74 0a 25 46 6f 72 20 6e 6f 77 20 22 6b 6e not.%For now "kn
0130: 6f 77 20 74 68 65 20 6c 6f 63 61 74 69 6f 6e 20 ow the location
0140: 69 64 22 20 75 70 66 72 6f 6e 74 2c 20 62 75 74 id" upfront, but
0150: 20 69 64 65 61 6c 6c 79 20 6e 65 65 64 20 74 6f ideally need to
0160: 20 73 65 61 72 63 68 20 66 6f 72 20 69 74 20 61 search for it a
0170: 74 20 73 6f 6d 65 20 70 6f 69 6e 74 20 6f 72 20 t some point or
0180: 70 72 65 73 65 6e 74 20 61 20 63 68 6f 69 63 65 present a choice
0190: 2e 0a 0a 25 49 6e 69 74 69 61 6c 6c 79 20 62 61 ...%Initially ba
01a0: 73 65 64 20 6f 6e 3a 20 68 74 74 70 3a 2f 2f 70 sed on: http://p
01b0: 72 61 67 64 61 76 65 2e 70 72 61 67 70 72 6f 67 ragdave.pragprog
01c0: 2e 63 6f 6d 2f 70 72 61 67 64 61 76 65 2f 32 30 .com/pragdave/20
01d0: 30 37 2f 30 34 2f 61 5f 66 69 72 73 74 5f 65 72 07/04/a_first_er
01e0: 6c 61 6e 67 5f 2e 68 74 6d 6c 0a 0a 2d 64 65 66 lang_.html..-def
01f0: 69 6e 65 28 42 41 53 45 5f 55 52 4c 2c 0a 09 22 ine(BASE_URL,.."
0200: 68 74 74 70 3a 2f 2f 64 61 74 61 70 6f 69 6e 74 http://datapoint
0210: 2e 6d 65 74 6f 66 66 69 63 65 2e 67 6f 76 2e 75 .metoffice.gov.u
0220: 6b 2f 70 75 62 6c 69 63 2f 64 61 74 61 2f 22 29 k/public/data/")
0230: 2e 0a 0a 2d 64 65 66 69 6e 65 28 57 58 46 43 53 ...-define(WXFCS
0240: 5f 53 49 54 45 4c 49 53 54 2c 0a 09 22 76 61 6c _SITELIST,.."val
0250: 2f 77 78 66 63 73 2f 61 6c 6c 2f 78 6d 6c 2f 73 /wxfcs/all/xml/s
0260: 69 74 65 6c 69 73 74 22 29 2e 0a 0a 2d 64 65 66 itelist")...-def
0270: 69 6e 65 28 57 58 46 43 53 5f 4c 4f 43 41 54 49 ine(WXFCS_LOCATI
0280: 4f 4e 49 44 2c 0a 09 22 76 61 6c 2f 77 78 66 63 ONID,.."val/wxfc
0290: 73 2f 61 6c 6c 2f 78 6d 6c 2f 22 29 2e 0a 0a 0a s/all/xml/")....
02a0: 25 46 69 72 73 74 20 6f 6e 65 20 66 6f 72 20 63 %First one for c
02b0: 6f 6d 6d 61 6e 64 20 6c 69 6e 65 20 75 73 61 67 ommand line usag
02c0: 65 0a 67 65 74 5f 6c 6f 63 61 74 69 6f 6e 73 28 e.get_locations(
02d0: 5b 53 65 61 72 63 68 5d 29 20 2d 3e 0a 09 67 65 [Search]) ->..ge
02e0: 74 5f 6c 6f 63 61 74 69 6f 6e 73 28 53 65 61 72 t_locations(Sear
02f0: 63 68 29 3b 0a 67 65 74 5f 6c 6f 63 61 74 69 6f ch);.get_locatio
0300: 6e 73 28 53 65 61 72 63 68 29 20 2d 3e 0a 09 67 ns(Search) ->..g
0310: 65 74 5f 6c 6f 63 61 74 69 6f 6e 73 5f 28 22 2f et_locations_("/
0320: 2f 4c 6f 63 61 74 69 6f 6e 5b 63 6f 6e 74 61 69 /Location[contai
0330: 6e 73 28 40 6e 61 6d 65 2c 20 27 22 2b 2b 53 65 ns(@name, '"++Se
0340: 61 72 63 68 2b 2b 22 27 29 5d 22 29 2e 0a 67 65 arch++"')]")..ge
0350: 74 5f 6c 6f 63 61 74 69 6f 6e 73 28 29 20 2d 3e t_locations() ->
0360: 0a 09 67 65 74 5f 6c 6f 63 61 74 69 6f 6e 73 5f ..get_locations_
0370: 28 22 2f 2f 4c 6f 63 61 74 69 6f 6e 22 29 2e 0a ("//Location")..
0380: 67 65 74 5f 6c 6f 63 61 74 69 6f 6e 73 5f 28 58 get_locations_(X
0390: 70 61 74 68 29 20 2d 3e 0a 09 69 6e 65 74 73 3a path) ->..inets:
03a0: 73 74 61 72 74 28 29 2c 0a 09 4b 65 79 20 3d 20 start(),..Key =
03b0: 72 65 61 64 61 70 69 6b 65 79 28 29 2c 0a 09 55 readapikey(),..U
03c0: 52 4c 20 3d 20 3f 42 41 53 45 5f 55 52 4c 20 2b RL = ?BASE_URL +
03d0: 2b 20 3f 57 58 46 43 53 5f 53 49 54 45 4c 49 53 + ?WXFCS_SITELIS
03e0: 54 20 2b 2b 20 22 3f 6b 65 79 3d 22 20 2b 2b 20 T ++ "?key=" ++
03f0: 4b 65 79 2c 0a 09 74 72 79 0a 09 09 25 48 61 6e Key,..try...%Han
0400: 64 6c 69 6e 67 20 74 69 6d 65 6f 75 74 73 3a 20 dling timeouts:
0410: 68 74 74 70 3a 2f 2f 73 74 61 63 6b 6f 76 65 72 http://stackover
0420: 66 6c 6f 77 2e 63 6f 6d 2f 61 2f 31 34 31 34 33 flow.com/a/14143
0430: 37 36 32 2f 32 30 38 37 39 33 0a 09 09 7b 20 6f 762/208793...{ o
0440: 6b 2c 20 7b 5f 53 74 61 74 75 73 2c 20 5f 48 65 k, {_Status, _He
0450: 61 64 65 72 73 2c 20 42 6f 64 79 20 7d 7d 20 3d aders, Body }} =
0460: 20 68 74 74 70 63 3a 72 65 71 75 65 73 74 28 67 httpc:request(g
0470: 65 74 2c 20 7b 55 52 4c 2c 20 5b 5d 7d 2c 20 5b et, {URL, []}, [
0480: 7b 74 69 6d 65 6f 75 74 2c 20 74 69 6d 65 72 3a {timeout, timer:
0490: 73 65 63 6f 6e 64 73 28 31 30 29 7d 5d 2c 20 5b seconds(10)}], [
04a0: 5d 29 2c 0a 09 09 7b 20 58 6d 6c 2c 20 5f 52 65 ]),...{ Xml, _Re
04b0: 73 74 20 7d 20 3d 20 78 6d 65 72 6c 5f 73 63 61 st } = xmerl_sca
04c0: 6e 3a 73 74 72 69 6e 67 28 42 6f 64 79 29 2c 0a n:string(Body),.
04d0: 09 09 25 50 72 69 6e 74 20 61 20 6c 69 73 74 20 ..%Print a list
04e0: 6f 66 20 4c 6f 63 61 74 69 6f 6e 73 20 61 6e 64 of Locations and
04f0: 20 49 44 73 0a 09 09 70 72 69 6e 74 5f 6c 6f 63 IDs...print_loc
0500: 61 74 69 6f 6e 73 28 78 6d 65 72 6c 5f 78 70 61 ations(xmerl_xpa
0510: 74 68 3a 73 74 72 69 6e 67 28 58 70 61 74 68 2c th:string(Xpath,
0520: 20 58 6d 6c 29 29 0a 09 09 25 53 74 72 69 63 74 Xml))...%Strict
0530: 6c 79 20 73 70 65 61 6b 69 6e 67 20 74 68 69 73 ly speaking this
0540: 20 66 75 6e 63 74 69 6f 6e 20 73 68 6f 75 6c 64 function should
0550: 6e 27 74 20 62 65 20 68 65 72 65 20 61 73 20 69 n't be here as i
0560: 74 27 73 20 72 65 63 75 72 73 69 76 65 0a 09 09 t's recursive...
0570: 25 62 75 74 20 67 65 74 5f 6c 6f 63 61 74 69 6f %but get_locatio
0580: 6e 73 20 69 73 20 61 20 72 75 6e 20 6f 6e 63 65 ns is a run once
0590: 20 66 75 6e 63 74 69 6f 6e 20 73 6f 20 49 20 74 function so I t
05a0: 68 69 6e 6b 20 69 74 27 73 20 6f 6b 0a 09 09 25 hink it's ok...%
05b0: 53 65 65 20 6e 6f 74 65 20 61 62 6f 76 65 20 68 See note above h
05c0: 74 74 70 3a 2f 2f 6c 65 61 72 6e 79 6f 75 73 6f ttp://learnyouso
05d0: 6d 65 65 72 6c 61 6e 67 2e 63 6f 6d 2f 65 72 72 meerlang.com/err
05e0: 6f 72 73 2d 61 6e 64 2d 65 78 63 65 70 74 69 6f ors-and-exceptio
05f0: 6e 73 23 74 68 65 72 65 73 2d 6d 6f 72 65 0a 09 ns#theres-more..
0600: 63 61 74 63 68 0a 09 09 5f 3a 52 65 61 73 6f 6e catch..._:Reason
0610: 20 2d 3e 0a 09 09 09 69 6f 3a 66 6f 72 6d 61 74 ->....io:format
0620: 28 22 41 50 49 20 4d 69 67 68 74 20 62 65 20 64 ("API Might be d
0630: 6f 77 6e 7e 6e 22 29 2c 0a 09 09 09 52 65 61 73 own~n"),....Reas
0640: 6f 6e 0a 09 61 66 74 65 72 0a 09 09 6d 61 79 62 on..after...mayb
0650: 65 5f 71 75 69 74 28 29 0a 09 65 6e 64 2e 0a 0a e_quit()..end...
0660: 0a 25 42 61 73 65 64 20 6f 6e 20 68 74 74 70 3a .%Based on http:
0670: 2f 2f 69 6e 74 65 72 74 77 69 6e 67 6c 79 2e 6e //intertwingly.n
0680: 65 74 2f 62 6c 6f 67 2f 32 30 30 37 2f 30 38 2f et/blog/2007/08/
0690: 32 38 2f 50 61 72 73 69 6e 67 2d 41 74 6f 6d 2d 28/Parsing-Atom-
06a0: 77 69 74 68 2d 45 72 6c 61 6e 67 0a 70 72 69 6e with-Erlang.prin
06b0: 74 5f 6c 6f 63 61 74 69 6f 6e 73 28 5b 5d 29 20 t_locations([])
06c0: 2d 3e 0a 09 65 6e 64 5f 6f 66 5f 6c 69 73 74 3b ->..end_of_list;
06d0: 0a 70 72 69 6e 74 5f 6c 6f 63 61 74 69 6f 6e 73 .print_locations
06e0: 28 5b 4e 6f 64 65 7c 52 65 73 74 5d 29 20 2d 3e ([Node|Rest]) ->
06f0: 0a 09 25 4e 65 65 64 20 74 6f 20 64 6f 20 74 68 ..%Need to do th
0700: 69 73 20 72 65 63 75 72 73 69 76 65 6c 79 0a 09 is recursively..
0710: 5b 20 23 78 6d 6c 41 74 74 72 69 62 75 74 65 7b [ #xmlAttribute{
0720: 76 61 6c 75 65 3d 4c 6f 63 61 74 69 6f 6e 7d 20 value=Location}
0730: 5d 20 3d 20 78 6d 65 72 6c 5f 78 70 61 74 68 3a ] = xmerl_xpath:
0740: 73 74 72 69 6e 67 28 22 40 6e 61 6d 65 22 2c 20 string("@name",
0750: 4e 6f 64 65 29 2c 0a 09 5b 20 23 78 6d 6c 41 74 Node),..[ #xmlAt
0760: 74 72 69 62 75 74 65 7b 76 61 6c 75 65 3d 49 44 tribute{value=ID
0770: 7d 20 5d 20 3d 20 78 6d 65 72 6c 5f 78 70 61 74 } ] = xmerl_xpat
0780: 68 3a 73 74 72 69 6e 67 28 22 40 69 64 22 2c 20 h:string("@id",
0790: 4e 6f 64 65 29 2c 0a 09 69 6f 3a 66 6f 72 6d 61 Node),..io:forma
07a0: 74 28 4c 6f 63 61 74 69 6f 6e 2b 2b 22 2c 20 22 t(Location++", "
07b0: 2b 2b 49 44 2b 2b 22 7e 6e 22 29 2c 0a 09 70 72 ++ID++"~n"),..pr
07c0: 69 6e 74 5f 6c 6f 63 61 74 69 6f 6e 73 28 52 65 int_locations(Re
07d0: 73 74 29 2e 0a 0a 0a 67 65 74 5f 77 65 61 74 68 st)....get_weath
07e0: 65 72 28 4c 6f 63 61 74 69 6f 6e 2c 20 7b 20 44 er(Location, { D
07f0: 61 74 65 5f 66 6f 72 6d 61 74 74 65 64 2c 20 52 ate_formatted, R
0800: 65 70 20 7d 29 20 2d 3e 0a 09 69 6e 65 74 73 3a ep }) ->..inets:
0810: 73 74 61 72 74 28 29 2c 0a 09 4b 65 79 20 3d 20 start(),..Key =
0820: 72 65 61 64 61 70 69 6b 65 79 28 29 2c 0a 09 55 readapikey(),..U
0830: 52 4c 20 3d 20 3f 42 41 53 45 5f 55 52 4c 20 2b RL = ?BASE_URL +
0840: 2b 20 3f 57 58 46 43 53 5f 4c 4f 43 41 54 49 4f + ?WXFCS_LOCATIO
0850: 4e 49 44 20 2b 2b 20 4c 6f 63 61 74 69 6f 6e 20 NID ++ Location
0860: 2b 2b 20 22 3f 6b 65 79 3d 22 20 2b 2b 20 4b 65 ++ "?key=" ++ Ke
0870: 79 20 2b 2b 20 22 26 72 65 73 3d 33 68 6f 75 72 y ++ "&res=3hour
0880: 6c 79 22 2c 0a 09 74 72 79 0a 09 09 7b 20 6f 6b ly",..try...{ ok
0890: 2c 20 7b 5f 53 74 61 74 75 73 2c 20 5f 48 65 61 , {_Status, _Hea
08a0: 64 65 72 73 2c 20 42 6f 64 79 20 7d 7d 20 3d 20 ders, Body }} =
08b0: 68 74 74 70 63 3a 72 65 71 75 65 73 74 28 67 65 httpc:request(ge
08c0: 74 2c 20 7b 55 52 4c 2c 20 5b 5d 7d 2c 20 5b 7b t, {URL, []}, [{
08d0: 74 69 6d 65 6f 75 74 2c 20 74 69 6d 65 72 3a 73 timeout, timer:s
08e0: 65 63 6f 6e 64 73 28 31 30 29 7d 5d 2c 20 5b 5d econds(10)}], []
08f0: 29 2c 0a 09 09 7b 20 58 6d 6c 2c 20 5f 52 65 73 ),...{ Xml, _Res
0900: 74 20 7d 20 3d 20 78 6d 65 72 6c 5f 73 63 61 6e t } = xmerl_scan
0910: 3a 73 74 72 69 6e 67 28 42 6f 64 79 29 2c 0a 09 :string(Body),..
0920: 09 5b 20 5b 20 23 78 6d 6c 41 74 74 72 69 62 75 .[ [ #xmlAttribu
0930: 74 65 7b 76 61 6c 75 65 3d 44 69 72 65 63 74 69 te{value=Directi
0940: 6f 6e 7d 20 5d 2c 0a 09 09 20 20 5b 20 23 78 6d on} ],... [ #xm
0950: 6c 41 74 74 72 69 62 75 74 65 7b 76 61 6c 75 65 lAttribute{value
0960: 3d 53 70 65 65 64 7d 20 5d 2c 0a 09 09 20 20 5b =Speed} ],... [
0970: 20 23 78 6d 6c 41 74 74 72 69 62 75 74 65 7b 76 #xmlAttribute{v
0980: 61 6c 75 65 3d 47 75 73 74 7d 20 5d 2c 0a 09 09 alue=Gust} ],...
0990: 20 20 5b 20 23 78 6d 6c 41 74 74 72 69 62 75 74 [ #xmlAttribut
09a0: 65 7b 76 61 6c 75 65 3d 57 65 61 74 68 65 72 7d e{value=Weather}
09b0: 20 5d 2c 0a 09 09 20 20 5b 20 23 78 6d 6c 41 74 ],... [ #xmlAt
09c0: 74 72 69 62 75 74 65 7b 76 61 6c 75 65 3d 54 65 tribute{value=Te
09d0: 6d 70 65 72 61 74 75 72 65 7d 20 5d 20 5d 20 3d mperature} ] ] =
09e0: 20 6c 69 73 74 73 3a 6d 61 70 28 0a 09 09 09 66 lists:map(....f
09f0: 75 6e 28 58 29 20 2d 3e 0a 09 09 09 09 78 6d 65 un(X) ->.....xme
0a00: 72 6c 5f 78 70 61 74 68 3a 73 74 72 69 6e 67 28 rl_xpath:string(
0a10: 22 2f 2f 50 65 72 69 6f 64 5b 40 76 61 6c 75 65 "//Period[@value
0a20: 3d 27 22 20 2b 2b 20 44 61 74 65 5f 66 6f 72 6d ='" ++ Date_form
0a30: 61 74 74 65 64 20 2b 2b 20 22 27 5d 2f 52 65 70 atted ++ "']/Rep
0a40: 5b 2e 3d 27 22 20 2b 2b 20 52 65 70 20 2b 2b 20 [.='" ++ Rep ++
0a50: 22 27 5d 2f 40 22 2b 2b 58 2c 20 58 6d 6c 29 0a "']/@"++X, Xml).
0a60: 09 09 09 65 6e 64 2c 0a 09 09 09 5b 22 44 22 2c ...end,....["D",
0a70: 20 22 53 22 2c 20 22 47 22 2c 20 22 57 22 2c 20 "S", "G", "W",
0a80: 22 54 22 5d 29 2c 0a 09 09 7b 44 69 72 65 63 74 "T"]),...{Direct
0a90: 69 6f 6e 2c 20 53 70 65 65 64 2c 20 47 75 73 74 ion, Speed, Gust
0aa0: 2c 20 57 65 61 74 68 65 72 2c 20 54 65 6d 70 65 , Weather, Tempe
0ab0: 72 61 74 75 72 65 7d 0a 09 63 61 74 63 68 0a 09 rature}..catch..
0ac0: 09 5f 3a 52 65 61 73 6f 6e 20 2d 3e 0a 09 09 09 ._:Reason ->....
0ad0: 69 6f 3a 66 6f 72 6d 61 74 28 22 41 50 49 20 4d io:format("API M
0ae0: 69 67 68 74 20 62 65 20 64 6f 77 6e 7e 6e 22 29 ight be down~n")
0af0: 2c 0a 09 09 09 52 65 61 73 6f 6e 0a 09 61 66 74 ,....Reason..aft
0b00: 65 72 0a 09 09 6d 61 79 62 65 5f 71 75 69 74 28 er...maybe_quit(
0b10: 29 0a 09 65 6e 64 2e 0a 0a 0a 64 61 74 65 5f 61 )..end....date_a
0b20: 6e 64 5f 72 65 70 28 44 61 74 65 29 20 2d 3e 0a nd_rep(Date) ->.
0b30: 09 7b 7b 5f 59 65 61 72 2c 20 5f 4d 6f 6e 74 68 .{{_Year, _Month
0b40: 2c 20 5f 44 61 79 7d 2c 20 7b 48 6f 75 72 73 2c , _Day}, {Hours,
0b50: 20 5f 4d 69 6e 75 74 65 73 2c 20 5f 53 65 63 6f _Minutes, _Seco
0b60: 6e 64 73 7d 7d 20 3d 20 44 61 74 65 2c 0a 09 64 nds}} = Date,..d
0b70: 61 74 65 5f 61 6e 64 5f 72 65 70 28 44 61 74 65 ate_and_rep(Date
0b80: 2c 20 48 6f 75 72 73 29 2e 0a 64 61 74 65 5f 61 , Hours)..date_a
0b90: 6e 64 5f 72 65 70 28 44 61 74 65 2c 20 48 6f 75 nd_rep(Date, Hou
0ba0: 72 73 29 20 77 68 65 6e 20 48 6f 75 72 73 20 3c rs) when Hours <
0bb0: 20 38 20 2d 3e 0a 09 52 65 70 20 3d 20 22 33 36 8 ->..Rep = "36
0bc0: 30 22 2c 0a 09 7b 66 6f 72 6d 61 74 5f 64 61 74 0",..{format_dat
0bd0: 65 28 44 61 74 65 29 2c 20 52 65 70 7d 3b 0a 64 e(Date), Rep};.d
0be0: 61 74 65 5f 61 6e 64 5f 72 65 70 28 44 61 74 65 ate_and_rep(Date
0bf0: 2c 20 48 6f 75 72 73 29 20 77 68 65 6e 20 48 6f , Hours) when Ho
0c00: 75 72 73 20 3e 3d 20 38 2c 20 48 6f 75 72 73 20 urs >= 8, Hours
0c10: 3c 20 31 39 20 2d 3e 0a 09 52 65 70 20 3d 20 22 < 19 ->..Rep = "
0c20: 31 30 38 30 22 2c 0a 09 7b 66 6f 72 6d 61 74 5f 1080",..{format_
0c30: 64 61 74 65 28 44 61 74 65 29 2c 20 52 65 70 7d date(Date), Rep}
0c40: 3b 0a 64 61 74 65 5f 61 6e 64 5f 72 65 70 28 44 ;.date_and_rep(D
0c50: 61 74 65 2c 20 48 6f 75 72 73 29 20 77 68 65 6e ate, Hours) when
0c60: 20 48 6f 75 72 73 20 3e 3d 20 31 39 20 2d 3e 0a Hours >= 19 ->.
0c70: 09 52 65 70 20 3d 20 22 33 36 30 22 2c 0a 09 7b .Rep = "360",..{
0c80: 66 6f 72 6d 61 74 5f 64 61 74 65 28 66 69 6e 64 format_date(find
0c90: 5f 6e 65 78 74 5f 64 61 79 28 44 61 74 65 29 29 _next_day(Date))
0ca0: 2c 20 52 65 70 7d 2e 0a 0a 0a 66 6f 72 6d 61 74 , Rep}....format
0cb0: 5f 64 61 74 65 28 44 61 74 65 5f 74 6f 5f 66 6f _date(Date_to_fo
0cc0: 72 6d 61 74 29 20 2d 3e 0a 09 7b 7b 59 65 61 72 rmat) ->..{{Year
0cd0: 2c 20 4d 6f 6e 74 68 2c 20 44 61 79 7d 2c 20 7b , Month, Day}, {
0ce0: 5f 48 6f 75 72 73 2c 20 5f 4d 69 6e 75 74 65 73 _Hours, _Minutes
0cf0: 2c 20 5f 53 65 63 6f 6e 64 73 7d 7d 20 3d 20 44 , _Seconds}} = D
0d00: 61 74 65 5f 74 6f 5f 66 6f 72 6d 61 74 2c 0a 09 ate_to_format,..
0d10: 25 54 68 61 6e 6b 73 20 74 6f 3a 20 68 74 74 70 %Thanks to: http
0d20: 3a 2f 2f 73 74 61 63 6b 6f 76 65 72 66 6c 6f 77 ://stackoverflow
0d30: 2e 63 6f 6d 2f 61 2f 37 35 39 39 35 30 36 2f 32 .com/a/7599506/2
0d40: 30 38 37 39 33 0a 09 44 61 74 65 5f 61 73 5f 73 08793..Date_as_s
0d50: 74 72 69 6e 67 20 3d 20 69 6f 5f 6c 69 62 3a 66 tring = io_lib:f
0d60: 6f 72 6d 61 74 28 22 7e 34 2e 2e 30 77 2d 7e 32 ormat("~4..0w-~2
0d70: 2e 2e 30 77 2d 7e 32 2e 2e 30 77 5a 22 2c 20 5b ..0w-~2..0wZ", [
0d80: 59 65 61 72 2c 20 4d 6f 6e 74 68 2c 20 44 61 79 Year, Month, Day
0d90: 5d 29 2c 0a 09 6c 69 73 74 73 3a 66 6c 61 74 74 ]),..lists:flatt
0da0: 65 6e 28 44 61 74 65 5f 61 73 5f 73 74 72 69 6e en(Date_as_strin
0db0: 67 29 2e 0a 0a 0a 6e 74 68 5f 77 72 61 70 28 4e g)....nth_wrap(N
0dc0: 2c 20 4c 69 73 74 29 20 2d 3e 0a 09 52 65 6d 20 , List) ->..Rem
0dd0: 3d 20 4e 20 72 65 6d 20 28 6c 65 6e 67 74 68 28 = N rem (length(
0de0: 4c 69 73 74 29 29 2c 0a 09 69 66 20 52 65 6d 20 List)),..if Rem
0df0: 3e 20 30 20 2d 3e 0a 09 09 6c 69 73 74 73 3a 6e > 0 ->...lists:n
0e00: 74 68 28 52 65 6d 2c 20 4c 69 73 74 29 3b 0a 09 th(Rem, List);..
0e10: 52 65 6d 20 3d 3a 3d 20 30 20 2d 3e 0a 09 09 25 Rem =:= 0 ->...%
0e20: 47 65 74 20 6c 61 73 74 20 6f 66 20 6c 69 73 74 Get last of list
0e30: 0a 09 09 68 64 28 6c 69 73 74 73 3a 72 65 76 65 ...hd(lists:reve
0e40: 72 73 65 28 4c 69 73 74 29 29 0a 09 65 6e 64 2e rse(List))..end.
0e50: 0a 0a 0a 66 69 6e 64 5f 6e 65 78 74 5f 64 61 79 ...find_next_day
0e60: 28 44 61 74 65 5f 74 6f 64 61 79 29 20 2d 3e 0a (Date_today) ->.
0e70: 09 25 67 65 74 20 69 6e 20 73 65 63 6f 6e 64 73 .%get in seconds
0e80: 0a 09 53 65 63 6f 6e 64 73 5f 74 6f 64 61 79 20 ..Seconds_today
0e90: 3d 20 63 61 6c 65 6e 64 61 72 3a 64 61 74 65 74 = calendar:datet
0ea0: 69 6d 65 5f 74 6f 5f 67 72 65 67 6f 72 69 61 6e ime_to_gregorian
0eb0: 5f 73 65 63 6f 6e 64 73 28 44 61 74 65 5f 74 6f _seconds(Date_to
0ec0: 64 61 79 29 2c 0a 09 44 61 74 65 5f 74 6f 6d 6f day),..Date_tomo
0ed0: 72 72 6f 77 20 3d 20 63 61 6c 65 6e 64 61 72 3a rrow = calendar:
0ee0: 67 72 65 67 6f 72 69 61 6e 5f 73 65 63 6f 6e 64 gregorian_second
0ef0: 73 5f 74 6f 5f 64 61 74 65 74 69 6d 65 28 53 65 s_to_datetime(Se
0f00: 63 6f 6e 64 73 5f 74 6f 64 61 79 2b 38 36 34 30 conds_today+8640
0f10: 30 29 2c 0a 09 44 61 74 65 5f 74 6f 6d 6f 72 72 0),..Date_tomorr
0f20: 6f 77 2e 0a 0a 0a 6d 61 79 62 65 5f 71 75 69 74 ow....maybe_quit
0f30: 28 29 20 2d 3e 0a 09 41 72 67 73 20 3d 20 69 6e () ->..Args = in
0f40: 69 74 3a 67 65 74 5f 61 72 67 75 6d 65 6e 74 73 it:get_arguments
0f50: 28 29 2c 20 0a 09 46 6f 75 6e 64 20 3d 20 6c 69 (), ..Found = li
0f60: 73 74 73 3a 6b 65 79 66 69 6e 64 28 6e 6f 73 68 sts:keyfind(nosh
0f70: 65 6c 6c 2c 20 31 2c 20 41 72 67 73 29 2c 0a 09 ell, 1, Args),..
0f80: 69 66 20 46 6f 75 6e 64 20 3d 3a 3d 20 66 61 6c if Found =:= fal
0f90: 73 65 20 2d 3e 0a 09 09 64 6f 6e 74 5f 71 75 69 se ->...dont_qui
0fa0: 74 3b 0a 09 74 72 75 65 20 2d 3e 0a 09 09 69 6e t;..true ->...in
0fb0: 69 74 3a 73 74 6f 70 28 29 0a 09 65 6e 64 2e 0a it:stop()..end..
0fc0: 0a 0a 25 46 72 6f 6d 3a 20 68 74 74 70 3a 2f 2f ..%From: http://
0fd0: 77 77 77 2e 63 6f 64 65 63 6f 64 65 78 2e 63 6f www.codecodex.co
0fe0: 6d 2f 77 69 6b 69 2f 69 6e 64 65 78 2e 70 68 70 m/wiki/index.php
0ff0: 3f 74 69 74 6c 65 3d 52 6f 75 6e 64 5f 61 5f 6e ?title=Round_a_n
1000: 75 6d 62 65 72 5f 74 6f 5f 61 5f 73 70 65 63 69 umber_to_a_speci
1010: 66 69 63 5f 64 65 63 69 6d 61 6c 5f 70 6c 61 63 fic_decimal_plac
1020: 65 23 45 72 6c 61 6e 67 0a 72 6f 75 6e 64 28 4e e#Erlang.round(N
1030: 75 6d 62 65 72 2c 20 50 72 65 63 69 73 69 6f 6e umber, Precision
1040: 29 20 2d 3e 0a 09 50 20 3d 20 6d 61 74 68 3a 70 ) ->..P = math:p
1050: 6f 77 28 31 30 2c 20 50 72 65 63 69 73 69 6f 6e ow(10, Precision
1060: 29 2c 0a 09 09 72 6f 75 6e 64 28 4e 75 6d 62 65 ),...round(Numbe
1070: 72 20 2a 20 50 29 20 2f 20 50 2e 0a 0a 0a 62 75 r * P) / P....bu
1080: 69 6c 64 5f 6c 69 73 74 5f 6f 66 5f 77 69 6e 64 ild_list_of_wind
1090: 5f 64 69 72 65 63 74 69 6f 6e 73 28 57 69 6e 64 _directions(Wind
10a0: 5f 64 69 72 65 63 74 69 6f 6e 29 20 2d 3e 0a 09 _direction) ->..
10b0: 25 54 68 65 72 65 20 69 73 20 6f 6e 6c 79 20 6f %There is only o
10c0: 6e 65 20 77 69 6e 64 20 64 69 72 65 63 74 69 6f ne wind directio
10d0: 6e 2c 20 62 75 74 20 63 61 6e 20 62 75 69 6c 64 n, but can build
10e0: 20 67 72 6f 75 70 73 20 6f 66 20 64 69 72 65 63 groups of direc
10f0: 74 69 6f 6e 73 20 74 68 61 74 20 77 69 6c 6c 20 tions that will
1100: 63 6f 75 6e 74 20 61 73 20 68 65 61 64 2c 20 73 count as head, s
1110: 69 64 65 20 61 6e 64 20 74 61 69 6c 20 77 69 6e ide and tail win
1120: 64 73 0a 09 43 6f 6d 70 61 73 73 20 3d 20 5b 22 ds..Compass = ["
1130: 4e 22 2c 20 22 4e 4e 45 22 2c 20 22 4e 45 22 2c N", "NNE", "NE",
1140: 20 22 45 4e 45 22 2c 20 22 45 22 2c 20 22 45 53 "ENE", "E", "ES
1150: 45 22 2c 20 22 53 45 22 2c 20 22 53 53 45 22 2c E", "SE", "SSE",
1160: 20 22 53 22 2c 20 22 53 53 57 22 2c 20 22 53 57 "S", "SSW", "SW
1170: 22 2c 20 22 57 53 57 22 2c 20 22 57 22 2c 20 22 ", "WSW", "W", "
1180: 57 4e 57 22 2c 20 22 4e 57 22 2c 20 22 4e 4e 57 WNW", "NW", "NNW
1190: 22 5d 2c 0a 09 25 51 75 69 63 6b 65 72 20 64 69 "],..%Quicker di
11a0: 72 74 69 65 72 28 3f 29 20 77 61 79 20 74 6f 20 rtier(?) way to
11b0: 64 6f 20 62 65 6c 6f 77 20 77 6f 75 6c 64 20 62 do below would b
11c0: 65 3a 20 68 74 74 70 3a 2f 2f 73 74 61 63 6b 6f e: http://stacko
11d0: 76 65 72 66 6c 6f 77 2e 63 6f 6d 2f 61 2f 36 37 verflow.com/a/67
11e0: 36 32 31 39 31 2f 32 30 38 37 39 33 0a 09 49 6e 62191/208793..In
11f0: 64 65 78 20 3d 20 6c 65 6e 67 74 68 28 6c 69 73 dex = length(lis
1200: 74 73 3a 74 61 6b 65 77 68 69 6c 65 28 66 75 6e ts:takewhile(fun
1210: 28 58 29 20 2d 3e 20 58 20 20 3d 2f 3d 20 57 69 (X) -> X =/= Wi
1220: 6e 64 5f 64 69 72 65 63 74 69 6f 6e 20 65 6e 64 nd_direction end
1230: 2c 20 43 6f 6d 70 61 73 73 29 29 2b 31 2c 0a 09 , Compass))+1,..
1240: 25 53 69 6e 63 65 20 68 65 61 64 69 6e 67 20 69 %Since heading i
1250: 73 20 74 6f 20 64 69 72 65 63 74 69 6f 6e 20 61 s to direction a
1260: 6e 64 20 77 69 6e 64 73 20 61 72 65 20 66 72 6f nd winds are fro
1270: 6d 2c 20 6f 70 70 6f 73 69 74 65 20 69 73 20 2d m, opposite is -
1280: 32 20 74 6f 20 2b 32 2c 20 6f 72 20 74 6f 20 6d 2 to +2, or to m
1290: 61 6b 65 20 69 74 20 65 61 73 69 65 72 20 74 6f ake it easier to
12a0: 20 77 72 61 70 2c 20 2b 31 34 20 2b 31 38 0a 09 wrap, +14 +18..
12b0: 25 53 69 6e 63 65 20 68 65 61 64 69 6e 67 20 69 %Since heading i
12c0: 73 20 74 6f 20 64 69 72 65 63 74 69 6f 6e 20 61 s to direction a
12d0: 6e 64 20 77 69 6e 64 73 20 61 72 65 20 66 72 6f nd winds are fro
12e0: 6d 2c 20 73 69 64 65 77 69 6e 64 73 20 61 72 65 m, sidewinds are
12f0: 20 2d 35 20 74 6f 20 2d 33 20 61 6e 64 20 2b 33 -5 to -3 and +3
1300: 20 74 6f 20 2b 35 2c 20 6f 72 20 74 6f 20 6d 61 to +5, or to ma
1310: 6b 65 20 69 74 20 65 61 73 69 65 72 20 74 6f 20 ke it easier to
1320: 77 72 61 70 2c 20 2b 31 34 20 2b 31 38 0a 09 25 wrap, +14 +18..%
1330: 41 6e 64 20 73 6f 20 6f 6e 0a 09 48 65 61 64 77 And so on..Headw
1340: 69 6e 64 5f 6c 69 73 74 20 3d 20 6c 69 73 74 73 ind_list = lists
1350: 3a 73 65 71 28 31 34 2c 31 38 29 2c 0a 09 53 69 :seq(14,18),..Si
1360: 64 65 77 69 6e 64 5f 6c 69 73 74 20 3d 20 6c 69 dewind_list = li
1370: 73 74 73 3a 73 65 71 28 33 2c 35 29 2b 2b 6c 69 sts:seq(3,5)++li
1380: 73 74 73 3a 73 65 71 28 31 31 2c 31 33 29 2c 0a sts:seq(11,13),.
1390: 09 54 61 69 6c 77 69 6e 64 5f 6c 69 73 74 20 3d .Tailwind_list =
13a0: 20 6c 69 73 74 73 3a 73 65 71 28 36 2c 31 30 29 lists:seq(6,10)
13b0: 2c 0a 09 6c 69 73 74 73 3a 6d 61 70 28 0a 09 09 ,..lists:map(...
13c0: 66 75 6e 28 57 69 6e 64 5f 6c 69 73 74 29 20 2d fun(Wind_list) -
13d0: 3e 0a 09 09 09 6c 69 73 74 73 3a 6d 61 70 28 0a >....lists:map(.
13e0: 09 09 09 09 66 75 6e 28 58 29 20 2d 3e 0a 09 09 ....fun(X) ->...
13f0: 09 09 09 6e 74 68 5f 77 72 61 70 28 49 6e 64 65 ...nth_wrap(Inde
1400: 78 2b 58 2c 20 43 6f 6d 70 61 73 73 29 0a 09 09 x+X, Compass)...
1410: 09 09 65 6e 64 2c 0a 09 09 09 09 57 69 6e 64 5f ..end,.....Wind_
1420: 6c 69 73 74 29 0a 09 09 65 6e 64 2c 0a 09 09 5b list)...end,...[
1430: 48 65 61 64 77 69 6e 64 5f 6c 69 73 74 2c 20 53 Headwind_list, S
1440: 69 64 65 77 69 6e 64 5f 6c 69 73 74 2c 20 54 61 idewind_list, Ta
1450: 69 6c 77 69 6e 64 5f 6c 69 73 74 5d 29 2e 0a 0a ilwind_list])...
1460: 0a 63 6f 6e 76 65 72 74 5f 6c 61 74 73 5f 6c 6f .convert_lats_lo
1470: 6e 67 73 5f 74 6f 5f 64 69 73 74 61 6e 63 65 5f ngs_to_distance_
1480: 68 65 61 64 69 6e 67 28 5b 5f 48 65 61 64 31 20 heading([_Head1
1490: 7c 20 5b 20 5f 48 65 61 64 32 20 7c 20 52 65 73 | [ _Head2 | Res
14a0: 74 5d 5d 29 20 20 2d 3e 20 0a 09 25 41 6c 6c 20 t]]) -> ..%All
14b0: 63 6f 2d 6f 72 64 73 20 61 72 65 20 64 69 66 66 co-ords are diff
14c0: 2c 20 73 6f 20 6a 75 73 74 20 69 67 6e 6f 72 65 , so just ignore
14d0: 20 66 69 72 73 74 20 74 77 6f 0a 09 63 6f 6e 76 first two..conv
14e0: 65 72 74 5f 6c 61 74 73 5f 6c 6f 6e 67 73 5f 74 ert_lats_longs_t
14f0: 6f 5f 64 69 73 74 61 6e 63 65 5f 68 65 61 64 69 o_distance_headi
1500: 6e 67 5f 28 52 65 73 74 2c 20 5b 5d 29 2e 0a 63 ng_(Rest, [])..c
1510: 6f 6e 76 65 72 74 5f 6c 61 74 73 5f 6c 6f 6e 67 onvert_lats_long
1520: 73 5f 74 6f 5f 64 69 73 74 61 6e 63 65 5f 68 65 s_to_distance_he
1530: 61 64 69 6e 67 5f 28 5b 4c 61 74 20 7c 20 5b 4c ading_([Lat | [L
1540: 6f 6e 20 7c 20 52 65 73 74 5d 5d 2c 20 44 69 73 on | Rest]], Dis
1550: 74 61 6e 63 65 5f 68 65 61 64 69 6e 67 73 5f 6c tance_headings_l
1560: 69 73 74 29 20 2d 3e 0a 09 25 57 61 6e 74 20 74 ist) ->..%Want t
1570: 6f 20 6d 61 70 20 74 68 72 6f 75 67 68 20 74 68 o map through th
1580: 65 20 6c 69 73 74 20 63 6f 6e 76 65 72 74 20 63 e list convert c
1590: 6f 2d 6f 72 64 73 20 74 6f 20 64 69 73 74 61 6e o-ords to distan
15a0: 63 65 20 61 6e 64 20 68 65 61 64 69 6e 67 0a 09 ce and heading..
15b0: 44 69 73 74 61 6e 63 65 20 3d 20 6d 61 74 68 3a Distance = math:
15c0: 73 71 72 74 28 6d 61 74 68 3a 70 6f 77 28 4c 61 sqrt(math:pow(La
15d0: 74 2c 32 29 20 2b 20 6d 61 74 68 3a 70 6f 77 28 t,2) + math:pow(
15e0: 4c 6f 6e 2c 32 29 29 2c 0a 09 48 65 61 64 69 6e Lon,2)),..Headin
15f0: 67 5f 73 69 67 6e 65 64 20 3d 20 6d 61 74 68 3a g_signed = math:
1600: 61 74 61 6e 32 28 4c 6f 6e 2c 20 4c 61 74 29 2c atan2(Lon, Lat),
1610: 0a 09 25 4e 65 65 64 20 74 6f 20 63 6f 6e 76 65 ..%Need to conve
1620: 72 74 20 68 65 61 64 69 6e 67 20 69 6e 74 6f 20 rt heading into
1630: 61 20 32 cf 80 20 76 61 6c 75 65 0a 09 48 65 61 a 2π value..Hea
1640: 64 69 6e 67 20 3d 20 69 66 20 48 65 61 64 69 6e ding = if Headin
1650: 67 5f 73 69 67 6e 65 64 20 3c 20 30 20 2d 3e 0a g_signed < 0 ->.
1660: 09 09 09 09 48 65 61 64 69 6e 67 5f 73 69 67 6e ....Heading_sign
1670: 65 64 20 2b 20 32 2a 6d 61 74 68 3a 70 69 28 29 ed + 2*math:pi()
1680: 3b 0a 09 09 09 74 72 75 65 20 2d 3e 0a 09 09 09 ;....true ->....
1690: 09 48 65 61 64 69 6e 67 5f 73 69 67 6e 65 64 0a .Heading_signed.
16a0: 09 09 09 65 6e 64 2c 0a 09 63 6f 6e 76 65 72 74 ...end,..convert
16b0: 5f 6c 61 74 73 5f 6c 6f 6e 67 73 5f 74 6f 5f 64 _lats_longs_to_d
16c0: 69 73 74 61 6e 63 65 5f 68 65 61 64 69 6e 67 5f istance_heading_
16d0: 28 52 65 73 74 2c 20 5b 7b 44 69 73 74 61 6e 63 (Rest, [{Distanc
16e0: 65 2c 20 48 65 61 64 69 6e 67 7d 5d 2b 2b 44 69 e, Heading}]++Di
16f0: 73 74 61 6e 63 65 5f 68 65 61 64 69 6e 67 73 5f stance_headings_
1700: 6c 69 73 74 29 3b 0a 63 6f 6e 76 65 72 74 5f 6c list);.convert_l
1710: 61 74 73 5f 6c 6f 6e 67 73 5f 74 6f 5f 64 69 73 ats_longs_to_dis
1720: 74 61 6e 63 65 5f 68 65 61 64 69 6e 67 5f 28 5b tance_heading_([
1730: 5d 2c 20 44 69 73 74 61 6e 63 65 5f 68 65 61 64 ], Distance_head
1740: 69 6e 67 73 5f 6c 69 73 74 29 20 2d 3e 0a 09 6c ings_list) ->..l
1750: 69 73 74 73 3a 72 65 76 65 72 73 65 28 44 69 73 ists:reverse(Dis
1760: 74 61 6e 63 65 5f 68 65 61 64 69 6e 67 73 5f 6c tance_headings_l
1770: 69 73 74 29 2e 0a 0a 0a 6a 6f 75 72 6e 65 79 28 ist)....journey(
1780: 44 69 73 74 61 6e 63 65 5f 68 65 61 64 69 6e 67 Distance_heading
1790: 73 5f 6c 69 73 74 29 20 2d 3e 0a 09 6c 69 73 74 s_list) ->..list
17a0: 73 3a 6d 61 70 28 0a 09 09 66 75 6e 28 7b 44 69 s:map(...fun({Di
17b0: 73 74 61 6e 63 65 2c 20 48 65 61 64 69 6e 67 7d stance, Heading}
17c0: 29 20 2d 3e 0a 09 09 09 43 6f 6d 70 61 73 73 5f ) ->....Compass_
17d0: 64 69 72 65 63 74 69 6f 6e 20 3d 20 67 65 74 5f direction = get_
17e0: 63 6f 6d 70 61 73 73 5f 64 69 72 65 63 74 69 6f compass_directio
17f0: 6e 5f 66 6f 72 28 48 65 61 64 69 6e 67 29 2c 0a n_for(Heading),.
1800: 09 09 09 7b 44 69 73 74 61 6e 63 65 2c 20 43 6f ...{Distance, Co
1810: 6d 70 61 73 73 5f 64 69 72 65 63 74 69 6f 6e 7d mpass_direction}
1820: 0a 09 09 65 6e 64 2c 0a 09 09 44 69 73 74 61 6e ...end,...Distan
1830: 63 65 5f 68 65 61 64 69 6e 67 73 5f 6c 69 73 74 ce_headings_list
1840: 29 2e 0a 0a 0a 72 65 76 65 72 73 65 5f 6a 6f 75 )....reverse_jou
1850: 72 6e 65 79 28 44 69 73 74 61 6e 63 65 5f 68 65 rney(Distance_he
1860: 61 64 69 6e 67 73 5f 6c 69 73 74 29 20 2d 3e 0a adings_list) ->.
1870: 09 25 44 6f 6e 27 74 20 61 63 74 75 61 6c 6c 79 .%Don't actually
1880: 20 6e 65 65 64 20 61 20 63 6f 72 72 65 63 74 6c need a correctl
1890: 79 20 6f 72 64 65 72 65 64 20 72 65 76 65 72 73 y ordered revers
18a0: 65 20 72 6f 75 74 65 2c 20 61 73 20 6c 6f 6e 67 e route, as long
18b0: 20 61 73 20 77 65 20 68 61 76 65 20 64 69 72 65 as we have dire
18c0: 63 74 69 6f 6e 73 20 61 6e 64 20 64 69 73 74 61 ctions and dista
18d0: 6e 63 65 73 2e 0a 09 6c 69 73 74 73 3a 6d 61 70 nces...lists:map
18e0: 28 0a 09 09 66 75 6e 28 7b 44 69 73 74 61 6e 63 (...fun({Distanc
18f0: 65 2c 20 48 65 61 64 69 6e 67 7d 29 20 2d 3e 0a e, Heading}) ->.
1900: 09 09 09 25 42 65 63 61 75 73 65 20 63 61 6e 27 ...%Because can'
1910: 74 20 68 61 76 65 20 66 75 6e 63 74 69 6f 6e 73 t have functions
1920: 20 69 6e 20 67 75 61 72 64 73 0a 09 09 09 50 69 in guards....Pi
1930: 20 3d 20 6d 61 74 68 3a 70 69 28 29 2c 0a 09 09 = math:pi(),...
1940: 09 52 65 76 65 72 73 65 5f 68 65 61 64 69 6e 67 .Reverse_heading
1950: 20 3d 20 69 66 20 48 65 61 64 69 6e 67 20 3c 20 = if Heading <
1960: 50 69 20 2d 3e 0a 09 09 09 09 48 65 61 64 69 6e Pi ->.....Headin
1970: 67 20 2b 20 50 69 3b 0a 09 09 09 48 65 61 64 69 g + Pi;....Headi
1980: 6e 67 20 3e 3d 20 50 69 20 2d 3e 0a 09 09 09 09 ng >= Pi ->.....
1990: 48 65 61 64 69 6e 67 20 2d 20 50 69 0a 09 09 09 Heading - Pi....
19a0: 65 6e 64 2c 0a 09 09 09 43 6f 6d 70 61 73 73 5f end,....Compass_
19b0: 64 69 72 65 63 74 69 6f 6e 20 3d 20 67 65 74 5f direction = get_
19c0: 63 6f 6d 70 61 73 73 5f 64 69 72 65 63 74 69 6f compass_directio
19d0: 6e 5f 66 6f 72 28 52 65 76 65 72 73 65 5f 68 65 n_for(Reverse_he
19e0: 61 64 69 6e 67 29 2c 0a 09 09 09 7b 44 69 73 74 ading),....{Dist
19f0: 61 6e 63 65 2c 20 43 6f 6d 70 61 73 73 5f 64 69 ance, Compass_di
1a00: 72 65 63 74 69 6f 6e 7d 0a 09 09 65 6e 64 2c 0a rection}...end,.
1a10: 09 09 44 69 73 74 61 6e 63 65 5f 68 65 61 64 69 ..Distance_headi
1a20: 6e 67 73 5f 6c 69 73 74 29 2e 0a 0a 0a 67 65 74 ngs_list)....get
1a30: 5f 63 6f 6d 70 61 73 73 5f 64 69 72 65 63 74 69 _compass_directi
1a40: 6f 6e 5f 66 6f 72 28 48 65 61 64 69 6e 67 29 20 on_for(Heading)
1a50: 2d 3e 0a 09 25 49 6e 20 61 20 77 61 79 20 74 68 ->..%In a way th
1a60: 69 73 20 69 73 20 61 20 77 61 73 74 65 20 6f 66 is is a waste of
1a70: 20 74 69 6d 65 20 61 73 20 63 6f 75 6c 64 20 6a time as could j
1a80: 75 73 74 20 64 6f 20 68 65 61 64 77 69 6e 64 2c ust do headwind,
1a90: 20 65 74 63 20 62 61 73 65 64 20 6f 6e 20 61 6e etc based on an
1aa0: 67 6c 65 73 2c 20 62 75 74 20 73 69 6e 63 65 20 gles, but since
1ab0: 61 6c 72 65 61 64 79 20 68 61 76 65 20 73 6f 6d already have som
1ac0: 65 20 63 6f 64 65 2c 20 77 68 79 20 6e 6f 74 3f e code, why not?
1ad0: 0a 09 53 65 67 6d 65 6e 74 20 3d 20 32 2a 6d 61 ..Segment = 2*ma
1ae0: 74 68 3a 70 69 28 29 2f 31 36 2c 0a 09 53 65 67 th:pi()/16,..Seg
1af0: 6d 65 6e 74 73 20 3d 20 65 72 6c 61 6e 67 3a 72 ments = erlang:r
1b00: 6f 75 6e 64 28 48 65 61 64 69 6e 67 2f 53 65 67 ound(Heading/Seg
1b10: 6d 65 6e 74 29 2b 31 2c 0a 09 43 6f 6d 70 61 73 ment)+1,..Compas
1b20: 73 20 3d 20 5b 22 4e 22 2c 20 22 4e 4e 45 22 2c s = ["N", "NNE",
1b30: 20 22 4e 45 22 2c 20 22 45 4e 45 22 2c 20 22 45 "NE", "ENE", "E
1b40: 22 2c 20 22 45 53 45 22 2c 20 22 53 45 22 2c 20 ", "ESE", "SE",
1b50: 22 53 53 45 22 2c 20 22 53 22 2c 20 22 53 53 57 "SSE", "S", "SSW
1b60: 22 2c 20 22 53 57 22 2c 20 22 57 53 57 22 2c 20 ", "SW", "WSW",
1b70: 22 57 22 2c 20 22 57 4e 57 22 2c 20 22 4e 57 22 "W", "WNW", "NW"
1b80: 2c 20 22 4e 4e 57 22 5d 2c 0a 09 25 48 61 6e 64 , "NNW"],..%Hand
1b90: 6c 65 20 74 68 65 20 63 61 73 65 20 6f 66 20 53 le the case of S
1ba0: 65 67 6d 65 6e 74 73 20 3d 20 31 36 2e 20 4e 65 egments = 16. Ne
1bb0: 65 64 20 74 6f 20 77 72 61 70 20 61 72 6f 75 6e ed to wrap aroun
1bc0: 64 2e 0a 09 6e 74 68 5f 77 72 61 70 28 53 65 67 d...nth_wrap(Seg
1bd0: 6d 65 6e 74 73 2c 20 43 6f 6d 70 61 73 73 29 2e ments, Compass).
1be0: 0a 0a 0a 68 65 61 64 5f 73 69 64 65 5f 6f 72 5f ...head_side_or_
1bf0: 74 61 69 6c 5f 77 69 6e 64 28 44 69 72 65 63 74 tail_wind(Direct
1c00: 69 6f 6e 2c 20 5b 48 65 61 64 77 69 6e 64 73 2c ion, [Headwinds,
1c10: 20 53 69 64 65 77 69 6e 64 73 2c 20 54 61 69 6c Sidewinds, Tail
1c20: 77 69 6e 64 73 5d 29 20 2d 3e 0a 09 5b 48 65 61 winds]) ->..[Hea
1c30: 64 77 69 6e 64 2c 20 53 69 64 65 77 69 6e 64 2c dwind, Sidewind,
1c40: 20 54 61 69 6c 77 69 6e 64 5d 20 3d 20 6c 69 73 Tailwind] = lis
1c50: 74 73 3a 6d 61 70 28 0a 09 09 66 75 6e 28 57 69 ts:map(...fun(Wi
1c60: 6e 64 73 29 20 2d 3e 0a 09 09 09 6c 69 73 74 73 nds) ->....lists
1c70: 3a 6d 65 6d 62 65 72 28 44 69 72 65 63 74 69 6f :member(Directio
1c80: 6e 2c 20 57 69 6e 64 73 29 0a 09 09 65 6e 64 2c n, Winds)...end,
1c90: 0a 09 09 5b 48 65 61 64 77 69 6e 64 73 2c 20 53 ...[Headwinds, S
1ca0: 69 64 65 77 69 6e 64 73 2c 20 54 61 69 6c 77 69 idewinds, Tailwi
1cb0: 6e 64 73 5d 29 2c 0a 09 69 66 20 48 65 61 64 77 nds]),..if Headw
1cc0: 69 6e 64 20 2d 3e 0a 09 09 68 65 61 64 77 69 6e ind ->...headwin
1cd0: 64 3b 0a 09 53 69 64 65 77 69 6e 64 20 2d 3e 0a d;..Sidewind ->.
1ce0: 09 09 73 69 64 65 77 69 6e 64 3b 0a 09 54 61 69 ..sidewind;..Tai
1cf0: 6c 77 69 6e 64 20 2d 3e 0a 09 09 74 61 69 6c 77 lwind ->...tailw
1d00: 69 6e 64 0a 09 65 6e 64 2e 0a 25 53 6f 6d 65 74 ind..end..%Somet
1d10: 68 69 6e 67 20 6c 69 6b 65 20 74 68 61 74 3f 0a hing like that?.
1d20: 09 0a 0a 25 46 69 72 73 74 20 74 77 6f 20 66 6f ...%First two fo
1d30: 72 20 63 6f 6d 6d 61 6e 64 20 6c 69 6e 65 20 75 r command line u
1d40: 73 61 67 65 0a 68 65 61 64 73 69 6c 6f 73 65 28 sage.headsilose(
1d50: 5b 4c 6f 63 61 74 69 6f 6e 5d 29 20 2d 3e 0a 09 [Location]) ->..
1d60: 68 65 61 64 73 69 6c 6f 73 65 5f 28 4c 6f 63 61 headsilose_(Loca
1d70: 74 69 6f 6e 29 3b 0a 68 65 61 64 73 69 6c 6f 73 tion);.headsilos
1d80: 65 28 5b 4c 6f 63 61 74 69 6f 6e 2c 20 52 6f 75 e([Location, Rou
1d90: 74 65 5f 63 68 6f 69 63 65 5d 29 20 2d 3e 0a 09 te_choice]) ->..
1da0: 68 65 61 64 73 69 6c 6f 73 65 5f 28 4c 6f 63 61 headsilose_(Loca
1db0: 74 69 6f 6e 2c 20 52 6f 75 74 65 5f 63 68 6f 69 tion, Route_choi
1dc0: 63 65 29 2e 0a 68 65 61 64 73 69 6c 6f 73 65 5f ce)..headsilose_
1dd0: 28 4c 6f 63 61 74 69 6f 6e 29 20 2d 3e 0a 09 25 (Location) ->..%
1de0: 49 66 20 72 6f 75 74 65 20 63 68 6f 69 63 65 20 If route choice
1df0: 6e 6f 74 20 73 70 65 63 69 66 69 65 64 20 64 65 not specified de
1e00: 66 61 75 6c 74 20 74 6f 20 64 65 66 61 75 6c 74 fault to default
1e10: 21 0a 09 25 54 68 65 20 6f 74 68 65 72 20 63 68 !..%The other ch
1e20: 6f 69 63 65 20 69 73 20 22 61 6c 74 65 72 6e 61 oice is "alterna
1e30: 74 69 76 65 5f 67 65 6f 6d 65 74 72 69 65 73 22 tive_geometries"
1e40: 2c 20 66 6f 72 20 6e 6f 77 20 49 20 74 68 69 6e , for now I thin
1e50: 6b 20 74 68 65 72 65 20 69 73 20 6f 6e 6c 79 20 k there is only
1e60: 65 76 65 72 20 6f 6e 65 20 61 6c 74 65 72 6e 61 ever one alterna
1e70: 74 69 76 65 20 73 6f 20 70 69 63 6b 20 74 68 69 tive so pick thi
1e80: 73 20 66 69 72 73 74 2e 0a 09 68 65 61 64 73 69 s first...headsi
1e90: 6c 6f 73 65 5f 28 4c 6f 63 61 74 69 6f 6e 2c 20 lose_(Location,
1ea0: 22 72 6f 75 74 65 5f 67 65 6f 6d 65 74 72 79 22 "route_geometry"
1eb0: 29 2e 0a 68 65 61 64 73 69 6c 6f 73 65 5f 28 4c )..headsilose_(L
1ec0: 6f 63 61 74 69 6f 6e 2c 20 52 6f 75 74 65 5f 63 ocation, Route_c
1ed0: 68 6f 69 63 65 29 20 2d 3e 0a 09 44 61 74 65 5f hoice) ->..Date_
1ee0: 74 6f 64 61 79 20 3d 20 65 72 6c 61 6e 67 3a 6c today = erlang:l
1ef0: 6f 63 61 6c 74 69 6d 65 28 29 2c 0a 09 7b 20 44 ocaltime(),..{ D
1f00: 61 74 65 5f 66 6f 72 6d 61 74 74 65 64 2c 20 52 ate_formatted, R
1f10: 65 70 20 7d 20 3d 20 64 61 74 65 5f 61 6e 64 5f ep } = date_and_
1f20: 72 65 70 28 44 61 74 65 5f 74 6f 64 61 79 29 2c rep(Date_today),
1f30: 0a 09 7b 44 69 72 65 63 74 69 6f 6e 2c 20 53 70 ..{Direction, Sp
1f40: 65 65 64 2c 20 47 75 73 74 2c 20 57 65 61 74 68 eed, Gust, Weath
1f50: 65 72 2c 20 54 65 6d 70 65 72 61 74 75 72 65 7d er, Temperature}
1f60: 20 3d 20 67 65 74 5f 77 65 61 74 68 65 72 28 4c = get_weather(L
1f70: 6f 63 61 74 69 6f 6e 2c 20 20 7b 20 44 61 74 65 ocation, { Date
1f80: 5f 66 6f 72 6d 61 74 74 65 64 2c 20 52 65 70 20 _formatted, Rep
1f90: 7d 29 2c 0a 09 57 65 61 74 68 65 72 5f 74 79 70 }),..Weather_typ
1fa0: 65 20 3d 20 77 65 61 74 68 65 72 5f 74 79 70 65 e = weather_type
1fb0: 73 3a 77 65 61 74 68 65 72 5f 74 79 70 65 28 65 s:weather_type(e
1fc0: 72 6c 61 6e 67 3a 6c 69 73 74 5f 74 6f 5f 69 6e rlang:list_to_in
1fd0: 74 65 67 65 72 28 57 65 61 74 68 65 72 29 29 2c teger(Weather)),
1fe0: 0a 09 5b 48 65 61 64 77 69 6e 64 73 2c 20 53 69 ..[Headwinds, Si
1ff0: 64 65 77 69 6e 64 73 2c 20 54 61 69 6c 77 69 6e dewinds, Tailwin
2000: 64 73 5d 20 3d 20 62 75 69 6c 64 5f 6c 69 73 74 ds] = build_list
2010: 5f 6f 66 5f 77 69 6e 64 5f 64 69 72 65 63 74 69 _of_wind_directi
2020: 6f 6e 73 28 44 69 72 65 63 74 69 6f 6e 29 2c 0a ons(Direction),.
2030: 09 7b 5f 43 68 65 63 6b 73 75 6d 2c 20 50 6f 6c .{_Checksum, Pol
2040: 79 6c 69 6e 65 7d 20 3d 20 6f 73 72 6d 3a 72 65 yline} = osrm:re
2050: 61 64 5f 72 6f 75 74 65 28 52 6f 75 74 65 5f 63 ad_route(Route_c
2060: 68 6f 69 63 65 29 2c 0a 09 50 6f 6c 79 6c 69 6e hoice),..Polylin
2070: 65 5f 64 65 63 6f 64 65 64 20 3d 20 70 6f 6c 79 e_decoded = poly
2080: 6c 69 6e 65 3a 64 65 63 6f 64 65 28 50 6f 6c 79 line:decode(Poly
2090: 6c 69 6e 65 29 2c 0a 09 44 69 73 74 61 6e 63 65 line),..Distance
20a0: 73 5f 61 6e 64 5f 68 65 61 64 69 6e 67 73 5f 6c s_and_headings_l
20b0: 69 73 74 20 3d 20 63 6f 6e 76 65 72 74 5f 6c 61 ist = convert_la
20c0: 74 73 5f 6c 6f 6e 67 73 5f 74 6f 5f 64 69 73 74 ts_longs_to_dist
20d0: 61 6e 63 65 5f 68 65 61 64 69 6e 67 28 50 6f 6c ance_heading(Pol
20e0: 79 6c 69 6e 65 5f 64 65 63 6f 64 65 64 29 2c 0a yline_decoded),.
20f0: 09 25 41 20 62 65 74 74 65 72 20 72 65 70 72 65 .%A better repre
2100: 73 65 6e 74 61 74 69 6f 6e 20 74 68 61 6e 20 33 sentation than 3
2110: 36 30 20 6f 72 20 31 30 38 30 20 77 6f 75 6c 64 60 or 1080 would
2120: 20 62 65 20 62 65 74 74 65 72 20 6e 6f 77 20 74 be better now t
2130: 68 69 73 20 69 73 20 75 73 65 64 20 68 65 72 65 his is used here
2140: 20 61 73 20 77 65 6c 6c 2e 0a 09 4a 6f 75 72 6e as well...Journ
2150: 65 79 20 3d 20 69 66 20 52 65 70 20 3d 3a 3d 20 ey = if Rep =:=
2160: 22 33 36 30 22 20 2d 3e 0a 09 09 6a 6f 75 72 6e "360" ->...journ
2170: 65 79 28 44 69 73 74 61 6e 63 65 73 5f 61 6e 64 ey(Distances_and
2180: 5f 68 65 61 64 69 6e 67 73 5f 6c 69 73 74 29 3b _headings_list);
2190: 0a 09 52 65 70 20 3d 3a 3d 20 22 31 30 38 30 22 ..Rep =:= "1080"
21a0: 20 2d 3e 0a 09 09 72 65 76 65 72 73 65 5f 6a 6f ->...reverse_jo
21b0: 75 72 6e 65 79 28 44 69 73 74 61 6e 63 65 73 5f urney(Distances_
21c0: 61 6e 64 5f 68 65 61 64 69 6e 67 73 5f 6c 69 73 and_headings_lis
21d0: 74 29 0a 09 65 6e 64 2c 0a 09 25 49 66 20 6e 6f t)..end,..%If no
21e0: 77 20 68 61 76 65 20 61 20 73 65 74 20 6f 66 20 w have a set of
21f0: 63 6f 2d 6f 72 64 73 20 6e 65 65 64 20 74 6f 20 co-ords need to
2200: 66 69 67 75 72 65 20 6f 75 74 20 64 69 73 74 61 figure out dista
2210: 6e 63 65 73 20 61 6e 64 20 64 69 72 65 63 74 69 nces and directi
2220: 6f 6e 73 0a 09 44 69 73 74 61 6e 63 65 73 5f 61 ons..Distances_a
2230: 6e 64 5f 77 69 6e 64 5f 74 79 70 65 5f 6c 69 73 nd_wind_type_lis
2240: 74 20 3d 20 6c 69 73 74 73 3a 6d 61 70 28 0a 09 t = lists:map(..
2250: 09 66 75 6e 28 7b 44 69 73 74 61 6e 63 65 2c 20 .fun({Distance,
2260: 43 6f 6d 70 61 73 73 7d 29 20 2d 3e 0a 09 09 09 Compass}) ->....
2270: 57 69 6e 64 5f 74 79 70 65 20 3d 20 68 65 61 64 Wind_type = head
2280: 5f 73 69 64 65 5f 6f 72 5f 74 61 69 6c 5f 77 69 _side_or_tail_wi
2290: 6e 64 28 43 6f 6d 70 61 73 73 2c 20 5b 48 65 61 nd(Compass, [Hea
22a0: 64 77 69 6e 64 73 2c 20 53 69 64 65 77 69 6e 64 dwinds, Sidewind
22b0: 73 2c 20 54 61 69 6c 77 69 6e 64 73 5d 29 2c 0a s, Tailwinds]),.
22c0: 09 09 09 7b 44 69 73 74 61 6e 63 65 2c 20 57 69 ...{Distance, Wi
22d0: 6e 64 5f 74 79 70 65 7d 0a 09 09 65 6e 64 2c 0a nd_type}...end,.
22e0: 09 09 4a 6f 75 72 6e 65 79 29 2c 0a 09 5b 48 65 ..Journey),..[He
22f0: 61 64 77 69 6e 64 5f 64 69 73 74 61 6e 63 65 73 adwind_distances
2300: 2c 20 53 69 64 65 77 69 6e 64 5f 64 69 73 74 61 , Sidewind_dista
2310: 6e 63 65 73 2c 20 54 61 69 6c 77 69 6e 64 5f 64 nces, Tailwind_d
2320: 69 73 74 61 6e 63 65 73 5d 20 3d 20 6c 69 73 74 istances] = list
2330: 73 3a 6d 61 70 28 0a 09 09 66 75 6e 28 57 69 6e s:map(...fun(Win
2340: 64 5f 74 79 70 65 5f 66 69 6c 74 65 72 29 20 2d d_type_filter) -
2350: 3e 0a 09 09 09 6c 69 73 74 73 3a 66 69 6c 74 65 >....lists:filte
2360: 72 28 0a 09 09 09 09 66 75 6e 28 7b 5f 44 69 73 r(.....fun({_Dis
2370: 74 61 6e 63 65 2c 20 57 69 6e 64 5f 74 79 70 65 tance, Wind_type
2380: 7d 29 20 2d 3e 0a 09 09 09 09 09 57 69 6e 64 5f }) ->......Wind_
2390: 74 79 70 65 20 3d 3d 20 57 69 6e 64 5f 74 79 70 type == Wind_typ
23a0: 65 5f 66 69 6c 74 65 72 0a 09 09 09 09 65 6e 64 e_filter.....end
23b0: 2c 0a 09 09 09 09 44 69 73 74 61 6e 63 65 73 5f ,.....Distances_
23c0: 61 6e 64 5f 77 69 6e 64 5f 74 79 70 65 5f 6c 69 and_wind_type_li
23d0: 73 74 29 0a 09 09 65 6e 64 2c 0a 09 09 5b 68 65 st)...end,...[he
23e0: 61 64 77 69 6e 64 2c 20 73 69 64 65 77 69 6e 64 adwind, sidewind
23f0: 2c 20 74 61 69 6c 77 69 6e 64 5d 29 2c 0a 09 5b , tailwind]),..[
2400: 53 75 6d 5f 6f 66 5f 68 65 61 64 77 69 6e 64 5f Sum_of_headwind_
2410: 64 69 73 74 61 6e 63 65 73 2c 20 53 75 6d 5f 6f distances, Sum_o
2420: 66 5f 73 69 64 65 77 69 6e 64 5f 64 69 73 74 61 f_sidewind_dista
2430: 6e 63 65 73 2c 20 53 75 6d 5f 6f 66 5f 74 61 69 nces, Sum_of_tai
2440: 6c 77 69 6e 64 5f 64 69 73 74 61 6e 63 65 73 5d lwind_distances]
2450: 20 3d 20 6c 69 73 74 73 3a 6d 61 70 28 0a 09 09 = lists:map(...
2460: 66 75 6e 28 57 69 6e 64 5f 74 79 70 65 29 20 2d fun(Wind_type) -
2470: 3e 0a 09 09 09 6c 69 73 74 73 3a 66 6f 6c 64 6c >....lists:foldl
2480: 28 0a 09 09 09 09 66 75 6e 28 7b 44 69 73 74 61 (.....fun({Dista
2490: 6e 63 65 2c 20 5f 57 69 6e 64 7d 2c 20 53 75 6d nce, _Wind}, Sum
24a0: 29 20 2d 3e 0a 09 09 09 09 09 44 69 73 74 61 6e ) ->......Distan
24b0: 63 65 20 2b 20 53 75 6d 0a 09 09 09 09 65 6e 64 ce + Sum.....end
24c0: 2c 0a 09 09 09 09 30 2c 0a 09 09 09 09 57 69 6e ,.....0,.....Win
24d0: 64 5f 74 79 70 65 29 0a 09 09 65 6e 64 2c 0a 09 d_type)...end,..
24e0: 09 5b 48 65 61 64 77 69 6e 64 5f 64 69 73 74 61 .[Headwind_dista
24f0: 6e 63 65 73 2c 20 53 69 64 65 77 69 6e 64 5f 64 nces, Sidewind_d
2500: 69 73 74 61 6e 63 65 73 2c 20 54 61 69 6c 77 69 istances, Tailwi
2510: 6e 64 5f 64 69 73 74 61 6e 63 65 73 5d 29 2c 0a nd_distances]),.
2520: 09 54 6f 74 61 6c 5f 64 69 73 74 61 6e 63 65 20 .Total_distance
2530: 3d 20 53 75 6d 5f 6f 66 5f 68 65 61 64 77 69 6e = Sum_of_headwin
2540: 64 5f 64 69 73 74 61 6e 63 65 73 20 2b 20 53 75 d_distances + Su
2550: 6d 5f 6f 66 5f 73 69 64 65 77 69 6e 64 5f 64 69 m_of_sidewind_di
2560: 73 74 61 6e 63 65 73 20 2b 20 53 75 6d 5f 6f 66 stances + Sum_of
2570: 5f 74 61 69 6c 77 69 6e 64 5f 64 69 73 74 61 6e _tailwind_distan
2580: 63 65 73 2c 0a 09 25 44 65 74 65 72 6d 69 6e 65 ces,..%Determine
2590: 20 77 68 69 63 68 20 69 73 20 77 6f 72 73 65 0a which is worse.
25a0: 09 69 66 20 28 53 75 6d 5f 6f 66 5f 68 65 61 64 .if (Sum_of_head
25b0: 77 69 6e 64 5f 64 69 73 74 61 6e 63 65 73 20 3e wind_distances >
25c0: 20 53 75 6d 5f 6f 66 5f 73 69 64 65 77 69 6e 64 Sum_of_sidewind
25d0: 5f 64 69 73 74 61 6e 63 65 73 29 20 61 6e 64 20 _distances) and
25e0: 28 53 75 6d 5f 6f 66 5f 68 65 61 64 77 69 6e 64 (Sum_of_headwind
25f0: 5f 64 69 73 74 61 6e 63 65 73 20 3e 20 53 75 6d _distances > Sum
2600: 5f 6f 66 5f 74 61 69 6c 77 69 6e 64 5f 64 69 73 _of_tailwind_dis
2610: 74 61 6e 63 65 73 29 20 2d 3e 0a 09 09 69 6f 3a tances) ->...io:
2620: 66 6f 72 6d 61 74 28 22 48 65 61 64 73 20 79 6f format("Heads yo
2630: 75 20 6c 6f 73 65 21 7e 6e 22 29 3b 0a 09 28 53 u lose!~n");..(S
2640: 75 6d 5f 6f 66 5f 74 61 69 6c 77 69 6e 64 5f 64 um_of_tailwind_d
2650: 69 73 74 61 6e 63 65 73 20 3e 20 53 75 6d 5f 6f istances > Sum_o
2660: 66 5f 73 69 64 65 77 69 6e 64 5f 64 69 73 74 61 f_sidewind_dista
2670: 6e 63 65 73 29 20 61 6e 64 20 28 53 75 6d 5f 6f nces) and (Sum_o
2680: 66 5f 74 61 69 6c 77 69 6e 64 5f 64 69 73 74 61 f_tailwind_dista
2690: 6e 63 65 73 20 3e 20 53 75 6d 5f 6f 66 5f 68 65 nces > Sum_of_he
26a0: 61 64 77 69 6e 64 5f 64 69 73 74 61 6e 63 65 73 adwind_distances
26b0: 29 20 2d 3e 0a 09 09 69 6f 3a 66 6f 72 6d 61 74 ) ->...io:format
26c0: 28 22 54 61 69 6c 73 20 79 6f 75 20 77 69 6e 21 ("Tails you win!
26d0: 7e 6e 22 29 3b 0a 09 28 53 75 6d 5f 6f 66 5f 73 ~n");..(Sum_of_s
26e0: 69 64 65 77 69 6e 64 5f 64 69 73 74 61 6e 63 65 idewind_distance
26f0: 73 20 3e 3d 20 53 75 6d 5f 6f 66 5f 68 65 61 64 s >= Sum_of_head
2700: 77 69 6e 64 5f 64 69 73 74 61 6e 63 65 73 29 20 wind_distances)
2710: 61 6e 64 20 28 53 75 6d 5f 6f 66 5f 73 69 64 65 and (Sum_of_side
2720: 77 69 6e 64 5f 64 69 73 74 61 6e 63 65 73 20 3e wind_distances >
2730: 3d 20 53 75 6d 5f 6f 66 5f 74 61 69 6c 77 69 6e = Sum_of_tailwin
2740: 64 5f 64 69 73 74 61 6e 63 65 73 29 20 2d 3e 0a d_distances) ->.
2750: 09 09 69 6f 3a 66 6f 72 6d 61 74 28 22 49 74 27 ..io:format("It'
2760: 73 20 61 20 64 72 61 77 7e 6e 22 29 0a 09 65 6e s a draw~n")..en
2770: 64 2c 0a 09 48 65 61 64 77 69 6e 64 5f 70 65 72 d,..Headwind_per
2780: 63 65 6e 74 20 3d 20 72 6f 75 6e 64 28 28 53 75 cent = round((Su
2790: 6d 5f 6f 66 5f 68 65 61 64 77 69 6e 64 5f 64 69 m_of_headwind_di
27a0: 73 74 61 6e 63 65 73 2f 54 6f 74 61 6c 5f 64 69 stances/Total_di
27b0: 73 74 61 6e 63 65 29 2a 31 30 30 2c 20 32 29 2c stance)*100, 2),
27c0: 0a 09 53 69 64 65 77 69 6e 64 5f 70 65 72 63 65 ..Sidewind_perce
27d0: 6e 74 20 3d 20 72 6f 75 6e 64 28 28 53 75 6d 5f nt = round((Sum_
27e0: 6f 66 5f 73 69 64 65 77 69 6e 64 5f 64 69 73 74 of_sidewind_dist
27f0: 61 6e 63 65 73 2f 54 6f 74 61 6c 5f 64 69 73 74 ances/Total_dist
2800: 61 6e 63 65 29 2a 31 30 30 2c 20 32 29 2c 0a 09 ance)*100, 2),..
2810: 54 61 69 6c 77 69 6e 64 5f 70 65 72 63 65 6e 74 Tailwind_percent
2820: 20 3d 20 72 6f 75 6e 64 28 28 53 75 6d 5f 6f 66 = round((Sum_of
2830: 5f 74 61 69 6c 77 69 6e 64 5f 64 69 73 74 61 6e _tailwind_distan
2840: 63 65 73 2f 54 6f 74 61 6c 5f 64 69 73 74 61 6e ces/Total_distan
2850: 63 65 29 2a 31 30 30 2c 20 32 29 2c 0a 09 69 6f ce)*100, 2),..io
2860: 3a 66 6f 72 6d 61 74 28 22 7e 77 25 20 48 65 61 :format("~w% Hea
2870: 64 77 69 6e 64 7e 6e 7e 77 25 20 53 69 64 65 77 dwind~n~w% Sidew
2880: 69 6e 64 7e 6e 7e 77 25 20 54 61 69 6c 77 69 6e ind~n~w% Tailwin
2890: 64 7e 6e 22 2c 20 5b 48 65 61 64 77 69 6e 64 5f d~n", [Headwind_
28a0: 70 65 72 63 65 6e 74 2c 20 53 69 64 65 77 69 6e percent, Sidewin
28b0: 64 5f 70 65 72 63 65 6e 74 2c 20 54 61 69 6c 77 d_percent, Tailw
28c0: 69 6e 64 5f 70 65 72 63 65 6e 74 5d 29 2c 0a 25 ind_percent]),.%
28d0: 0a 09 69 6f 3a 66 6f 72 6d 61 74 28 22 44 69 72 ..io:format("Dir
28e0: 65 63 74 69 6f 6e 3a 20 7e 73 7e 6e 53 70 65 65 ection: ~s~nSpee
28f0: 64 3a 20 7e 73 20 6d 70 68 7e 6e 47 75 73 74 3a d: ~s mph~nGust:
2900: 20 7e 73 20 6d 70 68 7e 6e 57 65 61 74 68 65 72 ~s mph~nWeather
2910: 20 74 79 70 65 3a 20 7e 73 7e 6e 54 65 6d 70 65 type: ~s~nTempe
2920: 72 61 74 75 72 65 3a 20 7e 73 20 64 65 67 20 43 rature: ~s deg C
2930: 7e 6e 22 2c 20 5b 44 69 72 65 63 74 69 6f 6e 2c ~n", [Direction,
2940: 20 53 70 65 65 64 2c 20 47 75 73 74 2c 20 57 65 Speed, Gust, We
2950: 61 74 68 65 72 5f 74 79 70 65 2c 20 54 65 6d 70 ather_type, Temp
2960: 65 72 61 74 75 72 65 5d 29 2e 0a 0a 0a 25 4e 65 erature])....%Ne
2970: 65 64 20 74 6f 20 72 65 61 64 20 41 50 49 20 6b ed to read API k
2980: 65 79 20 66 72 6f 6d 20 66 69 6c 65 0a 72 65 61 ey from file.rea
2990: 64 61 70 69 6b 65 79 28 29 20 2d 3e 0a 09 7b 5f dapikey() ->..{_
29a0: 53 74 61 74 75 73 2c 20 4b 65 79 7d 20 3d 20 66 Status, Key} = f
29b0: 69 6c 65 3a 72 65 61 64 5f 66 69 6c 65 28 6f 73 ile:read_file(os
29c0: 3a 67 65 74 65 6e 76 28 22 48 4f 4d 45 22 29 20 :getenv("HOME")
29d0: 2b 2b 20 22 2f 2e 64 61 74 61 70 6f 69 6e 74 22 ++ "/.datapoint"
29e0: 29 2c 0a 09 73 74 72 69 6e 67 3a 73 74 72 69 70 ),..string:strip
29f0: 28 65 72 6c 61 6e 67 3a 62 69 6e 61 72 79 5f 74 (erlang:binary_t
2a00: 6f 5f 6c 69 73 74 28 4b 65 79 29 2c 72 69 67 68 o_list(Key),righ
2a10: 74 2c 24 5c 6e 29 2e 0a t,$\n)..