I've been doing this in MySQL for years, but how can I do this in PHP?
Example CoordinateArray: http://pastebin.com/grVsbgL9
I'd like to return all the coordinates within 100 miles of a given coordinate.
function getCoordinatesWithinRadius ($coordinateArray, $center, $radius) {
//
return $resultArray;
}
In MySQL I typically used a query like:
SELECT *, ( 3959 * acos( cos( radians($latitude) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians($longitude) ) + sin( radians($latitude) ) * sin( radians( latitude ) ) ) ) AS distance FROM table HAVING distance < $radius ORDER BY distance;
How can I do the same in PHP?
In the code below, I'm assuming your coordinate objects are just stored as a two element array (both for the $center parameter and the coordinates in the $coordinateArray). If not it should be fairly obvious what you need to change.
function getCoordinatesWithinRadius ($coordinateArray, $center, $radius) {
$resultArray= array();
$lat1 = $center[0];
$long1 = $center[1];
foreach ($coordinateArray as $coordinate) {
$lat2 = $coordinate[0];
$long2 = $coordinate[1];
$distance = 3959 * acos(cos(radians($lat1)) * cos(radians($lat2)) * cos(radians($long2) - radians($long1)) + sin(radians($lat1)) * sin(radians($lat2)));
if ($distance < $radius) $resultArray[] = $coordinate;
}
return $resultArray;
}
The code just loops through all the coordinates, calculates the distance from the center point, and if its less than the given $radius, adds the coordinate to the $resultArray.
I haven't checked the $distance calcuation - that's basically just cut and paste from your mysql query, so I'm assuming that's correct.
Also the above code assumes the existence of a radians function. If you don't have one, you could add one like this:
function radians($deg) {
return $deg * M_PI / 180;
}
That's assuming the coordinates are in degrees.
Here is more imporoved version of function shared by James
/**
* @author WPExperts
* @usange to get array of all markers within certain radius
* @param $coordinateArray
* @param $center
* @param $radius
* @return array
*/
function wpe_getCoordinatesWithinRadius ( $lat1 , $lng1 , $radius , $available_markers ) {
$stores_data = $available_markers;
$resultArray= array();
foreach ( $stores_data as $store ) {
$lat2 = $store->lat;
$lng2 = $store->lng;
$distance = 3959 * acos(cos(wpe_radians($lat1)) * cos(wpe_radians($lat2)) * cos(wpe_radians($lng2) - wpe_radians($lng1)) + sin(wpe_radians($lat1)) * sin(wpe_radians($lat2)));
if ($distance < $radius){
$resultArray[] = (object) array( 'ID' => $store->ID , 'lat' => $store->lat , 'lng' => $store->lng , 'distance' => $distance );
}
}
// need to return id,distance,lat and lng
return $resultArray;
}
/**
* @usage to convert degree into radians
* @param $deg
* @return float
*/
function wpe_radians($deg) {
return $deg * M_PI / 180;
}
Hope this might help others in community out there.