the street portion of the location * 'supplemental' => additional street portion of the location * 'province' => the province, state, or territory * 'country' => lower-cased two-letter ISO code (REQUIRED) * 'postal_code' => the international postal code for this location (REQUIRED) * * @return * An associative array where * 'lat' => approximate latitude of the center of the postal code's area * 'lon' => approximate longitude of the center of the postal code's area * */ function location_latlon_rough_uk($location = array()) { if (!isset($location['postal_code'])) { return NULL; } $results = _location_latlon_uk_geonames($location); if($results['lat'] AND $results['lon']) { return array('lat' => $results['lat'], 'lon' => $results['lon']); } else { return NULL; } } /** * Returns a lat/lon pair of the approximate center of the given postal code in the given country * * @param $location * An associative array $location where only postal code and country are necessary, but can have the keys: * 'street' => the street portion of the location * 'supplemental' => additional street portion of the location * 'province' => the province, state, or territory * 'country' => lower-cased two-letter ISO code (REQUIRED) * 'postal_code' => the international postal code for this location (REQUIRED) * * @return * An associative array where * 'lat' => approximate latitude of the center of the postal code's area * 'lon' => approximate longitude of the center of the postal code's area * */ function location_get_postalcode_data_uk($location = array()) { $dash_index = strpos($location['postal_code'], '-'); // First we strip slash off if we're dealing with a 9-digit US zipcode if (!($dash_index === FALSE)) { $location['postal_code'] = substr($location['postal_code'], 0, $dash_index); } //Lets use Geonames... $results = _location_latlon_uk_geonames($location); if($results['lat'] AND $results['lon']) { return array('lat' => $results['lat'], 'lon' => $results['lon']); } else { return NULL; } } /** * Parameters: * An associative array $location where * 'street' => the street portion of the location * 'supplemental' => additional street portion of the location * 'province' => the province, state, or territory * 'country' => lower-cased two-letter ISO code (REQUIRED) * 'postal_code' => the international postal code for this location (REQUIRED) * * */ function location_latlon_exact_uk($location = array()) { return NULL; // By uncommenting the line of code below, you legally acknowledge that you understand that you can only // do so under the terms of the Non-Commercial Share-alike license described at http://creativecommons.org/licenses/by-nc-sa/2.0/ //return _location_latlon_exact_uk_geocoder($location); } /** * Calls up the Geonames web-service to retrieve a lat/lon pair for many different countries... * http://www.geonames.org/export/free-geocoding.html * * @param $location * An associative array that represents an location where * 'street' => is the street location * 'supplemental' => any supplemental portion to the street location * 'city' => city name * 'province' => state, province, or territorial abbreviation * 'postal_code' => postal code * 'country' => lower-cased two-letter ISO code (REQUIRED) * * * @return * An associative array where * 'lat' => Is a float value in latitude * 'lon' => Is a float value in longitude * If the location supplied does not provide enough information, NULL is returned. * "Enough information" means that at least a country has been specified, along with a postcode, or a city name */ function _location_latlon_uk_geonames($location = array()) { $location_string = ''; if(!isset($location['country'])) { return NULL; //We can't do anything without a country code, so return null } $location_string = 'country='.$location['country'] . '&postalcode=' . $location['postal_code'] . '&placename=' . $location['city'] . '&maxRows=1&style=short'; $result = drupal_http_request('http://ws.geonames.org/postalCodeSearch?' . $location_string); //TODO: Need to include ERROR HANDLING for when the http_request doens't work... $data = $result->data; $xml_parser = drupal_xml_parser_create($data); xml_parse_into_struct($xml_parser, $data, $vals, $index); xml_parser_free($xml_parser); $params = array(); $level = array(); foreach ($vals as $xml_elem) { if ($xml_elem['type'] == 'open') { if (array_key_exists('attributes',$xml_elem)) { list($level[$xml_elem['level']],$extra) = array_values($xml_elem['attributes']); } else { $level[$xml_elem['level']] = $xml_elem['tag'].$id++; //Note modification to handle Geonames structure (number each code block...) } } if ($xml_elem['type'] == 'complete') { $start_level = 1; $php_stmt = '$params'; while($start_level < $xml_elem['level']) { $php_stmt .= '[$level['.$start_level.']]'; $start_level++; } $php_stmt .= '[$xml_elem[\'tag\']] = $xml_elem[\'value\'];'; eval($php_stmt); } } /*Note: Geonames doesn't have province data for the UK... but for other countries we might now like to perform an extra look up from the Lat, Long to find out the province... See: http://www.geonames.org/export/index.html#countrysubdiv */ IF($params['GEONAMES']['CODE1']['LAT']) { return array('lat' => floatval($params['GEONAMES']['CODE1']['LAT']), 'lon' => floatval($params['GEONAMES']['CODE1']['LNG']), 'postal_code' => $params['GEONAMES']['CODE1']['POSTALCODE'], 'city' => $params['GEONAMES']['CODE1']['NAME']); } else { return NULL; } } /* geodans UK Map Link functions... */ /** * @return * An array where * -> the key is the word that helps identify the name of function that builds the link. For example, a key of 'yahoo' means the name of the * the function that builds a link to a map on Yahoo! Maps would be 'location_map_link_us_yahoo' * -> the value is itself an array with 3 key/value pairs: * 'name' => points to the name of the mapping service. For 'yahoo', this would be 'Yahoo! Maps' * 'url' => the url of the main page of the mapping service. For 'yahoo', this would be 'http://maps.yahoo.com' * 'tos' => the url of the page that explains the map providers Terms of Service, or Terms of Use. For 'yahoo', this would be * 'http://help.yahoo.com/help/us/maps/maps-24.html' */ function location_map_link_uk_providers() { return array('google' => array( 'name' => 'Google Maps', 'url' => 'http://maps.google.co.uk', 'tos' => 'http://www.google.co.uk/intl/en_uk/help/terms_local.html'), 'Multimap' => array( 'name' => 'Multimap', 'url' => 'http://www.multimap.com', 'tos' => 'http://www.multimap.com/static/about6.htm') ); } /** * @return * An array of values that work as keys to the array returned by location_map_link_us_providers. The idea is that if the * administrator of the site has not yet had a chance to visit the "Map Links" subtab on the location module's settings page, * that we can provide deep-linking to a relatively safe default. By 'relatively safe', we mean that the Terms Of Service of * the provider of the maps are flexible enough for most parties. * * For the case of the U.S., 'google' has relatively flexible Terms Of Service, whereas Yahoo! Maps and MapQuest have more * restrictive Terms Of Service. * */ function location_map_link_uk_default_providers() { return array('google'); } function location_map_link_uk_google($location = array()) { $query_params = array(); // Order of priority is co-ordinates, postcode and then street/city if ($location['lat'] && $location['lon']) { $ll = $location['lat']. ",". $location['lon']; } if ($location['postal_code']) { $query_params[] = $location['postal_code']; } else { foreach (array('street', 'city') as $field) { if ($location[$field]) { $query_params[] = $location[$field]; } } } $base = 'http://maps.google.co.uk/?'; if (isset($ll)) { $url = $base. 'll='. $ll; return $url; } elseif (count($query_params)) { $url = $base. 'q='. urlencode(implode(" ", $query_params)); return $url; } else { return NULL; } } function location_map_link_uk_multimap($location = array()) { $query_params = ''; // Order of priority is co-ordinates, postcode and then street/city if ($location['lat'] && $location['lon']) { $query_params .= 'lat='. $location['lat']; $query_params .= '&lon='. $location['lon']; } elseif ($location['postal_code']) { $query_params = 'pc='. urlencode($location['postal_code']); } else { if ($location['street'] && $location['city']) { $query_params = 'quicksearch='. urlencode($location['street']. ', '. $location['city']); } elseif ($location['city']) { $query_params = 'quicksearch='. urlencode($location['city']); } } $base = 'http://www.multimap.com/map/places.cgi?'; if ($query_params) { $url = $base. $query_params; return $url; } else { return NULL; } } /** * Parameters: * -> $locationA is an associative array that represents a full location where * 'street' => the street portions of the location * 'supplemental' => additional street portion of the location * 'province' => the province, state, or territory * 'country' => lower-cased two-letter ISO code (REQUIRED) * -> $locationB is associative array that represents a full location in the same way that * parameter $locationB does. * * Returns: a link to driving directions * * For now, assume site-admin wants UK driving directions linked to Google Driving Directions. * Maybe later, we can add some kind of country-specific settings page that allows the site-admin to * decide which site to link to for driving directions. */ function location_driving_directions_link_uk($locationA, $locationB) { return _location_driving_directions_link_uk_google($locationA, $locationB); } /** * Parameters: * Function that is called by location_driving_directions_link_uk() under assumption that it * is the chosen function * * Returns: * a URL with HTTP GET variables * Depending on how full the locationes are, the URL will either point to the driving directions * on Yahoo! or, if only partial locationes are provided, a URL that points to the *form* for * Yahoo! driving directions where the form is filled with whatever fields have been provided * for the partial location(es). */ function _location_driving_directions_link_uk_google($locationA, $locationB) { if ($locationA['lat'] && $locationA['lon']) { $from = 'from '. $locationA['lat']. ','. $locationA['lon']; } elseif ($locationA['postal_code']) { $from = 'from '. $locationA['postal_code']; } if ($locationB['lat'] && $locationB['lon']) { $to = 'to '. $locationB['lat']. ','. $locationB['lon']; } elseif ($locationB['postal_code']) { $to = 'to '. $locationB['postal_code']; } if ($from && $to) { $get_query = urlencode($from. ' '. $to); return ('http://maps.google.co.uk/?'. $get_query); } else { return NULL; } } function theme_location_uk($location = array()) { $output = ''; if (count($location)) { $output .= "\n"; $output .= '