My task is to write a function that would take an array of zip codes and spit out only the zip codes that do not qualify. A non-qualifying zip code will not exist in the database and does NOT have other input zip codes within 140 miles.
For example, if I input 90210, 90211, 77389 into the function, it should only spit out 77389 since it is not close to 90210 and 90211. Both 90210 and 90211 are disqualifying zip codes because they are close to one another.
Here are the two functions I am using:
//Accepts an input array of zips and outputs an array of zips that are not in proximity of any other input zip by a predefined distance
protected function qualifyZips($zips, $radius=70){
$validInputZips = array();
//looping through input zips to validate them against the zip master table
foreach ($zips as $key => $zip) {
$inputZip = ZipCode::where('zip', $zip)->first(); //some zip data from DB
//While we are at it, let's grab the lat/lon
if ($inputZip) {
$validInputZips[$zip]['latitude'] = $inputZip->latitude;
$validInputZips[$zip]['longitude'] = $inputZip->longitude;
$validInputZips[$zip]['hits'] = 0;
}
}
$maskedInputZips = $validInputZips;
$outputArray = array();
foreach ($validInputZips as $zip => $latlon) {
foreach ($maskedInputZips as $maskedZip => $maskedLatlon) {
if ($zip != $maskedZip) {
$miles = $this->haversineGreatCircleDistance($latlon['latitude'], $latlon['longitude'], $maskedLatlon['latitude'], $maskedLatlon['longitude'], 3959);
if ($miles < ($radius * 2)) {
$validInputZips[$zip]['hits'] += 1;
}
}
}
if ($validInputZips[$zip]['hits'] == 0){
$outputArray[] = $zip;
}
}
return $outputArray;
}
protected function haversineGreatCircleDistance($latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo, $earthRadius = 3959)
{
// convert from degrees to radians
$latFrom = deg2rad($latitudeFrom);
$lonFrom = deg2rad($longitudeFrom);
$latTo = deg2rad($latitudeTo);
$lonTo = deg2rad($longitudeTo);
$latDelta = $latTo - $latFrom;
$lonDelta = $lonTo - $lonFrom;
$angle = 2 * asin(sqrt(pow(sin($latDelta / 2), 2) +
cos($latFrom) * cos($latTo) * pow(sin($lonDelta / 2), 2)));
return $angle * $earthRadius;
}
Some data:
array:3 [
90210 => array:3 [
"latitude" => "34.0900"
"longitude" => "-118.4100"
"hits" => 0
]
90211 => array:3 [
"latitude" => "34.0600"
"longitude" => "-118.3800"
"hits" => 0
]
77389 => array:3 [
"latitude" => "30.0600"
"longitude" => "-95.3800"
"hits" => 0
]
]