r72009 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r72008‎ | r72009 | r72010 >
Date:02:47, 31 August 2010
Author:jeroendedauw
Status:deferred
Tags:
Comment:
Changes for 0.7 - rewrote the geocder functionality
Modified paths:
  • /trunk/extensions/Maps/Includes/Geocoders/Maps_GeonamesGeocoder.php (modified) (history)
  • /trunk/extensions/Maps/Includes/Geocoders/Maps_GoogleGeocoder.php (modified) (history)
  • /trunk/extensions/Maps/Includes/Geocoders/Maps_YahooGeocoder.php (modified) (history)
  • /trunk/extensions/Maps/Includes/Maps_Geocoder.php (modified) (history)
  • /trunk/extensions/Maps/Includes/Maps_Geocoders.php (modified) (history)
  • /trunk/extensions/Maps/Includes/Maps_Mapper.php (modified) (history)
  • /trunk/extensions/Maps/Maps.php (modified) (history)
  • /trunk/extensions/Maps/Maps_Settings.php (modified) (history)
  • /trunk/extensions/Maps/ParserHooks/Maps_Geocode.php (modified) (history)

Diff [purge]

Index: trunk/extensions/Maps/ParserHooks/Maps_Geocode.php
@@ -118,7 +118,7 @@
119119 * @return string
120120 */
121121 public function render( array $parameters ) {
122 - if ( MapsMapper::geocoderIsAvailable() ) {
 122+ if ( MapsGeocoders::canGeocode() ) {
123123 $geovalues = MapsGeocoders::attemptToGeocodeToString(
124124 $parameters['location'],
125125 $parameters['service'],
Index: trunk/extensions/Maps/Includes/Maps_Geocoders.php
@@ -13,51 +13,59 @@
1414 final class MapsGeocoders {
1515
1616 /**
17 - * The geocoder cache, holding geocoded data when enabled.
 17+ * Accociative with geoservice identifiers as keys containing instances of
 18+ * the geocoder classes.
 19+ *
 20+ * Note: This list only contains the instances, so is not to be used for
 21+ * looping over all available services, as not all of them are guaranteed
 22+ * to have an instance already, use $registeredServices for this purpouse.
 23+ *
 24+ * @since 0.7
 25+ *
 26+ * @var array of string => MapsGeocoder
 27+ */
 28+ protected static $geocoders = array();
 29+
 30+ /**
 31+ * Accociative with geoservice identifiers as keys containing the class
 32+ * name of the geocoders. This is used for registration of a geocoder
 33+ * without immedialty instantiating it.
 34+ *
 35+ * @since 0.7
 36+ *
 37+ * @var array of string => string
 38+ */
 39+ protected static $registeredGeocoders = array();
 40+
 41+ /**
 42+ * The global geocoder cache, holding geocoded data when enabled.
1843 *
1944 * @since 0.7
2045 *
2146 * @var array
2247 */
23 - private static $mGeocoderCache = array();
 48+ private static $globalGeocoderCache = array();
2449
2550 /**
26 - * Initialization function for Maps geocoder functionality.
 51+ * Returns if this class can do geocoding operations.
 52+ * Ie. if there are any geocoders available.
2753 *
28 - * @since 0.4
 54+ * @since 0.7
2955 *
30 - * @return true
 56+ * @return boolean
3157 */
32 - public static function initialize() {
33 - global $wgAutoloadClasses, $egMapsDir, $egMapsGeoServices, $egMapsAvailableGeoServices, $egMapsDefaultGeoService, $egMapsGeoOverrides;
 58+ public static function canGeocode() {
 59+ static $canGeocode = null;
3460
35 - $egMapsGeoServices = array();
36 - $egMapsGeoOverrides = array();
37 -
38 - $geoDir = dirname( __FILE__ ) . '/Geocoders/';
39 - // TODO: replace by autoloading
40 - include_once $geoDir . 'Maps_GoogleGeocoder.php'; // Google
41 - include_once $geoDir . 'Maps_YahooGeocoder.php'; // Yahoo!
42 - include_once $geoDir . 'Maps_GeonamesGeocoder.php'; // GeoNames
43 -
44 - // Remove the supported geocoding services that are not in the $egMapsAvailableGeoServices array.
45 - $supportedServices = array_keys( $egMapsGeoServices );
46 - foreach ( $supportedServices as $supportedService ) {
47 - if ( !in_array( $supportedService, $egMapsAvailableGeoServices ) ) {
48 - unset( $egMapsGeoServices[$supportedService] );
49 - }
 61+ if ( is_null( $canGeocode ) ) {
 62+ // Register the geocoders.
 63+ wfRunHooks( 'GeocoderFirstCallInit' );
 64+
 65+ // Determine if there are any geocoders.
 66+ $canGeocode = count( self::$registeredGeocoders ) > 0;
5067 }
5168
52 - // Re-populate the $egMapsAvailableGeoServices with it's original services that are supported.
53 - $egMapsAvailableGeoServices = array_keys( $egMapsGeoServices );
54 -
55 - // Enure that the default geoservice is one of the enabled ones.
56 - if ( !in_array( $egMapsDefaultGeoService, $egMapsAvailableGeoServices ) ) {
57 - reset( $egMapsAvailableGeoServices );
58 - $egMapsDefaultGeoService = key( $egMapsAvailableGeoServices );
59 - }
60 -
61 - return true;
 69+ return $canGeocode;
6270 }
6371
6472 /**
@@ -127,38 +135,82 @@
128136 * @since 0.7
129137 *
130138 * @param string $address
131 - * @param string $service
 139+ * @param string $geoService
132140 * @param string $mappingService
133141 *
134142 * @return array with coordinates or false
135143 */
136 - public static function geocode( $address, $service = '', $mappingService = false ) {
137 - global $egMapsGeoServices, $wgAutoloadClasses, $egMapsDir, $IP, $egMapsEnableGeoCache;
 144+ public static function geocode( $address, $geoService = '', $mappingService = false ) {
 145+ if ( !self::canGeocode() ) {
 146+ return false;
 147+ }
138148
139 - // If the adress is already in the cache and the cache is enabled, return the coordinates.
140 - if ( $egMapsEnableGeoCache && array_key_exists( $address, self::$mGeocoderCache ) ) {
141 - return self::$mGeocoderCache[$address];
 149+ $geocoder = self::getValidGeocoderInstance( $geoService, $mappingService );
 150+
 151+ // This means there was no suitable geocoder found, so return false.
 152+ if ( $geocoder === false ) {
 153+ return false;
142154 }
143 -
144 - $service = self::getValidGeoService( $service, $mappingService );
145155
146 - // Call the geocode function in the specific geocoder class.
147 - $coordinates = call_user_func( array( $egMapsGeoServices[$service], 'geocode' ), $address );
 156+ if ( $geocoder->hasGlobalCacheSupport() ) {
 157+ $cacheResult = self::cacheRead( $address );
 158+
 159+ // This means the cache returned an already computed set of coordinates.
 160+ if ( $cacheResult !== false ) {
 161+ return $cacheResult;
 162+ }
 163+ }
148164
 165+ // Do the actual geocoding via the geocoder.
 166+ $coordinates = $geocoder->geocode( $address );
 167+
149168 // If there address could not be geocoded, and contains comma's, try again without the comma's.
150169 // This is cause several geocoding services such as geonames do not handle comma's well.
151170 if ( !$coordinates && strpos( $address, ',' ) !== false ) {
152 - $coordinates = call_user_func(
153 - array( $egMapsGeoServices[$service], 'geocode' ), str_replace( ',', '', $address )
154 - );
 171+ $coordinates = $geocoder->geocode( str_replace( ',', '', $address ) );
155172 }
156173
 174+ self::cacheWrite( $address, $coordinates );
 175+
 176+ return $coordinates;
 177+ }
 178+
 179+ /**
 180+ * Returns already coordinates already known from previous geocoding operations,
 181+ * or false if there is no match found in the cache.
 182+ *
 183+ * @since 0.7
 184+ *
 185+ * @param string $address
 186+ *
 187+ * @return array or false
 188+ */
 189+ protected static function cacheRead( $address ) {
 190+ global $egMapsEnableGeoCache;
 191+
 192+ if ( $egMapsEnableGeoCache && array_key_exists( $address, self::$globalGeocoderCache ) ) {
 193+ return self::$globalGeocoderCache[$address];
 194+ }
 195+ else {
 196+ return false;
 197+ }
 198+ }
 199+
 200+ /**
 201+ * Writes the geocoded result to the cache if the cache is on.
 202+ *
 203+ * @since 0.7
 204+ *
 205+ * @param string $address
 206+ * @param array $coordinates
 207+ */
 208+ protected static function cacheWrite( $address, array $coordinates ) {
 209+ global $egMapsEnableGeoCache;
 210+
157211 // Add the obtained coordinates to the cache when there is a result and the cache is enabled.
158212 if ( $egMapsEnableGeoCache && $coordinates ) {
159 - self::$mGeocoderCache[$address] = $coordinates;
 213+ self::$globalGeocoderCache[$address] = $coordinates;
160214 }
161 -
162 - return $coordinates;
163215 }
164216
165217 /**
@@ -180,39 +232,118 @@
181233 }
182234
183235 /**
184 - * Makes sure that the geo service is one of the available ones.
185 - * Also enforces licencing restrictions when no geocoding service is explicitly provided.
 236+ * Registeres a geocoder linked to an identifier.
 237+ *
 238+ * @since 0.7
 239+ *
 240+ * @param string $geocoderIdentifier
 241+ * @param string $geocoderClassName
 242+ */
 243+ public static function registerGeocoder( $geocoderIdentifier, $geocoderClassName ) {
 244+ self::$registeredGeocoders[$geocoderIdentifier] = $geocoderClassName;
 245+ }
 246+
 247+ /**
 248+ * Returns the instance of the geocoder linked to the provided identifier
 249+ * or the default one when it's not valid. False is returned when there
 250+ * are no geocoders available.
 251+ *
 252+ * @since 0.7
 253+ *
 254+ * @param string $geocoderIdentifier
 255+ *
 256+ * @return MapsGeocoder or false
 257+ */
 258+ protected static function getValidGeocoderInstance( $geocoderIdentifier ) {
 259+ return self::getGeocoderInstance( self::getValidGeocoderIdentifier( $geocoderIdentifier ) );
 260+ }
 261+
 262+ /**
 263+ * Returns the instance of a geocoder. This function assumes there is a
 264+ * geocoder linked to the identifier you provide - if you are not sure
 265+ * it does, use getValidGeocoderInstance instead.
 266+ *
 267+ * @since 0.7
 268+ *
 269+ * @param string $geocoderIdentifier
 270+ *
 271+ * @return MapsGeocoder or false
 272+ */
 273+ protected static function getGeocoderInstance( $geocoderIdentifier ) {
 274+ if ( !array_key_exists( $geocoderIdentifier, self::$geocoders ) ) {
 275+ if ( array_key_exists( $geocoderIdentifier, self::$registeredGeocoders ) ) {
 276+ $geocoder = new self::$registeredGeocoders[$geocoderIdentifier]( $geocoderIdentifier );
 277+
 278+ //if ( $service instanceof iMappingService ) {
 279+ self::$geocoders[$geocoderIdentifier] = $geocoder;
 280+ //}
 281+ //else {
 282+ // throw new Exception( 'The geocoder linked to identifier ' . $geocoderIdentifier . ' does not implement .' );
 283+ //}
 284+ }
 285+ else {
 286+ throw new Exception( 'There is geocoder linked to identifier ' . $geocoderIdentifier . '.' );
 287+ }
 288+ }
 289+
 290+ return self::$geocoders[$geocoderIdentifier];
 291+ }
 292+
 293+ /**
 294+ * Returns a valid geocoder idenifier. If the given one is a valid main identifier,
 295+ * it will simply be returned. If it's an alias, it will be turned into the correponding
 296+ * main identifier. If it's not recognized at all (or empty), the default will be used.
 297+ * Only call this function when there are geocoders available, else an erro will be thrown.
 298+ *
 299+ * TODO: implement overrides
186300 *
187301 * @since 0.7
188302 *
189 - * @param string $service
 303+ * @param string $geocoderIdentifier
190304 * @param string $mappingService
191305 *
192 - * @return string
 306+ * @return string or false
193307 */
194 - private static function getValidGeoService( $service, $mappingService ) {
195 - global $egMapsAvailableGeoServices, $egMapsDefaultGeoService, $egMapsGeoOverrides, $egMapsUserGeoOverrides;
 308+ protected static function getValidGeocoderIdentifier( $geocoderIdentifier /*, $mappingService */ ) {
 309+ global $egMapsDefaultGeoService, $egMapsUserGeoOverrides;
 310+ static $validatedDefault = false;
196311
197 - if ( $service == '' ) {
198 - if ( $egMapsUserGeoOverrides && $mappingService ) {
199 - // If no service has been provided, check if there are overrides for the default.
200 - foreach ( $egMapsAvailableGeoServices as $geoService ) {
201 - if ( array_key_exists( $geoService, $egMapsGeoOverrides ) && in_array( $mappingService, $egMapsGeoOverrides[$geoService] ) ) {
202 - $service = $geoService; // Use the override.
203 - break;
 312+ // Get rid of any aliases.
 313+ $geocoderIdentifier = self::getMainGeocoderIndentifier( $geocoderIdentifier );
 314+
 315+ if ( $geocoderIdentifier == '' || !array_key_exists( $geocoderIdentifier, self::$registeredGeocoders ) ) {
 316+ if ( !$validatedDefault ) {
 317+ if ( !array_key_exists( $egMapsDefaultGeoService, self::$registeredGeocoders ) ) {
 318+ $egMapsDefaultGeoService = array_shift( array_keys( self::$registeredGeocoders ) );
 319+ if ( is_null( $egMapsDefaultGeoService ) ) {
 320+ throw new Exception( 'Tried to geocode while there are no geocoders available at ' . __METHOD__ );
204321 }
205322 }
206323 }
207 -
208 - // If no overrides where applied, use the default mapping service.
209 - if ( $service == '' ) $service = $egMapsDefaultGeoService;
 324+
 325+ if ( array_key_exists( $egMapsDefaultGeoService, self::$registeredGeocoders ) ) {
 326+ $geocoderIdentifier = $egMapsDefaultGeoService;
 327+ }
 328+ else {
 329+ return false;
 330+ }
210331 }
211 - else {
212 - // If a service is provided, but is not supported, use the default.
213 - if ( !in_array( $service, $egMapsAvailableGeoServices ) ) $service = $egMapsDefaultGeoService;
214 - }
215 -
216 - return $service;
217 - }
 332+
 333+ return $geocoderIdentifier;
 334+ }
218335
 336+ /**
 337+ * Gets the main geocoder identifier by resolving aliases.
 338+ *
 339+ * @since 0.7
 340+ *
 341+ * @param string $geocoderIdentifier
 342+ *
 343+ * @return string
 344+ */
 345+ protected static function getMainGeocoderIndentifier( $geocoderIdentifier ) {
 346+ // TODO: implement actual function
 347+ return $geocoderIdentifier;
 348+ }
 349+
219350 }
\ No newline at end of file
Index: trunk/extensions/Maps/Includes/Geocoders/Maps_GoogleGeocoder.php
@@ -1,45 +1,59 @@
22 <?php
33
44 /**
5 - * Google Geocoding Service (v2)
6 - * More info: http://code.google.com/apis/maps/documentation/services.html#Geocoding_Direct
 5+ * Class for geocoding requests with the Google Geocoding Service (v2).
 6+ *
 7+ * Webservice documentation: http://code.google.com/apis/maps/documentation/services.html#Geocoding_Direct
78 *
89 * @file Maps_GoogleGeocoder.php
910 * @ingroup Maps
 11+ * @ingroup Geocoders
1012 *
1113 * @author Jeroen De Dauw
1214 * @author Sergey Chernyshev
1315 */
14 -
15 -if ( !defined( 'MEDIAWIKI' ) ) {
16 - die( 'Not an entry point.' );
17 -}
18 -
19 -$wgAutoloadClasses['MapsGoogleGeocoder'] = __FILE__;
20 -$egMapsGeoServices['google'] = 'MapsGoogleGeocoder';
21 -$egMapsGeoOverrides['google'] = array( 'googlemaps2', 'googlemaps3' );
22 -
2316 final class MapsGoogleGeocoder extends MapsGeocoder {
2417
2518 /**
26 - * @see MapsBaseGeocoder::geocode()
27 - *
 19+ * Registeres the geocoder.
 20+ *
 21+ * No LST in pre-5.3 PHP *sigh*.
 22+ * This is to be refactored as soon as php >=5.3 becomes acceptable.
 23+ *
 24+ * @since 0.7
 25+ */
 26+ public static function register() {
 27+ MapsGeocoders::registerGeocoder( 'google', __CLASS__ );
 28+ return true;
 29+ }
 30+
 31+ /**
 32+ * @see MapsGeocoder::getRequestUrl
 33+ *
 34+ * @since 0.7
 35+ *
2836 * @param string $address
29 - */
30 - public static function geocode( $address ) {
 37+ *
 38+ * @return string
 39+ */
 40+ protected function getRequestUrl( $address ) {
3141 global $egGoogleMapsKey;
32 -
33 - // In case the google maps api key is not set, return false0
34 - if ( empty( $egGoogleMapsKey ) ) return false;
35 -
36 - // Create the request url
37 - $requestURL = 'http://maps.google.com/maps/geo?q=' . urlencode( $address ) . '&output=csv&key=' . urlencode( $egGoogleMapsKey );
38 -
39 - $result = Http::get( $requestURL );
40 -
41 - // Check the Google Geocoder API Response code to ensure success0
42 - if ( substr( $result, 0, 3 ) == '200' ) {
43 - $result = explode( ',', $result );
 42+ return 'http://maps.google.com/maps/geo?q=' . urlencode( $address ) . '&output=csv&key=' . urlencode( $egGoogleMapsKey );
 43+ }
 44+
 45+ /**
 46+ * @see MapsGeocoder::parseResponse
 47+ *
 48+ * @since 0.7
 49+ *
 50+ * @param string $address
 51+ *
 52+ * @return array
 53+ */
 54+ protected function parseResponse( $response ) {
 55+ // Check the Google Geocoder API Response code to ensure success.
 56+ if ( substr( $response, 0, 3 ) == '200' ) {
 57+ $result = explode( ',', $response );
4458
4559 // $precision = $result[1];
4660
@@ -48,8 +62,20 @@
4963 'lon' => $result[3]
5064 );
5165 }
52 - else { // When the request fails, return false0
 66+ else { // When the request fails, return false.
5367 return false;
54 - }
 68+ }
5569 }
 70+
 71+ /**
 72+ * @see MapsGeocoder::getOverrides
 73+ *
 74+ * @since 0.7
 75+ *
 76+ * @return array
 77+ */
 78+ public function getOverrides() {
 79+ return array( 'googlemaps2', 'googlemaps3' );
 80+ }
 81+
5682 }
\ No newline at end of file
Index: trunk/extensions/Maps/Includes/Geocoders/Maps_GeonamesGeocoder.php
@@ -1,47 +1,65 @@
22 <?php
33
44 /**
 5+ * Class for geocoding requests with the GeoNames webservice.
 6+ *
57 * GeoNames Web Services Documentation: http://www.geonames.org/export/geonames-search.html
68 *
79 * @file Maps_GeonamesGeocoder.php
810 * @ingroup Maps
 11+ * @ingroup Geocoders
912 *
1013 * @author Jeroen De Dauw
1114 * Thanks go to Joel Natividad for pointing me to the GeoNames services.
1215 */
13 -
14 -if ( !defined( 'MEDIAWIKI' ) ) {
15 - die( 'Not an entry point.' );
16 -}
17 -
18 -$wgAutoloadClasses['MapsGeonamesGeocoder'] = __FILE__;
19 -$egMapsGeoServices['geonames'] = 'MapsGeonamesGeocoder';
20 -
2116 final class MapsGeonamesGeocoder extends MapsGeocoder {
2217
2318 /**
24 - * @see MapsBaseGeocoder::geocode()
25 - *
26 - * @param string $address
 19+ * Registeres the geocoder.
2720 *
28 - * NOTE: The service is now also available in JSON, so it might be nice to change to that.
 21+ * No LST in pre-5.3 PHP *sigh*.
 22+ * This is to be refactored as soon as php >=5.3 becomes acceptable.
 23+ *
 24+ * @since 0.7
2925 */
30 - public static function geocode( $address ) {
31 - // Create the request url
32 - $requestURL = 'http://ws.geonames.org/search?q=' . urlencode( $address ) . '&maxRows=1&style=SHORT';
33 -
34 - $result = Http::get( $requestURL );
 26+ public static function register() {
 27+ MapsGeocoders::registerGeocoder( 'geonames', __CLASS__ );
 28+ return true;
 29+ }
3530
36 - $lon = self::getXmlElementValue( $result, 'lng' );
37 - $lat = self::getXmlElementValue( $result, 'lat' );
 31+ /**
 32+ * @see MapsGeocoder::getRequestUrl
 33+ *
 34+ * @since 0.7
 35+ *
 36+ * @param string $address
 37+ *
 38+ * @return string
 39+ */
 40+ protected function getRequestUrl( $address ) {
 41+ return 'http://ws.geonames.org/search?q=' . urlencode( $address ) . '&maxRows=1&style=SHORT';
 42+ }
 43+
 44+ /**
 45+ * @see MapsGeocoder::parseResponse
 46+ *
 47+ * @since 0.7
 48+ *
 49+ * @param string $address
 50+ *
 51+ * @return array
 52+ */
 53+ protected function parseResponse( $response ) {
 54+ $lon = self::getXmlElementValue( $response, 'lng' );
 55+ $lat = self::getXmlElementValue( $response, 'lat' );
3856
39 - // In case one of the values is not found, return false
 57+ // In case one of the values is not found, return false.
4058 if ( !$lon || !$lat ) return false;
4159
4260 return array(
4361 'lat' => $lat,
4462 'lon' => $lon
45 - );
 63+ );
4664 }
4765
4866 }
\ No newline at end of file
Index: trunk/extensions/Maps/Includes/Geocoders/Maps_YahooGeocoder.php
@@ -1,49 +1,76 @@
22 <?php
33
44 /**
 5+ * Class for geocoding requests with the Yahoo! Geocoding Service.
 6+ *
57 * Yahoo! Geocoding Service info: http://developer.yahoo.com/geo/geoplanet/
68 *
79 * @file Maps_YahooGeocoder.php
810 * @ingroup Maps
 11+ * @ingroup Geocoders
912 *
1013 * @author Jeroen De Dauw
1114 */
12 -
13 -if ( !defined( 'MEDIAWIKI' ) ) {
14 - die( 'Not an entry point.' );
15 -}
16 -
17 -$wgAutoloadClasses['MapsYahooGeocoder'] = __FILE__;
18 -$egMapsGeoServices['yahoo'] = 'MapsYahooGeocoder';
19 -
2015 final class MapsYahooGeocoder extends MapsGeocoder {
2116
2217 /**
23 - * @see MapsBaseGeocoder::geocode()
24 - *
 18+ * Registeres the geocoder.
 19+ *
 20+ * No LST in pre-5.3 PHP *sigh*.
 21+ * This is to be refactored as soon as php >=5.3 becomes acceptable.
 22+ *
 23+ * @since 0.7
 24+ */
 25+ public static function register() {
 26+ MapsGeocoders::registerGeocoder( 'yahoo', __CLASS__ );
 27+ return true;
 28+ }
 29+
 30+ /**
 31+ * @see MapsGeocoder::getRequestUrl
 32+ *
 33+ * @since 0.7
 34+ *
2535 * @param string $address
26 - */
27 - public static function geocode( $address ) {
 36+ *
 37+ * @return string
 38+ */
 39+ protected function getRequestUrl( $address ) {
2840 global $egYahooMapsKey;
29 -
30 - // In case the Yahoo! Maps API key is not set, return false
31 - if ( empty( $egYahooMapsKey ) ) return false;
32 -
33 - // Create the request url
34 - $requestURL = "http://where.yahooapis.com/v1/places.q('" . urlencode( $address ) . "')?appid=" . urlencode( $egYahooMapsKey ) . "&format=xml";
35 -
36 - $result = Http::get( $requestURL );
 41+ return "http://where.yahooapis.com/v1/places.q('" . urlencode( $address ) . "')?appid=" . urlencode( $egYahooMapsKey ) . '&format=xml';
 42+ }
3743
38 - $lon = self::getXmlElementValue( $result, 'longitude' );
39 - $lat = self::getXmlElementValue( $result, 'latitude' );
 44+ /**
 45+ * @see MapsGeocoder::parseResponse
 46+ *
 47+ * @since 0.7
 48+ *
 49+ * @param string $address
 50+ *
 51+ * @return array
 52+ */
 53+ protected function parseResponse( $response ) {
 54+ $lon = self::getXmlElementValue( $response, 'longitude' );
 55+ $lat = self::getXmlElementValue( $response, 'latitude' );
4056
41 - // In case one of the values is not found, return false
 57+ // In case one of the values is not found, return false.
4258 if ( !$lon || !$lat ) return false;
4359
4460 return array(
4561 'lat' => $lat,
4662 'lon' => $lon
47 - );
 63+ );
4864 }
4965
 66+ /**
 67+ * @see MapsGeocoder::getOverrides
 68+ *
 69+ * @since 0.7
 70+ *
 71+ * @return array
 72+ */
 73+ public function getOverrides() {
 74+ return array( 'yahoomaps' );
 75+ }
 76+
5077 }
\ No newline at end of file
Index: trunk/extensions/Maps/Includes/Maps_Mapper.php
@@ -175,11 +175,12 @@
176176 /**
177177 * Returns a boolean indicating if MapsGeocoder is available.
178178 *
 179+ * @deprecated - use MapsGeocoders::canGeocode() instead
 180+ *
179181 * @return Boolean
180182 */
181183 public static function geocoderIsAvailable() {
182 - global $wgAutoloadClasses;
183 - return array_key_exists( 'MapsGeocoders', $wgAutoloadClasses );
 184+ return MapsGeocoders::canGeocode();
184185 }
185186
186187 /**
Index: trunk/extensions/Maps/Includes/Maps_Geocoder.php
@@ -11,8 +11,92 @@
1212 * @author Jeroen De Dauw
1313 */
1414 abstract class MapsGeocoder {
 15+
 16+ /**
 17+ * The internal name of the geocoder.
 18+ *
 19+ * @since 0.7
 20+ *
 21+ * @var string
 22+ */
 23+ protected static $name;
1524
1625 /**
 26+ * A list of aliases for the internal name.
 27+ *
 28+ * @since 0.7
 29+ *
 30+ * @var array
 31+ */
 32+ protected $aliases;
 33+
 34+ /**
 35+ * Returns the url to which to make the geocoding request.
 36+ *
 37+ * @since 0.7
 38+ *
 39+ * @param string $address
 40+ *
 41+ * @return string
 42+ */
 43+ protected abstract function getRequestUrl( $address );
 44+
 45+ /**
 46+ * Parses the response and returns it as an array with lat and lon keys.
 47+ *
 48+ * @since 0.7
 49+ *
 50+ * @param string $address
 51+ *
 52+ * @return array
 53+ */
 54+ protected abstract function parseResponse( $response );
 55+
 56+ /**
 57+ * Constructor.
 58+ *
 59+ * @since 0.7
 60+ *
 61+ * @param string $identifier
 62+ */
 63+ public function __construct( $identifier ) {
 64+ self::$name = $identifier;
 65+ }
 66+
 67+ /**
 68+ * Returns the geocoders identifier.
 69+ *
 70+ * @since 0.7
 71+ *
 72+ * @return string
 73+ */
 74+ public static function getName() {
 75+ return self::$name;
 76+ }
 77+
 78+ /**
 79+ * Returns the geocoders aliases.
 80+ *
 81+ * @since 0.7
 82+ *
 83+ * @return array
 84+ */
 85+ public function getAliases() {
 86+ return $this->aliases;
 87+ }
 88+
 89+ /**
 90+ * Returns if the geocoder has a certain alias.
 91+ *
 92+ * @since 0.7
 93+ *
 94+ * @return boolean
 95+ */
 96+ public function hasAlias( $alias ) {
 97+ return in_array( $alias, $this->aliases );
 98+ }
 99+
 100+ /**
17101 * Returns an array containing the geocoded latitude (lat) and
18102 * longitude (lon) of the provided address, or false in case the
19103 * geocoding fails.
@@ -21,10 +105,17 @@
22106 *
23107 * @param $address String: the address to be geocoded
24108 *
25 - * @return string or false
 109+ * @return array or false
26110 */
27 - public static function geocode( $address ) {
28 - return false; // This method needs to be overriden, if it's not, return false.
 111+ public function geocode( $address ) {
 112+ $response = Http::get( $this->getRequestUrl( $address ) );
 113+
 114+ if ( $response === false ) {
 115+ return false;
 116+ }
 117+ else {
 118+ return $this->parseResponse( $response );
 119+ }
29120 }
30121
31122 /**
@@ -42,4 +133,31 @@
43134 return count( $match ) > 1 ? $match[1] : false;
44135 }
45136
 137+ /**
 138+ * Returns the mapping service overrides for this geocoder, allowing it to be used
 139+ * instead of the default geocoder when none is provided for certain mapping services.
 140+ *
 141+ * Returns an empty array by default. Override to add overrides.
 142+ *
 143+ * @since 0.7
 144+ *
 145+ * @return array
 146+ */
 147+ public function getOverrides() {
 148+ return array();
 149+ }
 150+
 151+ /**
 152+ * Returns if the global geocoder cache should be used or not.
 153+ * By default it should be, but overriding this function allows
 154+ * for making a geocoder ignore it and implement it's own solution.
 155+ *
 156+ * @since 0.7
 157+ *
 158+ * @return boolean
 159+ */
 160+ public function hasGlobalCacheSupport() {
 161+ return true;
 162+ }
 163+
46164 }
\ No newline at end of file
Index: trunk/extensions/Maps/Maps.php
@@ -101,6 +101,12 @@
102102 $wgAutoloadClasses['MapsGeocoders'] = $incDir . 'Maps_Geocoders.php';
103103 $wgAutoloadClasses['MapsGeocoder'] = $incDir . 'Maps_Geocoder.php';
104104
 105+ // Geocoders at "Includes/Geocoders/".
 106+ $geoDir = $incDir . 'Geocoders/';
 107+ $wgAutoloadClasses['MapsGeonamesGeocoder'] = $geoDir . 'Maps_GeonamesGeocoder.php';
 108+ $wgAutoloadClasses['MapsGoogleGeocoder'] = $geoDir . 'Maps_GoogleGeocoder.php';
 109+ $wgAutoloadClasses['MapsYahooGeocoder'] = $geoDir . 'Maps_YahooGeocoder.php';
 110+
105111 // Autoload the "ParserHooks/" classes.
106112 $phDir = dirname( __FILE__ ) . '/ParserHooks/';
107113 $wgAutoloadClasses['MapsCoordinates'] = $phDir . 'Maps_Coordinates.php';
Index: trunk/extensions/Maps/Maps_Settings.php
@@ -52,12 +52,11 @@
5353 $wgHooks['ParserFirstCallInit'][] = 'MapsGeodistance::staticInit';
5454 $wgHooks['LanguageGetMagic'][] = 'MapsGeodistance::staticMagic';
5555
56 - #
57 -
58 - $wgHooks['MappingFeatureLoad'][] = 'MapsGeocoders::initialize';
59 -
60 -
 56+ # Geocoders
6157
 58+ $wgHooks['GeocoderFirstCallInit'][] = 'MapsGeonamesGeocoder::register';
 59+ $wgHooks['GeocoderFirstCallInit'][] = 'MapsGoogleGeocoder::register';
 60+ $wgHooks['GeocoderFirstCallInit'][] = 'MapsYahooGeocoder::register';
6261
6362 # Mapping services configuration
6463 # Note: You can not use aliases in the settings. Use the main service names.

Follow-up revisions

RevisionCommit summaryAuthorDate
r72014Fixed bug introduced in r72009jeroendedauw05:03, 31 August 2010

Status & tagging log