From: Stéphane Jacob Date: Thu, 23 Dec 2010 20:04:13 +0000 (+0100) Subject: Also tries to geocode in the country's languages if geocoded and given text don't... X-Git-Tag: xorg/1.0.2~59 X-Git-Url: http://git.polytechnique.org/?a=commitdiff_plain;h=803612aed41026b035217d47f32763b4f65562de;p=platal.git Also tries to geocode in the country's languages if geocoded and given text don't match. Signed-off-by: Stéphane Jacob --- diff --git a/classes/address.php b/classes/address.php index 0ba8f93..d7f7970 100644 --- a/classes/address.php +++ b/classes/address.php @@ -298,6 +298,9 @@ class Address public $localityName = null; public $subAdministrativeAreaName = null; public $administrativeAreaName = null; + public $localityNameLocal = null; + public $subAdministrativeAreaNameLocal = null; + public $administrativeAreaNameLocal = null; public $countryId = null; public $latitude = null; public $longitude = null; @@ -609,26 +612,29 @@ class Address public function toFormArray() { $address = array( - 'accuracy' => $this->accuracy, - 'text' => $this->text, - 'postalText' => $this->postalText, - 'postalCode' => $this->postalCode, - 'localityId' => $this->localityId, - 'subAdministrativeAreaId' => $this->subAdministrativeAreaId, - 'administrativeAreaId' => $this->administrativeAreaId, - 'countryId' => $this->countryId, - 'localityName' => $this->localityName, - 'subAdministrativeAreaName' => $this->subAdministrativeAreaName, - 'administrativeAreaName' => $this->administrativeAreaName, - 'latitude' => $this->latitude, - 'longitude' => $this->longitude, - 'north' => $this->north, - 'south' => $this->south, - 'east' => $this->east, - 'west' => $this->west, - 'error' => $this->error, - 'changed' => $this->changed, - 'removed' => $this->removed, + 'accuracy' => $this->accuracy, + 'text' => $this->text, + 'postalText' => $this->postalText, + 'postalCode' => $this->postalCode, + 'localityId' => $this->localityId, + 'subAdministrativeAreaId' => $this->subAdministrativeAreaId, + 'administrativeAreaId' => $this->administrativeAreaId, + 'countryId' => $this->countryId, + 'localityName' => $this->localityName, + 'subAdministrativeAreaName' => $this->subAdministrativeAreaName, + 'administrativeAreaName' => $this->administrativeAreaName, + 'localityNameLocal' => $this->localityNameLocal, + 'subAdministrativeAreaNameLocal' => $this->subAdministrativeAreaNameLocal, + 'administrativeAreaNameLocal' => $this->administrativeAreaNameLocal, + 'latitude' => $this->latitude, + 'longitude' => $this->longitude, + 'north' => $this->north, + 'south' => $this->south, + 'east' => $this->east, + 'west' => $this->west, + 'error' => $this->error, + 'changed' => $this->changed, + 'removed' => $this->removed, ); if (!is_null($this->geocodedText)) { $address['geocodedText'] = $this->geocodedText; diff --git a/classes/geocoder.php b/classes/geocoder.php index 425b017..0808f4e 100644 --- a/classes/geocoder.php +++ b/classes/geocoder.php @@ -41,9 +41,10 @@ abstract class Geocoder { ); $areaName = $area . 'Name'; + $areaNameLocal = $areaName . 'Local'; $areaId = $area . 'Id'; if (!is_null($address->$areaName) && isset($databases[$area])) { - $res = XDB::query('SELECT id + $res = XDB::query('SELECT id, nameLocal FROM ' . $databases[$area] . ' WHERE name = {?}', $address->$areaName); diff --git a/classes/gmapsgeocoder.php b/classes/gmapsgeocoder.php index 38eff81..d8fad1f 100644 --- a/classes/gmapsgeocoder.php +++ b/classes/gmapsgeocoder.php @@ -78,15 +78,19 @@ class GMapsGeocoder extends Geocoder { // Updates the address with the geocoded information from Google Maps. Also // cleans up the final informations. private function getUpdatedAddress(Address &$address, array $geocodedData, $extraLines) { - $this->fillAddressWithGeocoding($address, $geocodedData); + $this->fillAddressWithGeocoding($address, $geocodedData, false); $this->formatAddress($address, $extraLines); } // Retrieves the Placemark object (see #getPlacemarkFromJson()) for the @p // address, by querying the Google Maps API. Returns the array on success, // and null otherwise. - private function getPlacemarkForAddress($address) { - $url = $this->getGeocodingUrl($address); + private function getPlacemarkForAddress($address, $defaultLanguage = null) { + if (is_null($defaultLanguage)) { + $defaultLanguage = Platal::globals()->geocoder->gmaps_hl; + } + + $url = $this->getGeocodingUrl($address, $defaultLanguage); $geoData = $this->getGeoJsonFromUrl($url); return ($geoData ? $this->getPlacemarkFromJson($geoData) : null); @@ -99,13 +103,13 @@ class GMapsGeocoder extends Geocoder { // Builds the Google Maps geocoder url to fetch information about @p address. // Returns the built url. - private function getGeocodingUrl($address) { + private function getGeocodingUrl($address, $defaultLanguage) { global $globals; $parameters = array( 'key' => $globals->geocoder->gmaps_key, 'sensor' => 'false', // The queried address wasn't obtained from a GPS sensor. - 'hl' => $globals->geocoder->gmaps_hl, + 'hl' => $defaultLanguage, 'oe' => 'utf8', // Output encoding. 'output' => 'json', // Output format. 'gl' => $globals->geocoder->gmaps_gl, @@ -178,38 +182,45 @@ class GMapsGeocoder extends Geocoder { } // Fills the address with the geocoded data - private function fillAddressWithGeocoding(Address &$address, $geocodedData) { + private function fillAddressWithGeocoding(Address &$address, $geocodedData, $isLocal) { // The geocoded address three is // Country -> AdministrativeArea -> SubAdministrativeArea -> Locality -> Thoroughfare // with all the possible shortcuts // The address is formatted as xAL, or eXtensible Address Language, an international // standard for address formatting. // xAL documentation: http://www.oasis-open.org/committees/ciq/ciq.html#6 - $address->geocodedText = str_replace(', ', "\n", $geocodedData['address']); + if ($isLocal) { + $ext = 'Local'; + } else { + $ext = ucfirst(Platal::globals()->geocoder->gmaps_hl); + $address->geocodedText = str_replace(', ', "\n", $geocodedData['address']); + } + if (isset($geocodedData['AddressDetails']['Accuracy'])) { $address->accuracy = $geocodedData['AddressDetails']['Accuracy']; } $currentPosition = $geocodedData['AddressDetails']; if (isset($currentPosition['Country'])) { + $country = 'country' . $ext; $currentPosition = $currentPosition['Country']; $address->countryId = $currentPosition['CountryNameCode']; - $address->country = $currentPosition['CountryName']; + $address->$country = $currentPosition['CountryName']; } if (isset($currentPosition['AdministrativeArea'])) { - $currentPosition = $currentPosition['AdministrativeArea']; - $address->administrativeAreaName = $currentPosition['AdministrativeAreaName']; + $administrativeAreaName = 'administrativeAreaName' . $ext; + $currentPosition = $currentPosition['AdministrativeArea']; + $address->$administrativeAreaName = $currentPosition['AdministrativeAreaName']; } if (isset($currentPosition['SubAdministrativeArea'])) { - $currentPosition = $currentPosition['SubAdministrativeArea']; - $address->subAdministrativeAreaName = $currentPosition['SubAdministrativeAreaName']; + $subAdministrativeAreaName = 'subAdministrativeAreaName' . $ext; + $currentPosition = $currentPosition['SubAdministrativeArea']; + $address->$subAdministrativeAreaName = $currentPosition['SubAdministrativeAreaName']; } if (isset($currentPosition['Locality'])) { - $currentPosition = $currentPosition['Locality']; - $address->localityName = $currentPosition['LocalityName']; - } - if (isset($currentPosition['Thoroughfare'])) { - $address->thoroughfareName = $currentPosition['Thoroughfare']['ThoroughfareName']; + $localityName = 'localityName' . $ext; + $currentPosition = $currentPosition['Locality']; + $address->$localityName = $currentPosition['LocalityName']; } if (isset($currentPosition['PostalCode'])) { $address->postalCode = $currentPosition['PostalCode']['PostalCodeNumber']; @@ -236,14 +247,11 @@ class GMapsGeocoder extends Geocoder { } } - // Formats the text of the geocoded address using the unused data and - // compares it to the given address. If they are too different, the user - // will be asked to choose between them. - private function formatAddress(Address &$address, $extraLines) { + // Compares the geocoded address with the given address and returns true + // iff their are close enough to be considered as equals or not. + private function compareAddress($address) + { $same = true; - if ($extraLines) { - $address->geocodedText = $extraLines . "\n" . $address->geocodedText; - } $geoloc = strtoupper(preg_replace(array("/[0-9,\"'#~:;_\- ]/", "/\r\n/"), array('', "\n"), $address->geocodedText)); $text = strtoupper(preg_replace(array("/[0-9,\"'#~:;_\- ]/", "/\r\n/"), @@ -269,9 +277,41 @@ class GMapsGeocoder extends Geocoder { } } - if ($same) { + return $same; + } + + // Formats the text of the geocoded address using the unused data and + // compares it to the given address. If they are too different, the user + // will be asked to choose between them. + private function formatAddress(Address &$address, $extraLines) + { + if ($extraLines) { + $address->geocodedText = $extraLines . "\n" . $address->geocodedText; + } + + if ($this->compareAddress($address)) { $address->geocodedText = null; } else { + $languages = XDB::fetchOneCell('SELECT IF(ISNULL(gc1.belongsTo), gc1.languages, gc2.languages) + FROM geoloc_countries AS gc1 + LEFT JOIN geoloc_countries AS gc2 ON (gc1.belongsTo = gc2.iso_3166_1_a2) + WHERE gc1.iso_3166_1_a2 = {?}', + $address->countryId); + $toGeocode = substr($address->text, strlen($extraLines)); + foreach (explode(',', $languages) as $language) { + if ($language != Platal::globals()->geocoder->gmaps_hl) { + $geocodedData = $this->getPlacemarkForAddress($toGeocode, $language); + $address->geocodedText = str_replace(', ', "\n", $geocodedData['address']); + if ($extraLines) { + $address->geocodedText = $extraLines . "\n" . $address->geocodedText; + } + if ($this->compareAddress($address)) { + $this->fillAddressWithGeocoding($address, $geocodedData, true); + $address->geocodedText = null; + break; + } + } + } $address->geocodedText = str_replace("\n", "\r\n", $address->geocodedText); } $address->text = str_replace("\n", "\r\n", $address->text);