array('name' => 'Geonames Webservice', 'url' => 'http://www.geonames.org/export/', 'tos' => 'http://creativecommons.org/licenses/by/2.5/') ); } /** * 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_geocode_generic_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; } }