Index: trunk/extensions/Maps/ParserFunctions/GeoFunctions/Maps_GeoFunctions.php |
— | — | @@ -16,6 +16,9 @@ |
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 ); |
| 22 | + |
20 | 23 | $wgHooks['LanguageGetMagic'][] = 'efMapsGeoFunctionsMagic'; |
21 | 24 | $wgHooks['ParserFirstCallInit'][] = 'efMapsGeoFunctions'; |
22 | 25 | |
— | — | @@ -33,89 +36,92 @@ |
34 | 37 | */ |
35 | 38 | function efMapsGeoFunctions( &$wgParser ) { |
36 | 39 | // Hooks to enable the geocoding parser functions. |
37 | | - $wgParser->setFunctionHook( 'geodistance', 'efMapsRenderGeoDistance' ); |
| 40 | + $wgParser->setFunctionHook( 'geodistance', array( 'MapsGeoFunctions', 'renderGeoDistance' ) ); |
38 | 41 | |
39 | 42 | return true; |
40 | 43 | } |
41 | 44 | |
42 | | -// TODO: add support for smart geocoding |
43 | | -// TODO: add coordinate validation |
44 | | -function efMapsRenderGeoDistance( Parser &$parser ) { |
45 | | - $args = func_get_args(); |
| 45 | +final class MapsGeoFunctions { |
46 | 46 | |
47 | | - // We already know the $parser. |
48 | | - array_shift( $args ); |
49 | | - |
50 | | - // Default parameter assignment, to allow for nameless syntax. |
51 | | - $defaultParams = array( 'location1', 'location2' ); |
52 | | - $parameters = array(); |
| 47 | + // TODO: add support for smart geocoding |
| 48 | + // TODO: add coordinate validation |
| 49 | + function renderGeoDistance( Parser &$parser ) { |
| 50 | + $args = func_get_args(); |
| 51 | + |
| 52 | + // We already know the $parser. |
| 53 | + array_shift( $args ); |
53 | 54 | |
54 | | - // Determine all parameter names and value, and take care of default (nameless) |
55 | | - // parameters, by turning them into named ones. |
56 | | - foreach( $args as $arg ) { |
57 | | - $parts = explode( '=', $arg ); |
58 | | - if ( count( $parts ) == 1 ) { |
59 | | - if ( count( $defaultParams ) > 0 ) { |
60 | | - $defaultParam = array_shift( $defaultParams ); |
61 | | - $parameters[$defaultParam] = trim( $parts[0] ); |
| 55 | + // Default parameter assignment, to allow for nameless syntax. |
| 56 | + $defaultParams = array( 'location1', 'location2' ); |
| 57 | + $parameters = array(); |
| 58 | + |
| 59 | + // Determine all parameter names and value, and take care of default (nameless) |
| 60 | + // parameters, by turning them into named ones. |
| 61 | + foreach( $args as $arg ) { |
| 62 | + $parts = explode( '=', $arg ); |
| 63 | + if ( count( $parts ) == 1 ) { |
| 64 | + if ( count( $defaultParams ) > 0 ) { |
| 65 | + $defaultParam = array_shift( $defaultParams ); |
| 66 | + $parameters[$defaultParam] = trim( $parts[0] ); |
| 67 | + } |
| 68 | + } else { |
| 69 | + $name = strtolower( trim( array_shift( $parts ) ) ); |
| 70 | + $parameters[$name] = trim( implode( $parts ) ); |
62 | 71 | } |
| 72 | + } |
| 73 | + |
| 74 | + $parameterInfo = array( |
| 75 | + 'location1' => array( |
| 76 | + 'required' => true |
| 77 | + ), |
| 78 | + 'location2' => array( |
| 79 | + 'required' => true |
| 80 | + ), |
| 81 | + ); |
| 82 | + |
| 83 | + $manager = new ValidatorManager(); |
| 84 | + |
| 85 | + $parameters = $manager->manageMapparameters( $parameters, $parameterInfo ); |
| 86 | + |
| 87 | + $doCalculation = $parameters !== false; |
| 88 | + |
| 89 | + if ( $doCalculation ) { |
| 90 | + $start = MapsCoordinateParser::parseCoordinates( $parameters['location1'] ); |
| 91 | + $end = MapsCoordinateParser::parseCoordinates( $parameters['location2'] ); |
| 92 | + |
| 93 | + $northRad1 = deg2rad( $start['lat'] ); |
| 94 | + $eastRad1 = deg2rad( $start['lon'] ); |
| 95 | + |
| 96 | + $cosNorth1 = cos( $northRad1 ); |
| 97 | + $cosEast1 = cos( $eastRad1 ); |
| 98 | + |
| 99 | + $sinNorth1 = sin( $northRad1 ); |
| 100 | + $sinEast1 = sin( $eastRad1 ); |
| 101 | + |
| 102 | + $northRad2 = deg2rad( $end['lat'] ); |
| 103 | + $eastRad2 = deg2rad( $end['lon'] ); |
| 104 | + |
| 105 | + $cosNorth2 = cos( $northRad2 ); |
| 106 | + $cosEast2 = cos( $eastRad2 ); |
| 107 | + |
| 108 | + $sinNorth2 = sin( $northRad2 ); |
| 109 | + $sinEast2 = sin( $eastRad2 ); |
| 110 | + |
| 111 | + $term1 = $cosNorth1 * $sinEast1 - $cosNorth2 * $sinEast2; |
| 112 | + $term2 = $cosNorth1 * $cosEast1 - $cosNorth2 * $cosEast2; |
| 113 | + $term3 = $sinNorth1 - $sinNorth2; |
| 114 | + |
| 115 | + $distThruSquared = $term1 * $term1 + $term2 * $term2 + $term3 * $term3; |
| 116 | + |
| 117 | + $surfaceDistance = 2 * Maps_EARTH_RADIUS * asin( sqrt( $distThruSquared ) / 2 ); |
| 118 | + |
| 119 | + $output = $surfaceDistance . ' km<br />' . $manager->getErrorList(); |
63 | 120 | } else { |
64 | | - $name = strtolower( trim( array_shift( $parts ) ) ); |
65 | | - $parameters[$name] = trim( implode( $parts ) ); |
| 121 | + $output = $manager->getErrorList(); |
66 | 122 | } |
| 123 | + |
| 124 | + return array( $output, 'noparse' => true, 'isHTML' => true ); |
67 | 125 | } |
68 | 126 | |
69 | | - $parameterInfo = array( |
70 | | - 'location1' => array( |
71 | | - 'required' => true |
72 | | - ), |
73 | | - 'location2' => array( |
74 | | - 'required' => true |
75 | | - ), |
76 | | - ); |
77 | | - |
78 | | - $manager = new ValidatorManager(); |
79 | | - |
80 | | - $parameters = $manager->manageMapparameters( $parameters, $parameterInfo ); |
81 | | - |
82 | | - $doCalculation = $parameters !== false; |
83 | | - |
84 | | - if ( $doCalculation ) { |
85 | | - $start = MapsCoordinateParser::parseCoordinates( $parameters['location1'] ); |
86 | | - $end = MapsCoordinateParser::parseCoordinates( $parameters['location2'] ); |
87 | | - |
88 | | - $radiusOfEarthKm = 20000 / M_PI; |
89 | | - |
90 | | - $northRad1 = deg2rad( $start['lat'] ); |
91 | | - $eastRad1 = deg2rad( $start['lon'] ); |
| 127 | +} |
92 | 128 | |
93 | | - $cosNorth1 = cos( $northRad1 ); |
94 | | - $cosEast1 = cos( $eastRad1 ); |
95 | | - |
96 | | - $sinNorth1 = sin( $northRad1 ); |
97 | | - $sinEast1 = sin( $eastRad1 ); |
98 | | - |
99 | | - $northRad2 = deg2rad( $end['lat'] ); |
100 | | - $eastRad2 = deg2rad( $end['lon'] ); |
101 | | - |
102 | | - $cosNorth2 = cos( $northRad2 ); |
103 | | - $cosEast2 = cos( $eastRad2 ); |
104 | | - |
105 | | - $sinNorth2 = sin( $northRad2 ); |
106 | | - $sinEast2 = sin( $eastRad2 ); |
107 | | - |
108 | | - $term1 = $cosNorth1 * $sinEast1 - $cosNorth2 * $sinEast2; |
109 | | - $term2 = $cosNorth1 * $cosEast1 - $cosNorth2 * $cosEast2; |
110 | | - $term3 = $sinNorth1 - $sinNorth2; |
111 | | - |
112 | | - $distThruSquared = $term1 * $term1 + $term2 * $term2 + $term3 * $term3; |
113 | | - |
114 | | - $surfaceDistance = 2 * $radiusOfEarthKm * asin( sqrt( $distThruSquared ) / 2 ); |
115 | | - |
116 | | - $output = $surfaceDistance . ' km<br />' . $manager->getErrorList(); |
117 | | - } else { |
118 | | - $output = $manager->getErrorList(); |
119 | | - } |
120 | | - |
121 | | - return array( $output, 'noparse' => true, 'isHTML' => true ); |
122 | | -} |
\ No newline at end of file |