Index: branches/RC/core/units/general/helpers/geocode_helper.php =================================================================== diff -u --- branches/RC/core/units/general/helpers/geocode_helper.php (revision 0) +++ branches/RC/core/units/general/helpers/geocode_helper.php (revision 11436) @@ -0,0 +1,173 @@ +Application->ConfigValue('GeoCodeUser'); + $pass = $this->Application->ConfigValue('GeoCodePass'); + + $rie_path = sprintf(FULL_PATH.'/tools/rie/rie -u %s -p %s -g "%s" -l', + $user, + $pass, + $address.'|'.$city.'|'.$state.'|'.$zip + ); + + exec($rie_path, $geo_array, $code); + + if ($code == 0) { + $out_data = explode('|', $geo_array[2]); + + include_once(FULL_PATH.'/compat/array_combine.php'); + $assoc_data = array_combine(explode('|', $geo_array[1]), $out_data); + + $lon = abs($out_data[8]); // set to positive, because required by SQL formula + $lat = $out_data[7]; + + $zip4 = $out_data[9]; + $dpbc = $out_data[10]; + $carrier = $out_data[11]; + } + else { + $lon = ''; + $lat = ''; + $zip4 = ''; + $dpbc = ''; + $carrier = ''; + $assoc_data = Array(); + } + + return Array($lon, $lat, $zip4, $dpbc, $carrier, serialize($assoc_data)); + } + + function getTag($tag, $xml) + { + $open_tag_pos = strpos($xml, '<'.$tag.'>'); + $close_tag_pos = strpos($xml, ''); + if (!$open_tag_pos || !$close_tag_pos) + { + return ''; + } + $tag_length = strlen($tag) + 2; + return substr($xml, $open_tag_pos + $tag_length, $close_tag_pos - $open_tag_pos - $tag_length); + } + + function QueryCoordinatesFromGoogle($address, $city, $state, $zip) + { + // 1908 Pike pl, Seattle, WA + // http://maps.google.com/maps/geo? + // ABQIAAAAzNbTbxHki-PAnXzsrA7z2hR0fs2_a3JecCfKmMFhGT8VtEjV7xRV8rMK1czaEH2ZG3eiYJMuej_vnQ + + $qaddress = $address.', '.$city.', '.$state; + $request_url = $this->Application->ConfigValue('GoogleMapsURL').'output=xml&key='. + $this->Application->ConfigValue('GoogleMapsKey').'&q='.urlencode($qaddress); + + $delay = 0; + while (true) + { + $xml = file_get_contents($request_url); + if (strpos($xml, '620')) { + $delay += 100000; + } elseif (strpos($xml, '200')) { + // get latitude, longitude and zip from xml-answer + $a_coords = explode(',', $this->getTag('coordinates', $xml)); + $lat = $a_coords[1]; + $lon = abs($a_coords[0]); // set to positive, because required by SQL formula + $zip4 = $this->getTag('PostalCodeNumber', $xml); + $dpbc = ''; + $carrier = ''; + $assoc_data = Array(); + break; + } else { + $lon = ''; + $lat = ''; + $zip4 = ''; + $dpbc = ''; + $carrier = ''; + $assoc_data = Array(); + break; + } + usleep($delay); + } + + return Array($lon, $lat, $zip4, $dpbc, $carrier, serialize($assoc_data)); + + } + + /** + * Try to find lon, lat by address return false if failed + * + * @param string $address + * @param string $city + * @param string $state + * @param int $zip + * @return Array (lon, lat) + */ + function GetCoordinates($address, $city, $state, $zip, $no_cache = false, $force_cache = false) + { + if (!$zip && !$state) { + // if state or zip missing then do nothing + return false; + } + + $zip_info = $no_cache ? false : $this->GetFromCache($address, $city, $state, $zip); +// $zip_info = $this->GetFromCache($address, $city, $state, $zip); + + if (!$zip_info && !$force_cache) { + list($lon, $lat, $zip4, $dpbc, $carrier, $geocode_answer) = $this->QueryCoordinatesFromGoogle($address, $city, $state, $zip); + + if ($lon != '' && $lat != '') { + // valid position returned by geocode => add to cache + $fields_hash = Array( + 'zipcode' => $zip4, + 'address' => $address, + 'city' => $city, + 'state' => $state, + 'lat' => $lat, + 'lon' => $lon, + 'zip4' => $zip4, + 'dpbc' => $dpbc, + 'carrier' => $carrier, + 'geocode_answer' => $geocode_answer, + ); + $this->Conn->doInsert($fields_hash, TABLE_PREFIX.'ZipCodes'); + return Array($lon, $lat, $zip4, $dpbc, $carrier); + } + else { + // bad case, rie call failed => no data retrieved + return false; + } + } + + return Array($zip_info['lon'], $zip_info['lat'], getArrayValue($zip_info, 'zip4'), getArrayValue($zip_info, 'dpbc'), getArrayValue($zip_info, 'carrier')); + } + + /** + * Try to find cached lon, lat by address + * + * @param string $address + * @param string $city + * @param string $state + * @param int $zip + * @return Array (lon, lat) + */ + function GetFromCache($address, $city, $state, $zip) + { + $zip = substr($zip, 0, 5); // use only first 5 digits + $sql = 'SELECT lon, lat + FROM '.TABLE_PREFIX.'ZipCodes + WHERE zipcode = '.$this->Conn->qstr($zip); + return $this->Conn->GetRow($sql); + } + } + +?> \ No newline at end of file