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: trunk, origin/master
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: trunk, origin/master
2014-11-27
19:12
Rename function to something more sensible check-in: 47dd9b33c8 user: base@atomicules.co.uk tags: trunk, origin/master
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to headsilose.erl.

1
2
3
4


5
6
7
8
9
10
11
...
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
-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,
................................................................................
	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).

|


>
>







 







|
|
<
<
<
<


|











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

|


<
>

<
>

<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
|






1
2
3
4
5
6
7
8
9
10
11
12
13
...
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
-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,
................................................................................
	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).