-
Notifications
You must be signed in to change notification settings - Fork 0
/
bearing.py
96 lines (83 loc) · 3.45 KB
/
bearing.py
1
2
3
4
5
6
7
8
9
10
11
12
13
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
########################################################################
#
# This file is part of bearing.
#
# bearing is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# bearing is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with bearing. If not, see <http://www.gnu.org/licenses/>.
#
########################################################################
from geopy import geocoders
import sys
__orig_raw_input__ = raw_input
def raw_input(prompt):
text = __orig_raw_input__(prompt).decode(sys.stdin.encoding)
return text.encode('utf-8')
def input_coordinates(prompt):
position = raw_input(prompt)
g = geocoders.Google()
results = g.geocode(position, exactly_one=False)
while len(results)!=1:
if len(results)==0:
print("No places found under this name, try again")
position = raw_input(prompt)
results = g.geocode(position, exactly_one=False)
else:
print("Multiple options found:")
for (idx, item) in enumerate(results):
print("%3u - %s" % (idx+1, item[0]))
selection = raw_input("Choose one or type 'n' to enter a new place")
if selection=="n":
position = raw_input(prompt)
results = g.geocode(position, exactly_one=False)
else:
# TODO: catch entry of 0 which results in -1
if selection.isdigit() and int(selection)-1 < len(results):
results = [ results[int(selection)-1]]
else:
print "Wrong selection, try again"
# Uuh, this is evil, the user can't choose again, he
# must renter his selection
position = raw_input(prompt)
results = g.geocode(position, exactly_one=False)
return results[0][1]
from math import pi, cos, sin, acos, asin
def deg2rad(deg):
return pi * deg / 180.0
def rad2deg(rad):
return 180.0 * rad / pi
def gps2decimal(gps_tuple):
degree = float(gps_tuple[0])
degree += float(gps_tuple[1] / 60.0)
degree += float(gps_tuple[2] / 3600.0)
return degree
def spherical_beta(angle_alpha, side_b, side_c):
#print("Angle alpha: %f" % rad2deg(angle_alpha))
#print("Side b in degree: %f" % rad2deg(side_b))
#print("Side c in degree: %f" % rad2deg(side_c))
side_a = acos( cos(side_b)*cos(side_c) + sin(side_b)*sin(side_c)*cos(angle_alpha) )
#print("Side a in degree: %f" % rad2deg(side_a))
angle_beta = asin( ( sin(angle_alpha)*sin(side_b) ) / sin(side_a) )
return angle_beta
def bearing(location, target):
loc_N = location[0]
loc_E = location[1]
tgt_N = target[0]
tgt_E = target[1]
alpha = deg2rad( tgt_E - loc_E )
b = deg2rad( 90 - tgt_N )
c = deg2rad( 90 - loc_N )
alpha = spherical_beta( alpha, b, c )
return 180 - rad2deg(alpha)
location = input_coordinates("Your position: ")
target = input_coordinates("Target for bearing: ")
print( "Bearing from your position to the target: %f" % bearing( location, target ) )