Heads-I-Lose

Check-in [3a98087e88]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:WIP - 1st attempt at bringing together polyline and OSRM functionality

Compiles, but doesn't yet run.

The general principle is that it will get a previously saved polyline
and convert this into a list of compass headings and distances. It will
then sum up the distances of head, side and tail winds to see which
wins.

For the time being I'm focusing on summing up headwinds only.

Adds the following functions:

- build_list_of_wind_directions

Previously this didn't exist as a standalone function, rather it was
built into the main headsilose routine. Before it was fed with a
direction of travel and based on this it would work out which 16 point
compass headings were head, side or tail winds. Now it needs to work a
bit in reverse (although I haven't made the necessary changes yet - I
don't think1) and instead feed it with the actual wind direction and
it will use this to build the list of head, side and tail winds.

- get_compass_direction_for

Convert an angle into a 16-point compass direction

- head_side_or_tail_wind

Decided whether, for a given direction of heading, it is a head, side
or tailwind. Uses the lists from build_list_of_wind_directions.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk | origin/master
Files: files | file ages | folders
SHA3-256: 3a98087e8802f674bc5eae704f1e0a239150ed2d814e9fa8c5f6162483c90127
User & Date: base@atomicules.co.uk 2014-11-28 20:12:25
Context
2014-11-28
21:03
Do head | tail properly

Wasn't thinking straight when I first wrote that, obviously check-in: 5c494abd30 user: base@atomicules.co.uk tags: origin/master, trunk

20:12
WIP - 1st attempt at bringing together polyline and OSRM functionality

Compiles, but doesn't yet run.

The general principle is that it will get a previously saved polyline
and convert this into a list of compass headings and distances. It will
then sum up the distances of head, side and tail winds to see which
wins.

For the time being I'm focusing on summing up headwinds only.

Adds the following functions:

- build_list_of_wind_directions

Previously this didn't exist as a standalone function, rather it was
built into the main headsilose routine. Before it was fed with a
direction of travel and based on this it would work out which 16 point
compass headings were head, side or tail winds. Now it needs to work a
bit in reverse (although I haven't made the necessary changes yet - I
don't think1) and instead feed it with the actual wind direction and
it will use this to build the list of head, side and tail winds.

- get_compass_direction_for

Convert an angle into a 16-point compass direction

- head_side_or_tail_wind

Decided whether, for a given direction of heading, it is a head, side
or tailwind. Uses the lists from build_list_of_wind_directions.
check-in: 3a98087e88 user: base@atomicules.co.uk tags: origin/master, trunk
2014-11-27
19:12
Rename function to something more sensible check-in: 47dd9b33c8 user: base@atomicules.co.uk tags: origin/master, trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to headsilose.erl.

1
2
3
4


5
6
7
8
9
10
11
-module(headsilose).
-export([get_locations/0, get_locations/1, get_weather/1, headsilose/2, headsilose/1]).
-include_lib("xmerl/include/xmerl.hrl").
-import(weather_types, [weather_type/1]).



%Supply a direction and location and work out if head wind or not
%For now "know the location id" upfront, but ideally need to search for it at some point or present a choice.

%Initially based on: http://pragdave.pragprog.com/pragdave/2007/04/a_first_erlang_.html 

-define(BASE_URL,

|


>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
-module(headsilose).
-export([get_locations/0, get_locations/1, get_weather/1, headsilose/1]).
-include_lib("xmerl/include/xmerl.hrl").
-import(weather_types, [weather_type/1]).
-import(polyline, [decode/1]).
-import(osrm, [read_route/0]).

%Supply a direction and location and work out if head wind or not
%For now "know the location id" upfront, but ideally need to search for it at some point or present a choice.

%Initially based on: http://pragdave.pragprog.com/pragdave/2007/04/a_first_erlang_.html 

-define(BASE_URL,
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
























156
157
158
159
160
161
162

163



164














165








166
167
168
169
170
171
172
	Found = lists:keyfind(noshell, 1, Args),
	if Found =:= false ->
		dont_quit;
	true -> init:stop()
	end.	


%For command line usage, from http://stackoverflow.com/a/8498073/208793
headsilose([Location, Heading]) ->
	headsilose(Location, Heading).
headsilose(Location, Heading) ->
	{Direction, Speed, Gust, Weather, Temperature} = get_weather(Location),
	Weather_type = weather_types:weather_type(erlang:list_to_integer(Weather)),
	Compass = ["N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"],
	%Quicker dirtier(?) way to do below would be: http://stackoverflow.com/a/6762191/208793
	Index = length(lists:takewhile(fun(X) -> X  =/= Direction end, Compass))+1,
	%Since heading is to direction and winds are from, opposite is -2 to +2, or to make it easier to wrap, +14 +18
	%Since heading is to direction and winds are from, sidewinds are -5 to -3 and +3 to +5, or to make it easier to wrap, +14 +18
	%And so on
	HeadwindList = lists:seq(14,18),
	SidewindList = lists:seq(3,5)++lists:seq(11,13),
	TailwindList = lists:seq(6,10),
	[Headwinds, Sidewinds, Tailwinds] = lists:map(fun(WindList) ->
		lists:map(fun(X) ->
			nth_wrap(Index+X, Compass) end,
			WindList)
		end,
		[HeadwindList, SidewindList, TailwindList]),
























	[Headwind, Sidewind, Tailwind] = lists:map(fun(Winds) ->
		lists:member(Heading, Winds) end,
		[Headwinds, Sidewinds, Tailwinds]),
	if Headwind ->
		io:format("Heads you lose!~n");
	Sidewind ->
		io:format("It's a draw~n");

	Tailwind ->



		io:format("Tails you win!~n")














	end,








	io:format("Direction: ~s~nSpeed: ~s mph~nGust: ~s mph~nWeather type: ~s~nTemperature: ~s deg C~n", [Direction, Speed, Gust, Weather_type, Temperature]).


%Need to read API key from file
readapikey() ->
	{_Status, KeyB} = file:read_file(os:getenv("HOME") ++ "/.datapoint"),
	string:strip(erlang:binary_to_list(KeyB),right,$\n).







<
|
<
<
|
<


|











|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|


|

<
>

>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
|






130
131
132
133
134
135
136

137


138

139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
	Found = lists:keyfind(noshell, 1, Args),
	if Found =:= false ->
		dont_quit;
	true -> init:stop()
	end.	



build_list_of_wind_directions(Wind_direction) ->


	%There is only one wind direction, but can build groups of directions that will count as head, side and tail winds

	Compass = ["N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"],
	%Quicker dirtier(?) way to do below would be: http://stackoverflow.com/a/6762191/208793
	Index = length(lists:takewhile(fun(X) -> X  =/= Wind_direction end, Compass))+1,
	%Since heading is to direction and winds are from, opposite is -2 to +2, or to make it easier to wrap, +14 +18
	%Since heading is to direction and winds are from, sidewinds are -5 to -3 and +3 to +5, or to make it easier to wrap, +14 +18
	%And so on
	HeadwindList = lists:seq(14,18),
	SidewindList = lists:seq(3,5)++lists:seq(11,13),
	TailwindList = lists:seq(6,10),
	[Headwinds, Sidewinds, Tailwinds] = lists:map(fun(WindList) ->
		lists:map(fun(X) ->
			nth_wrap(Index+X, Compass) end,
			WindList)
		end,
		[HeadwindList, SidewindList, TailwindList]).


convert_lats_longs_to_distance_heading([_, _, Rest])  -> 
	%All co-ords are diff, so just ignore first two
	convert_lats_longs_to_distance_heading_(Rest, []).
convert_lats_longs_to_distance_heading_([Lat, Lon, Rest], List_distance_headings) ->
	%Want to map through the list convert co-ords to distance and heading
	Distance = math:sqrt(math:pow(Lat,2) + math:pow(Lon,2)),
	Heading = math:atan2(Lon, Lat),
	Compass_direction = get_compass_direction_for(Heading),
	convert_lats_longs_to_distance_heading_(Rest, [{Distance, Compass_direction}]++List_distance_headings);
convert_lats_longs_to_distance_heading_([], List_distance_headings) ->
	lists:reverse(List_distance_headings).


get_compass_direction_for(Heading) ->
	%In a way this is a waste of time as could just do headwind, etc based on angles, but since already have some code, why not?
	Segment = 2*math:pi()/16,
	Segments = erlang:round(Heading/Segment),
	Compass = ["N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"],
	lists:nth(Segments, Compass).


head_side_or_tail_wind(Direction, [Headwinds, Sidewinds, Tailwinds]) ->
	[Headwind, Sidewind, Tailwind] = lists:map(fun(Winds) ->
		lists:member(Direction, Winds) end,
		[Headwinds, Sidewinds, Tailwinds]),
	if Headwind ->
		headwind;
	Sidewind ->

		sidewind;
	Tailwind ->
		tailwind
	end.
%Something like that?
	

headsilose(Location) ->
	{Direction, Speed, Gust, Weather, Temperature} = get_weather(Location),
	Weather_type = weather_types:weather_type(erlang:list_to_integer(Weather)),
	[Headwinds, Sidewinds, Tailwinds] = build_list_of_wind_directions(Direction),
	%Ok so now map this list over (like previous function) the headings list to get list of head, side, tail and distances?

	{_Checksum, Polyline} = osrm:read_route(),
	Polyline_decoded = polyline:decode(Polyline),
	List_of_distances_and_compass = convert_lats_longs_to_distance_heading(Polyline_decoded),
	%If now have a set of co-ords need to figure out distances and directions
	List_of_distances_and_wind = lists:map(fun({Compass, Distance}) ->
			Wind = head_side_or_tail_wind(Compass, [Headwinds, Sidewinds, Tailwinds]),
			{Wind, Distance}
		end,
		List_of_distances_and_compass),
	%lists:map to get distnaces only? Could also map each of the winds?
	%Figure out for headwinds only for now
	Headw = lists:filter(fun({Element, _}) ->
		Element == headwind end,
		List_of_distances_and_wind),
	Sum_of_Headw = lists:foldl(fun({_wind, Distance}, Sum) -> Distance + Sum end, 0, Headw),
	io:format(Sum_of_Headw).
	%io:format("Direction: ~s~nSpeed: ~s mph~nGust: ~s mph~nWeather type: ~s~nTemperature: ~s deg C~n", [Direction, Speed, Gust, Weather_type, Temperature]).


%Need to read API key from file
readapikey() ->
	{_Status, KeyB} = file:read_file(os:getenv("HOME") ++ "/.datapoint"),
	string:strip(erlang:binary_to_list(KeyB),right,$\n).