/**
  * Uses Google Maps API to parse flat address
  */
 static function parse($str, $returnAccuracy = false)
 {
     //CLEANUP
     $str = preg_replace('/[\\n\\r]/', ' ', $str);
     $key = sfConfig::get('sf_google_maps_key');
     $url = 'http://maps.google.com/maps/geo?q=' . urlencode($str) . '&output=xml&key=' . $key;
     //echo $url . "\n";
     $c = new sfWebBrowser();
     try {
         if (!$c->get($url)->responseIsError()) {
             $c->setResponseText(iconv('ISO-8859-1', 'UTF-8', $c->getResponseText()));
             $xml = $c->getResponseXml();
             //var_dump($xml);
             $structured = $xml->Response->Placemark->AddressDetails;
             $accuracy = (int) $structured['Accuracy'];
         } else {
             return null;
         }
     } catch (Exception $e) {
         // Adapter error (eg. Host not found)
         throw $e;
     }
     //accuracy of 4+ means we have at least a town (UNLESS THE TOWN DOESN'T "OFFICIALLY" EXIST)
     if ($accuracy > 3) {
         $address = new Address();
         //COUNTRY (USA only for now)
         $address->country_id = 1;
         //STATE (for some reason trickery needs to be done to get state to work right)
         $stateName = null;
         if (isset($structured->Country->AdministrativeArea->AdministrativeAreaName)) {
             $stateName = (array) $structured->Country->AdministrativeArea->AdministrativeAreaName;
             $stateName = isset($stateName[0]) ? $stateName[0] : $stateName;
         } else {
             $possible_state = $structured->Country->CountryNameCode;
             if ($possible_state != 'US') {
                 $stateName = $possible_state;
             }
         }
         if (!$stateName) {
             return null;
         }
         if (!($state = AddressStateTable::retrieveByText($stateName))) {
             return null;
         }
         $address->state_id = $state->id;
         //COUNTY (this may not exist)
         $countyName = $structured->Country->AdministrativeArea->SubAdministrativeArea->SubAdministrativeAreaName;
         $address->county = LsString::emptyToNull((string) $countyName);
         if ($countyName) {
             $cityName = $structured->Country->AdministrativeArea->SubAdministrativeArea->Locality->LocalityName;
         } else {
             $cityName = $structured->Country->AdministrativeArea->Locality->LocalityName;
         }
         //CITY (this may not exist!)
         $address->city = (string) $cityName;
         //accuracy of 5+ means we have postal code
         if ($accuracy > 4) {
             if ($cityName && $countyName) {
                 $base = $structured->Country->AdministrativeArea->SubAdministrativeArea->Locality;
                 if (isset($base->DependentLocality)) {
                     $base = $base->DependentLocality;
                 }
             } else {
                 if ($cityName && !$countyName) {
                     $base = $structured->Country->AdministrativeArea->Locality;
                 } else {
                     if (!$cityName && $countyName) {
                         $base = $structured->Country->AdministrativeArea->SubAdministrativeArea;
                     } else {
                         $base = $structured->Country->AdministrativeArea;
                     }
                 }
             }
             //POSTAL CODE (for some reason trickery needs to be done to get postal code to work right)
             if ($postalCode = (array) $base->PostalCode->PostalCodeNumber) {
                 $postalCode = $postalCode[0];
                 $address->postal = (string) $postalCode;
             }
             //accuracy of 8 means we have exact match
             //echo $accuracy . "\n";
             if ($accuracy > 5) {
                 //STREET (unit info is lost)
                 //echo "street1 info found \n";
                 $street1 = $base->Thoroughfare->ThoroughfareName;
                 $address->street1 = (string) $street1;
             }
         }
         //COORDINATES
         // Parse the coordinate string
         $coords = $c->getResponseXml()->Response->Placemark->Point->coordinates;
         list($lon, $lat, $alt) = explode(",", $coords);
         $address->longitude = $lon;
         $address->latitude = $lat;
         if ($returnAccuracy) {
             return array('address' => $address, 'accuracy' => $accuracy);
         } else {
             return $address;
         }
     } else {
         return null;
     }
 }
Exemple #2
0
 public function removeFields($fields)
 {
     $diff = array_diff($this->getFieldsArray(), (array) $fields);
     sort($diff);
     return $this->fields = LsString::emptyToNull(implode(',', $diff));
 }