1
|
|
|
<?php |
2
|
|
|
/*************************************************************************** |
3
|
|
|
* for license information see LICENSE.md |
4
|
|
|
* |
5
|
|
|
* |
6
|
|
|
* In lib2 this file is always included via common.inc.php. |
7
|
|
|
* Also used in lib1. |
8
|
|
|
***************************************************************************/ |
9
|
|
|
|
10
|
|
|
class geomath |
11
|
|
|
{ |
12
|
|
|
public static function calcBearing($lat1, $lon1, $lat2, $lon2) |
13
|
|
|
{ |
14
|
|
|
// Input sind Breite/Laenge in Altgrad |
15
|
|
|
// Der Fall lat/lon1 == lat/lon2 sollte vorher abgefangen werden, |
16
|
|
|
// zB. ueber die Abfrage der Distanz, dass Bearing nur bei Distanz > 5m |
17
|
|
|
// geholt wird, sonst = false gesetzt wird... |
18
|
|
|
if ($lat1 == $lat2 && $lon1 == $lon2) { |
19
|
|
|
return false; |
20
|
|
|
} |
21
|
|
|
$pi = 3.141592653589793238462643383279502884197; |
22
|
|
|
|
23
|
|
|
if ($lat1 == $lat2) { |
24
|
|
|
$lat1 += 0.0000166; |
25
|
|
|
} |
26
|
|
|
if ($lon1 == $lon2) { |
27
|
|
|
$lon1 += 0.0000166; |
28
|
|
|
} |
29
|
|
|
|
30
|
|
|
$rad_lat1 = $lat1 / 180.0 * $pi; |
31
|
|
|
$rad_lon1 = $lon1 / 180.0 * $pi; |
32
|
|
|
$rad_lat2 = $lat2 / 180.0 * $pi; |
33
|
|
|
$rad_lon2 = $lon2 / 180.0 * $pi; |
34
|
|
|
|
35
|
|
|
$delta_lon = $rad_lon2 - $rad_lon1; |
36
|
|
|
$bearing = atan2( |
37
|
|
|
sin($delta_lon) * cos($rad_lat2), |
38
|
|
|
cos($rad_lat1) * sin($rad_lat2) - sin($rad_lat1) * cos($rad_lat2) * cos($delta_lon) |
39
|
|
|
); |
40
|
|
|
$bearing = 180.0 * $bearing / $pi; |
41
|
|
|
|
42
|
|
|
// Output Richtung von lat/lon1 nach lat/lon2 in Altgrad von -180 bis +180 |
43
|
|
|
// wenn man Output von 0 bis 360 haben moechte, kann man dies machen: |
44
|
|
|
if ($bearing < 0.0) { |
45
|
|
|
$bearing = $bearing + 360.0; |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
return $bearing; |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* @param $parBearing |
53
|
|
|
* @param int $parShortText |
54
|
|
|
* @param $language |
55
|
|
|
* @return string |
56
|
|
|
*/ |
57
|
|
|
public static function Bearing2Text($parBearing, $parShortText, $language) |
58
|
|
|
{ |
59
|
|
|
global $translate; |
60
|
|
|
|
61
|
|
|
if ($parShortText == 0) { |
62
|
|
|
if ($parBearing === false) { |
63
|
|
|
return 'N/A'; |
64
|
|
|
} elseif (($parBearing < 11.25) || ($parBearing > 348.75)) { |
65
|
|
|
$bearing = 'north'; |
66
|
|
|
} elseif ($parBearing < 33.75) { |
67
|
|
|
$bearing = 'north-northeast'; |
68
|
|
|
} elseif ($parBearing < 56.25) { |
69
|
|
|
$bearing = 'northeast'; |
70
|
|
|
} elseif ($parBearing < 78.75) { |
71
|
|
|
$bearing = 'east-northeast'; |
72
|
|
|
} elseif ($parBearing < 101.25) { |
73
|
|
|
$bearing = 'east'; |
74
|
|
|
} elseif ($parBearing < 123.75) { |
75
|
|
|
$bearing = 'east-southeast'; |
76
|
|
|
} elseif ($parBearing < 146.25) { |
77
|
|
|
$bearing = 'southeast'; |
78
|
|
|
} elseif ($parBearing < 168.75) { |
79
|
|
|
$bearing = 'south-southeast'; |
80
|
|
|
} elseif ($parBearing < 191.25) { |
81
|
|
|
$bearing = 'south'; |
82
|
|
|
} elseif ($parBearing < 213.75) { |
83
|
|
|
$bearing = 'south-southwest'; |
84
|
|
|
} elseif ($parBearing < 236.25) { |
85
|
|
|
$bearing = 'southwest'; |
86
|
|
|
} elseif ($parBearing < 258.75) { |
87
|
|
|
$bearing = 'west-southwest'; |
88
|
|
|
} elseif ($parBearing < 281.25) { |
89
|
|
|
$bearing = 'west'; |
90
|
|
|
} elseif ($parBearing < 303.75) { |
91
|
|
|
$bearing = 'west-northwest'; |
92
|
|
|
} elseif ($parBearing < 326.25) { |
93
|
|
|
$bearing = 'northwest'; |
94
|
|
|
} elseif ($parBearing <= 348.75) { |
95
|
|
|
$bearing = 'north-northwest'; |
96
|
|
|
} else { |
97
|
|
|
return 'N/A'; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
return $translate->t($bearing, '', '', 0, '', 1, $language); |
101
|
|
|
} |
102
|
|
|
if ($parBearing === false) { |
103
|
|
|
return 'N/A'; |
104
|
|
|
} elseif (($parBearing < 11.25) || ($parBearing > 348.75)) { |
105
|
|
|
$bearing = 'N'; |
106
|
|
|
} elseif ($parBearing < 33.75) { |
107
|
|
|
$bearing = 'NNE'; |
108
|
|
|
} elseif ($parBearing < 56.25) { |
109
|
|
|
$bearing = 'NE'; |
110
|
|
|
} elseif ($parBearing < 78.75) { |
111
|
|
|
$bearing = 'ENE'; |
112
|
|
|
} elseif ($parBearing < 101.25) { |
113
|
|
|
$bearing = 'E'; |
114
|
|
|
} elseif ($parBearing < 123.75) { |
115
|
|
|
$bearing = 'ESE'; |
116
|
|
|
} elseif ($parBearing < 146.25) { |
117
|
|
|
$bearing = 'SE'; |
118
|
|
|
} elseif ($parBearing < 168.75) { |
119
|
|
|
$bearing = 'SSE'; |
120
|
|
|
} elseif ($parBearing < 191.25) { |
121
|
|
|
$bearing = 'S'; |
122
|
|
|
} elseif ($parBearing < 213.75) { |
123
|
|
|
$bearing = 'SSW'; |
124
|
|
|
} elseif ($parBearing < 236.25) { |
125
|
|
|
$bearing = 'SW'; |
126
|
|
|
} elseif ($parBearing < 258.75) { |
127
|
|
|
$bearing = 'WSW'; |
128
|
|
|
} elseif ($parBearing < 281.25) { |
129
|
|
|
$bearing = 'W'; |
130
|
|
|
} elseif ($parBearing < 303.75) { |
131
|
|
|
$bearing = 'WNW'; |
132
|
|
|
} elseif ($parBearing < 326.25) { |
133
|
|
|
$bearing = 'NW'; |
134
|
|
|
} elseif ($parBearing <= 348.75) { |
135
|
|
|
$bearing = 'NNW'; |
136
|
|
|
} else { |
137
|
|
|
return 'N/A'; |
138
|
|
|
} |
139
|
|
|
$tb = ''; |
140
|
|
|
$max = strlen($bearing); |
141
|
|
|
for ($i = 0; $i < $max; ++ $i) { |
142
|
|
|
$tb .= $translate->t($bearing[$i], '', '', 0, '', 1, $language); |
143
|
|
|
} |
144
|
|
|
// Translation of N S W E does not work, for whatever reason. |
145
|
|
|
// But this is currently not in use. |
146
|
|
|
return $tb; |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
public static function calcDistance($latFrom, $lonFrom, $latTo, $lonTo, $distanceMultiplier = 1) |
150
|
|
|
{ |
151
|
|
|
return acos( |
152
|
|
|
cos((90 - $latFrom) * 3.14159 / 180) * cos((90 - $latTo) * 3.14159 / 180) + sin( |
153
|
|
|
(90 - $latFrom) * 3.14159 / 180 |
154
|
|
|
) * sin((90 - $latTo) * 3.14159 / 180) * cos(($lonFrom - $lonTo) * 3.14159 / 180) |
155
|
|
|
) * 6370 * $distanceMultiplier; |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
public static function getSqlDistanceFormula( |
159
|
|
|
$lonFrom, |
160
|
|
|
$latFrom, |
161
|
|
|
$maxDistance, |
162
|
|
|
$distanceMultiplier = 1, |
163
|
|
|
$lonField = 'longitude', |
164
|
|
|
$latField = 'latitude', |
165
|
|
|
$tableName = 'caches' |
166
|
|
|
) { |
167
|
|
|
$lonFrom += 0; |
168
|
|
|
$latFrom += 0; |
169
|
|
|
$maxDistance += 0; |
170
|
|
|
$distanceMultiplier += 0; |
171
|
|
|
|
172
|
|
|
if (!mb_ereg_match('^[a-zA-Z][a-zA-Z0-9_]{0,59}$', $lonField)) { |
173
|
|
|
die('Fatal Error: invalid lonField'); |
174
|
|
|
} |
175
|
|
|
if (!mb_ereg_match('^[a-zA-Z][a-zA-Z0-9_]{0,59}$', $latField)) { |
176
|
|
|
die('Fatal Error: invalid latField'); |
177
|
|
|
} |
178
|
|
|
if (!mb_ereg_match('^[a-zA-Z][a-zA-Z0-9_]{0,59}$', $tableName)) { |
179
|
|
|
die('Fatal Error: invalid tableName'); |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
$b1_rad = (90 - $latFrom) * 3.14159 / 180; |
183
|
|
|
$l1_deg = $lonFrom; |
184
|
|
|
|
185
|
|
|
$lonField = '`' . sql_escape_backtick($tableName) . '`.`' . sql_escape_backtick($lonField) . '`'; |
|
|
|
|
186
|
|
|
$latField = '`' . sql_escape_backtick($tableName) . '`.`' . sql_escape_backtick($latField) . '`'; |
|
|
|
|
187
|
|
|
|
188
|
|
|
$r = 6370 * $distanceMultiplier; |
189
|
|
|
|
190
|
|
|
$retval = 'acos(cos(' . $b1_rad . ') * cos((90-' . $latField . ') * 3.14159 / 180) + sin(' . $b1_rad . ') * sin((90-' . $latField . ') * 3.14159 / 180) * cos((' . $l1_deg . '-' . $lonField . ') * 3.14159 / 180)) * ' . $r; |
191
|
|
|
|
192
|
|
|
return $retval; |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
public static function getMaxLat($lon, $lat, $distance, $distanceMultiplier = 1) |
|
|
|
|
196
|
|
|
{ |
197
|
|
|
return $lat + $distance / (111.12 * $distanceMultiplier); |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
public static function getMinLat($lon, $lat, $distance, $distanceMultiplier = 1) |
|
|
|
|
201
|
|
|
{ |
202
|
|
|
return $lat - $distance / (111.12 * $distanceMultiplier); |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
public static function getMaxLon($lon, $lat, $distance, $distanceMultiplier = 1) |
206
|
|
|
{ |
207
|
|
|
return $lon + $distance * 180 / (abs(sin((90 - $lat) * 3.14159 / 180)) * 6378 * $distanceMultiplier * 3.14159); |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
public static function getMinLon($lon, $lat, $distance, $distanceMultiplier = 1) |
211
|
|
|
{ |
212
|
|
|
return $lon - $distance * 180 / (abs(sin((90 - $lat) * 3.14159 / 180)) * 6378 * $distanceMultiplier * 3.14159); |
213
|
|
|
} |
214
|
|
|
} |
215
|
|
|
|
This function has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.