-
Notifications
You must be signed in to change notification settings - Fork 21
/
geomath.py
executable file
·128 lines (106 loc) · 3.13 KB
/
geomath.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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#
# geomath.py
#
# some geo coordinate math that I found on the internet
#
#
import math
def HeadingStr(heading):
"""
Gives a heading string given the heading float
"""
headstr = "?"
if heading != None:
if heading < 22.5 or heading >= 337.5:
headstr = "N"
elif heading >=22.5 and heading < 67.5:
headstr = "NE"
elif heading >= 67.5 and heading < 112.5:
headstr = "E"
elif heading >= 112.5 and heading < 157.5:
headstr = "SE"
elif heading >= 157.5 and heading < 202.5:
headstr = "S"
elif heading >= 202.5 and heading < 247.5:
headstr = "SW"
elif heading >= 247.5 and heading < 292.5:
headstr = "W"
elif heading >= 292.5 and heading < 337.5:
headstr = "NW"
return headstr
def knot2mph(k):
"""
Converts knots to miles per hour.
"""
if k == None:
return None
return k * 1.15078
def mi2km(mi):
"""
Converts to miles to kilometers.
"""
if mi == None:
return None
return mi * 1.60934
def mi2nm(mi):
"""
Converts miles to nautical miles
"""
if mi == None:
return None
return mi * 0.868976
def ft2m(ft):
"""
Converts feet to meters.
"""
if ft == None:
return None
return ft * 0.3048
def distance(pointA, pointB):
"""
Calculate the great circle distance between two points
on the earth (specified in decimal degrees)
http://stackoverflow.com/questions/15736995/how-can-i-quickly-estimate-the-distance-between-two-latitude-longitude-points
"""
# convert decimal degrees to radians
lon1, lat1, lon2, lat2 = map(math.radians, [pointA[1], pointA[0], pointB[1], pointB[0]])
# haversine formula
dlon = lon2 - lon1
dlat = lat2 - lat1
a = math.sin(dlat/2)**2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2)**2
c = 2 * math.asin(math.sqrt(a))
r = 3956 # Radius of earth in miles. Use 6371 for kilometers
return c * r
def bearing(pointA, pointB):
"""
Calculates the bearing between two points.
Found here: https://gist.github.com/jeromer/2005586
The formulae used is the following:
θ = atan2(sin(Δlong).cos(lat2),
cos(lat1).sin(lat2) − sin(lat1).cos(lat2).cos(Δlong))
:Parameters:
- `pointA: The tuple representing the latitude/longitude for the
first point. Latitude and longitude must be in decimal degrees
- `pointB: The tuple representing the latitude/longitude for the
second point. Latitude and longitude must be in decimal degrees
:Returns:
The bearing in degrees
:Returns Type:
float
"""
if (type(pointA) != tuple) or (type(pointB) != tuple):
raise TypeError("Only tuples are supported as arguments")
lat1 = math.radians(pointA[0])
lat2 = math.radians(pointB[0])
diffLong = math.radians(pointB[1] - pointA[1])
x = math.sin(diffLong) * math.cos(lat2)
y = math.cos(lat1) * math.sin(lat2) - (math.sin(lat1)
* math.cos(lat2) * math.cos(diffLong))
initial_bearing = math.atan2(x, y)
# Now we have the initial bearing but math.atan2 return values
# from -180° to + 180° which is not what we want for a compass bearing
# The solution is to normalize the initial bearing as shown below
initial_bearing = math.degrees(initial_bearing)
compass_bearing = (initial_bearing + 360) % 360
return compass_bearing