Index: trunk/extensions/Maps/ParserFunctions/GeoFunctions/Maps_GeoFunctions.php |
— | — | @@ -16,8 +16,8 @@ |
17 | 17 | die( 'Not an entry point.' ); |
18 | 18 | } |
19 | 19 | |
20 | | -// The approximate radius of the earth in km. |
21 | | -define( 'Maps_EARTH_RADIUS', 20000 / M_PI ); |
| 20 | +// The approximate radius of the earth in meters, according to http://en.wikipedia.org/wiki/Earth_radius. |
| 21 | +define( 'Maps_EARTH_RADIUS', 6371000 ); |
22 | 22 | |
23 | 23 | if ( version_compare( $wgVersion, '1.16alpha', '<' ) ) { |
24 | 24 | $wgHooks['LanguageGetMagic'][] = 'efMapsGeoFunctionsMagic'; |
— | — | @@ -203,7 +203,8 @@ |
204 | 204 | } |
205 | 205 | |
206 | 206 | if ( $location ) { |
207 | | - $destination = self::findDestination( $location, $parameters['bearing'], $parameters['distance'] ); |
| 207 | + // TODO: have distance unit support here |
| 208 | + $destination = self::findDestination( $location, $parameters['bearing'], (float)$parameters['distance'] * 1000 ); |
208 | 209 | $output = MapsCoordinateParser::formatCoordinates( $destination, $parameters['format'], $parameters['directional'] ); |
209 | 210 | } else { |
210 | 211 | global $egValidatorFatalLevel; |
— | — | @@ -259,14 +260,11 @@ |
260 | 261 | |
261 | 262 | $sinNorth2 = sin( $northRad2 ); |
262 | 263 | $sinEast2 = sin( $eastRad2 ); |
| 264 | + |
| 265 | + $distNOacos = $sinNorth1 * $sinNorth2 + $cosNorth1 * $cosNorth2 + cos ($eastRad1 - $eastRad2); |
263 | 266 | |
264 | | - $term1 = $cosNorth1 * $sinEast1 - $cosNorth2 * $sinEast2; |
265 | | - $term2 = $cosNorth1 * $cosEast1 - $cosNorth2 * $cosEast2; |
266 | | - $term3 = $sinNorth1 - $sinNorth2; |
267 | | - |
268 | | - $distThruSquared = $term1 * $term1 + $term2 * $term2 + $term3 * $term3; |
269 | | - |
270 | | - return 2 * Maps_EARTH_RADIUS * asin( sqrt( $distThruSquared ) / 2 ); |
| 267 | + // Divide by 1000, as the radius is defined in meters. |
| 268 | + return Maps_EARTH_RADIUS * acos( $distNOacos ) / 1000; |
271 | 269 | } |
272 | 270 | |
273 | 271 | /** |
— | — | @@ -281,22 +279,17 @@ |
282 | 280 | public static function findDestination( array $startingCoordinates, $bearing, $distance ) { |
283 | 281 | $startingCoordinates['lat'] = deg2rad( (float)$startingCoordinates['lat'] ); |
284 | 282 | $startingCoordinates['lon'] = deg2rad( (float)$startingCoordinates['lon'] ); |
| 283 | + |
| 284 | + $radBearing = deg2rad ( (float)$bearing ); |
| 285 | + $angularDistance = $distance / Maps_EARTH_RADIUS; |
285 | 286 | |
286 | | - $angularDistance = deg2rad( $distance / Maps_EARTH_RADIUS ); |
287 | | - |
288 | | - $lat = asin( |
289 | | - sin( $startingCoordinates['lat'] ) * cos( $angularDistance ) + |
290 | | - cos( $startingCoordinates['lat'] ) * sin( $angularDistance ) * cos( $bearing ) |
291 | | - ); |
292 | | - |
| 287 | + $lat = asin (sin ( $startingCoordinates['lat'] ) * cos ( $angularDistance ) + cos ( $startingCoordinates['lat'] ) * sin ( $angularDistance ) * cos ( $radBearing ) ); |
| 288 | + $lon = $startingCoordinates['lon'] + atan2 ( sin ( $radBearing ) * sin ( $angularDistance ) * cos ( $startingCoordinates['lat'] ), cos ( $angularDistance ) - sin ( $startingCoordinates['lat'] ) * sin ( $lat ) ); |
| 289 | + |
293 | 290 | return array( |
294 | 291 | 'lat' => rad2deg( $lat ), |
295 | | - 'lon' => rad2deg( $startingCoordinates['lon'] + atan2( |
296 | | - sin( $bearing ) * sin( $angularDistance ) * cos( $startingCoordinates['lat'] ), |
297 | | - cos( $angularDistance ) - sin( $startingCoordinates['lat'] ) * sin( $lat ) ) |
298 | | - ) |
| 292 | + 'lon' => rad2deg( $lon ) |
299 | 293 | ); |
300 | 294 | } |
301 | 295 | |
302 | | -} |
303 | | - |
| 296 | +} |
\ No newline at end of file |
Index: trunk/extensions/Maps/Maps_CoordinateParser.php |
— | — | @@ -20,7 +20,6 @@ |
21 | 21 | * @ingroup Maps |
22 | 22 | * |
23 | 23 | * @author Jeroen De Dauw |
24 | | - * |
25 | 24 | */ |
26 | 25 | class MapsCoordinateParser { |
27 | 26 | |
— | — | @@ -67,8 +66,8 @@ |
68 | 67 | } |
69 | 68 | |
70 | 69 | $coordinates = array( |
71 | | - 'lat' => trim ( $split[0] ), |
72 | | - 'lon' => trim ( $split[1] ), |
| 70 | + 'lat' => trim( $split[0] ), |
| 71 | + 'lon' => trim( $split[1] ), |
73 | 72 | ); |
74 | 73 | |
75 | 74 | // Ensure the coordinates are in non-directional notation. |
— | — | @@ -416,8 +415,6 @@ |
417 | 416 | * @param string $coordinate |
418 | 417 | * |
419 | 418 | * @return string |
420 | | - * |
421 | | - * FIXME: fix innacuracy |
422 | 419 | */ |
423 | 420 | private static function parseDMSCoordinate( $coordinate ) { |
424 | 421 | $isNegative = $coordinate{0} == '-'; |
— | — | @@ -459,8 +456,6 @@ |
460 | 457 | * @param string $coordinate |
461 | 458 | * |
462 | 459 | * @return string |
463 | | - * |
464 | | - * TODO: fix innacuracy |
465 | 460 | */ |
466 | 461 | private static function parseDMCoordinate( $coordinate ) { |
467 | 462 | $isNegative = $coordinate{0} == '-'; |