Heads-I-Lose

Check-in [9c81571ac3]
Login

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

Overview
Comment: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}).

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk | origin/master
Files: files | file ages | folders
SHA3-256: 9c81571ac3f9d034088ce7f84a95d70db7320b90efb17b9314b868f458bcf73e
User & Date: base@atomicules.co.uk 2014-12-26 22:15:31
Context
2018-06-05
10:56
Formatting Leaf check-in: 64b10ac7d9 user: noreply@github.com tags: master, trunk
2014-12-26
22:15
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}). Leaf check-in: 9c81571ac3 user: base@atomicules.co.uk tags: origin/master, trunk

2014-12-14
21:54
Remove some redundant comments check-in: 0c4224822a user: base@atomicules.co.uk tags: origin/master, trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to README.md.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39


40
41
42
43
44
45
46
47
6. Run `erl -run headsilose headsilose <location id> -noshell` to get the result.

Since I wrote this to be semi-useful for me, the result returned depends on the time of the day. If it's run before 8am it looks for the 6am weather data (since data is in 3 hour periods) and assumes the route is being traversed normally, run between 8am and 7pm it looks for the 6pm data for going home and therefore also traverses the saved route in reverse, and run after that time it looks again for the 6am data, but for the next day, and thus the route is back to being traversed in the normal direction.

_Hint:_ I have a shell function defined as follows:

	function headsilose {
		erl -pa /home/simon/Code/github/atomicules/heads-I-lose /home/simon/Code/github/atomicules/heads-I-lose/ebin -run headsilose headsilose XXXXXX -noshell;
	}

So I can just call

	headsilose

Which will result in something like the following being printed out:

	It's a draw
	47.1% Headwind
	51.45% Sidewind
	1.45% Tailwind
	Direction: SSW
	Speed: 13 mph
	Gust: 29 mph
	Weather type: Cloudy
	Temperature: 4 deg C



_Note:_ I don't use [init stop](http://erlangcentral.org/wiki/index.php?title=Running_Erlang_Code_From_The_Command_Line&oldid=2293) in my main command line call as I have that in my script instead. Otherwise, if `headsilose` errors out then `init stop` will crash out (I guess because it is trying to stop something that isn't running).

##Credits

Various posts I've found that have helped me out:

- Initial inspiration from [PragDave - A First Erlang Program](http://pragdave.pragprog.com/pragdave/2007/04/a_first_erlang_.html)
- Putting initial inspiration to practice (i.e. `inets:start`) from [Andrew Locatelli Woodcock - Connecting to Cloudant from Erlang: a quick example of using HTTPS from httpc:request](http://andrewlocatelliwoodcock.com/2012/06/12/connecting-to-cloudant-from-erlang-a-quick-example-of-using-https-from-httpcrequest-17-2/)







|


















>
>
|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
6. Run `erl -run headsilose headsilose <location id> -noshell` to get the result.

Since I wrote this to be semi-useful for me, the result returned depends on the time of the day. If it's run before 8am it looks for the 6am weather data (since data is in 3 hour periods) and assumes the route is being traversed normally, run between 8am and 7pm it looks for the 6pm data for going home and therefore also traverses the saved route in reverse, and run after that time it looks again for the 6am data, but for the next day, and thus the route is back to being traversed in the normal direction.

_Hint:_ I have a shell function defined as follows:

	function headsilose {
		erl -pa /home/simon/Code/github/atomicules/heads-I-lose /home/simon/Code/github/atomicules/heads-I-lose/ebin -run headsilose headsilose XXXXXX alternative_geometries -noshell;
	}

So I can just call

	headsilose

Which will result in something like the following being printed out:

	It's a draw
	47.1% Headwind
	51.45% Sidewind
	1.45% Tailwind
	Direction: SSW
	Speed: 13 mph
	Gust: 29 mph
	Weather type: Cloudy
	Temperature: 4 deg C

_Note1:_ Since the route is from OSRM there is the option to specify `alternative_geometries` as an argument. In theory OSRM can return more than one alternative route, but in practice (at least as far as I can tell) I think it only ever returns one alternative route so although the argument is `alternative_geometries` it is actually the first alternative that is used. If `alternative_geometries` is not specified then the default route is used. If you'd like to see visually which route is the default and which is the alternative you can see them at [Project OSRM](http://map.project-osrm.org/) as routes A (default) and B (alternative).

_Note2:_ I don't use [init stop](http://erlangcentral.org/wiki/index.php?title=Running_Erlang_Code_From_The_Command_Line&oldid=2293) in my main command line call as I have that in my script instead. Otherwise, if `headsilose` errors out then `init stop` will crash out (I guess because it is trying to stop something that isn't running).

##Credits

Various posts I've found that have helped me out:

- Initial inspiration from [PragDave - A First Erlang Program](http://pragdave.pragprog.com/pragdave/2007/04/a_first_erlang_.html)
- Putting initial inspiration to practice (i.e. `inets:start`) from [Andrew Locatelli Woodcock - Connecting to Cloudant from Erlang: a quick example of using HTTPS from httpc:request](http://andrewlocatelliwoodcock.com/2012/06/12/connecting-to-cloudant-from-erlang-a-quick-example-of-using-https-from-httpcrequest-17-2/)

Changes to headsilose.erl.

1
2
3
4
5
6
7
8
9
10
11
12
13
-module(headsilose).
-export([get_locations/0, get_locations/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,





|







1
2
3
4
5
6
7
8
9
10
11
12
13
-module(headsilose).
-export([get_locations/0, get_locations/1, headsilose/1]).
-include_lib("xmerl/include/xmerl.hrl").
-import(weather_types, [weather_type/1]).
-import(polyline, [decode/1]).
-import(osrm, [read_route/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,
227
228
229
230
231
232
233





234




235
236
237
238
239
240
241
242
243
244
245
246
247
		sidewind;
	Tailwind ->
		tailwind
	end.
%Something like that?
	






headsilose(Location) ->




	Date_today = erlang:localtime(),
	{ Date_formatted, Rep } = date_and_rep(Date_today),
	{Direction, Speed, Gust, Weather, Temperature} = get_weather(Location,  { Date_formatted, Rep }),
	Weather_type = weather_types:weather_type(erlang:list_to_integer(Weather)),
	[Headwinds, Sidewinds, Tailwinds] = build_list_of_wind_directions(Direction),
	{_Checksum, Polyline} = osrm:read_route(),
	Polyline_decoded = polyline:decode(Polyline),
	Distances_and_headings_list = convert_lats_longs_to_distance_heading(Polyline_decoded),
	%A better representation than 360 or 1080 would be better now this is used here as well.
	Journey = if Rep =:= "360" ->
		journey(Distances_and_headings_list);
	Rep =:= "1080" ->
		reverse_journey(Distances_and_headings_list)







>
>
>
>
>
|
>
>
>
>





|







227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
		sidewind;
	Tailwind ->
		tailwind
	end.
%Something like that?
	

%First two for command line usage
headsilose([Location]) ->
	headsilose_(Location);
headsilose([Location, Route_choice]) ->
	headsilose_(Location, Route_choice).
headsilose_(Location) ->
	%If route choice not specified default to default!
	%The other choice is "alternative_geometries", for now I think there is only ever one alternative so pick this first.
	headsilose_(Location, "route_geometry").
headsilose_(Location, Route_choice) ->
	Date_today = erlang:localtime(),
	{ Date_formatted, Rep } = date_and_rep(Date_today),
	{Direction, Speed, Gust, Weather, Temperature} = get_weather(Location,  { Date_formatted, Rep }),
	Weather_type = weather_types:weather_type(erlang:list_to_integer(Weather)),
	[Headwinds, Sidewinds, Tailwinds] = build_list_of_wind_directions(Direction),
	{_Checksum, Polyline} = osrm:read_route(Route_choice),
	Polyline_decoded = polyline:decode(Polyline),
	Distances_and_headings_list = convert_lats_longs_to_distance_heading(Polyline_decoded),
	%A better representation than 360 or 1080 would be better now this is used here as well.
	Journey = if Rep =:= "360" ->
		journey(Distances_and_headings_list);
	Rep =:= "1080" ->
		reverse_journey(Distances_and_headings_list)

Changes to osrm.erl.

1
2
3
4
5
6
7
8
9
-module(osrm).
-export([get_route/1, get_route/2, read_route/0]).
-import(polyline, [decode/1]).

%https://github.com/Project-OSRM/osrm-backend/wiki/Server-api
%For now, get weather for one location (probably good enough as relatively short distances weather wise; ultimately consider time as well?)
%To get lats and longs could also do a query for here: http://www.uk-postcodes.com/ (json again)

-define(BASE_URL,

|







1
2
3
4
5
6
7
8
9
-module(osrm).
-export([get_route/1, get_route/2, read_route/1]).
-import(polyline, [decode/1]).

%https://github.com/Project-OSRM/osrm-backend/wiki/Server-api
%For now, get weather for one location (probably good enough as relatively short distances weather wise; ultimately consider time as well?)
%To get lats and longs could also do a query for here: http://www.uk-postcodes.com/ (json again)

-define(BASE_URL,
34
35
36
37
38
39
40
41
42
43
44
45

46





47
48
49
50
51
52
53
			io:format("API Might be down~n"),
			Reason
	after
		maybe_quit()
	end.


read_route() ->
	{_Status, Route} = file:read_file(os:getenv("HOME") ++ "/.headsilose_route"),
	%Use jiffy
	%http://www.snip2code.com/Snippet/51463/how-to-support-chinese-in-http-request-b/
	{ Props } = jiffy:decode(Route),

	Route_geometry = proplists:get_value(<<"route_geometry">>, Props),





	%That is all for now? Because...
	%And these don't seem to actually be returned, hence having to go down the route of polyline decoding
	%Route_Instructions = proplists:get_value(<<"route_instructions">>, Props),
	%Total_Distance = proplists:get_value(<<"total_distance">>, proplists:get_value(<<"route_summary">>, Props)),
	%And need to figure out how to get nested values. I.e like xpath. Just nest the queries? Nope that doesn't work
	%Like so:
	{Hint_data} = proplists:get_value(<<"hint_data">>, Props),







|




>
|
>
>
>
>
>







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
			io:format("API Might be down~n"),
			Reason
	after
		maybe_quit()
	end.


read_route(Route_choice) ->
	{_Status, Route} = file:read_file(os:getenv("HOME") ++ "/.headsilose_route"),
	%Use jiffy
	%http://www.snip2code.com/Snippet/51463/how-to-support-chinese-in-http-request-b/
	{ Props } = jiffy:decode(Route),
	Route_geometry = if Route_choice =:= "route_geometry" ->
		proplists:get_value(binary:list_to_bin(Route_choice), Props);
	Route_choice =:= "alternative_geometries" ->
		%hd only if alternative though!
		%for now I think there is only ever one alternative so that is why we pick hd
		hd(proplists:get_value(binary:list_to_bin(Route_choice), Props))
	end,
	%That is all for now? Because...
	%And these don't seem to actually be returned, hence having to go down the route of polyline decoding
	%Route_Instructions = proplists:get_value(<<"route_instructions">>, Props),
	%Total_Distance = proplists:get_value(<<"total_distance">>, proplists:get_value(<<"route_summary">>, Props)),
	%And need to figure out how to get nested values. I.e like xpath. Just nest the queries? Nope that doesn't work
	%Like so:
	{Hint_data} = proplists:get_value(<<"hint_data">>, Props),