Source for file geo-mashup-geocoders.php
Documentation is available at geo-mashup-geocoders.php
* The Geo Mashup Http Geocoder base class.
* Parameters to use with http requests.
* Maximum number of results
* @param string $args Optional array of arguments:
* language - two digit language code, defaults to blog language
* max_results - maximum number of results to fetch
* default http params - array of WP_Http request parameters, including timeout
'language' => get_locale(),
'request_params' => array( 'timeout' => 3.0 )
$args = wp_parse_args( $args, $defaults );
include_once( ABSPATH . WPINC. '/class-http.php' );
$this->http = new WP_Http();
* Look up locations from a text query, like an address or place name.
* @param string $query Text query.
* @return array|WP_ErrorArray of search result locations.
abstract public function geocode( $query );
* Look up additional location information from coordinates.
* Resulting locations have as much address information as
* possible filled in. Most services return the nearest match
* first, and some return only one.
* @param float $lat Latitude
* @param float $lng Longitude
* @return array|WP_ErrorArray of search result locations.
* HTTP geocoder using the geonames web services.
* Includes an additional method for looking up administrative area names.
* The application username to include in geonames API requests.
private $geonames_username;
$this->geonames_username = $geo_mashup_options->get( 'overall', 'geonames_username' );
public function geocode( $query ) {
$url = 'http://api.geonames.org/searchJSON?username=' . $this->geonames_username .
if ( is_wp_error( $response ) )
$status = $response['response']['code'];
return new WP_Error( 'geocoder_http_request_failed', $status . ': ' . $response['response']['message'], $response );
if ( empty( $data ) or 0 == $data->totalResultsCount )
foreach( $data->geonames as $geoname ) {
$location->lat = $geoname->lat;
$location->lng = $geoname->lng;
if ( !empty( $geoname->countryCode ) )
$location->country_code = $geoname->countryCode;
if ( !empty( $geoname->adminCode1) )
$location->admin_code = $geoname->adminCode1;
if ( !empty( $geoname->fcode ) and 'PPL' == substr( $geoname->fcode, 0, 3 ) )
$location->locality_name = $geoname->name;
$locations[] = $location;
return new WP_Error( 'bad_reverse_geocode_request', __( 'Reverse geocoding requires numeric coordinates.', 'GeoMashup' ) );
$url = 'http://api.geonames.org/countrySubdivisionJSON?style=FULL&username=' . $this->geonames_username .
if ( is_wp_error( $response ) )
$status = $response['response']['code'];
if ( empty( $data ) or !empty( $data->status ) )
if ( !empty( $data->countryCode ) )
$location->country_code = $data->countryCode;
if ( !empty( $data->adminCode1 ) )
$location->admin_code = $data->adminCode1;
// Look up more things, postal code, locality or address in US
$url = 'http://api.geonames.org/findNearestAddressJSON?style=FULL&username=' . $this->geonames_username .
if ( !is_wp_error( $response ) ) {
$status = $response['response']['code'];
if ( ! empty( $data->address ) ) {
$address_parts = array();
if ( ! empty( $data->address->street ) ) {
$address_parts[] = ( empty( $data->address->streetNumber ) ? '' : $data->address->streetNumber . ' ' ) .
if ( ! empty( $data->address->adminName1 ) ) {
$address_parts[] = $data->address->adminName1;
if ( ! empty( $data->address->postalcode ) ) {
$address_parts[] = $data->address->postalcode;
$address_parts[] = $data->address->countryCode;
$location->address = implode( ', ', $address_parts );
$location->locality_name = $data->address->placename;
$location->postal_code = $data->address->postalcode;
// Just look for a postal code
$url = 'http://api.geonames.org/findNearbyPostalCodesJSON?username=' . $this->geonames_username .
if ( !is_wp_error( $response ) ) {
$status = $response['response']['code'];
if ( ! empty( $data->postalCodes ) ) {
$postal_code = $data->postalCodes[0];
$admin_name = ( empty( $postal_code->adminName1 ) ? '' : $postal_code->adminName1 );
$location->address = $postal_code->placeName . ', ' .
$admin_name . ', ' . $postal_code->postalCode . ', ' .
$postal_code->countryCode;
$location->locality_name = $postal_code->placeName;
$location->postal_code = $postal_code->postalCode;
return array( $location );
* Use the Geonames web service to look up an administrative name.
* @param string $country_code
* @param string $admin_code Admin area name to look up. If empty, look up the country name.
* @return string|WP_ErrorThe administrative name.
if ( empty( $admin_code ) ) {
// Look up a country name
$country_info_url = 'http://api.geonames.org/countryInfoJSON?username=' . $this->geonames_username .
if ( is_wp_error( $country_info_response ) )
return $country_info_response;
$status = $country_info_response['response']['code'];
return new WP_Error( 'geocoder_http_request_failed', $status . ': ' . $country_info_response['response']['message'], $country_info_response );
if ( empty( $data->geonames ) )
$country_name = $data->geonames[0]->countryName;
$country_id = $data->geonames[0]->geonameId;
if ( !empty( $country_name ) )
$admin_search_url = 'http://api.geonames.org/searchJSON?maxRows=1&style=SHORT&featureCode=ADM1&username=' . $this->geonames_username .
if ( is_wp_error( $admin_search_response ) )
return $admin_search_response;
$status = $admin_search_response['response']['code'];
return new WP_Error( 'geocoder_http_request_failed', $status . ': ' . $admin_search_response['response']['message'], $admin_search_response );
if ( empty( $data ) or 0 == $data->totalResultsCount )
$admin_name = $data->geonames[0]->name;
$admin_id = $data->geonames[0]->geonameId;
if ( !empty( $admin_name ) )
* HTTP geocoder using the Google geocoding web service
* Do regular or reverse geocoding
* @param string $query_type 'address' or 'latlng'
* @return array Locations.
private function query( $query_type, $query ) {
$google_geocode_url = 'http://maps.google.com/maps/api/geocode/json?sensor=false&' . $query_type . '=' .
if ( is_wp_error( $response ) )
$status = $response['response']['code'];
return new WP_Error( 'geocoder_http_request_failed', $status . ': ' . $response['response']['message'], $response );
if ( 'ZERO_RESULTS' == $data->status )
if ( 'OK' != $data->status ) // status of OVER_QUERY_LIMIT, REQUEST_DENIED, INVALID_REQUEST, etc.
return new WP_Error( 'geocoder_request_failed', sprintf( __( 'The geocoding request failed with status %s.', 'GeoMashup' ), $status), $data );
foreach( $data->results as $result ) {
$location->lat = $result->geometry->location->lat;
$location->lng = $result->geometry->location->lng;
$location->address = $result->formatted_address;
if ( ! empty( $result->address_components ) ) {
foreach( $result->address_components as $component ) {
if ( in_array( 'country', $component->types ) )
$location->country_code = $component->short_name;
if ( in_array( 'administrative_area_level_1', $component->types ) )
$location->admin_code = $component->short_name;
if ( in_array( 'administrative_area_level_2', $component->types ) )
$location->sub_admin_code = $component->short_name;
if ( in_array( 'postal_code', $component->types ) )
$location->postal_code = $component->short_name;
if ( in_array( 'locality', $component->types ) )
$location->locality_name = $component->short_name;
$locations[] = $location;
public function geocode( $query ) {
return $this->query( 'address', $query );
return new WP_Error( 'bad_reverse_geocode_request', __( 'Reverse geocoding requires numeric coordinates.', 'GeoMashup' ) );
return $this->query( 'latlng', $lat . ',' . $lng );
* HTTP geocoder using the nominatim web service.
public function geocode( $query ) {
$geocode_url = 'http://nominatim.openstreetmap.org/search?format=json&polygon=0&addressdetails=1&q=' .
'&email=' . urlencode( get_option( 'admin_email' ) );
if ( is_wp_error( $response ) )
$status = $response['response']['code'];
return new WP_Error( 'geocoder_http_request_failed', $status . ': ' . $response['response']['message'], $response );
foreach( $data as $result ) {
$location->lat = $result->lat;
$location->lng = $result->lon;
$location->address = $result->display_name;
if ( !empty( $result->address ) ) {
if ( !empty( $first_result->address->country_code ) )
$location->country_code = strtoupper( $first_result->address->country_code );
// Returns admin name in address->state, but no code
if ( !empty( $first_result->address->county ) )
$location->sub_admin_code = $first_result->address->county;
if ( !empty( $first_result->address->postcode ) )
$location->postal_code = $first_result->address->postcode;
if ( !empty( $first_result->address->city ) )
$location = $first_result->address->city;
$locations[] = $location;
return new WP_Error( 'bad_reverse_geocode_request', __( 'Reverse geocoding requires numeric coordinates.', 'GeoMashup' ) );
$geocode_url = 'http://nominatim.openstreetmap.org/reverse?format=json&zoom=18&address_details=1&lat=' .
$lat . '&lon=' . $lng . '&email=' . urlencode( get_option( 'admin_email' ) );
if ( is_wp_error( $response ) )
$status = $response['response']['code'];
return new WP_Error( 'geocoder_http_request_failed', $status . ': ' . $response['response']['message'], $response );
$location->address = $data->display_name;
if ( !empty( $data->address ) ) {
if ( !empty( $data->address->country_code ) )
$location->country_code = strtoupper( $data->address->country_code );
// Returns admin name in address->state, but no code
if ( !empty( $data->address->county ) )
$location->sub_admin_code = $data->address->county;
if ( !empty( $data->address->postcode ) )
$location->postal_code = $data->address->postcode;
if ( !empty( $data->address->city ) )
$location->locality_name = $data->address->city;
return array( $location );
|