I have a longitude and latitude as a string in PHP like below
49.648881
-103.575312
And I want to take that and look in an array of values to find the closest one. The array looks like
array(
'0'=>array('item1','otheritem1details....','55.645645','-42.5323'),
'1'=>array('item1','otheritem1details....','100.645645','-402.5323')
);
I want to return the array that has the closest long and lad. In this case it would be the first one (and yes I know -400 is not a a possible value).
Is there any quick and easy way to do this? I tried array searching but that didn't work.
Difference code
function distance($lat1, $lon1, $lat2, $lon2, $unit) {
$theta = $lon1 - $lon2;
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
$dist = acos($dist);
$dist = rad2deg($dist);
$miles = $dist * 60 * 1.1515;
$unit = strtoupper($unit);
if ($unit == "K") {
return ($miles * 1.609344);
} else if ($unit == "N") {
return ($miles * 0.8684);
} else {
return $miles;
}
}
php"); $lat = "3.107685"; $lon = "101.7624521"; $sql="SELECT ((ACOS(SIN($lat * PI() / 180) * SIN(lat * PI() / 180) + COS($lat * PI() / 180) * COS(lat * PI() / 180) * COS(($lon – lon) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS 'distance' FROM loc_coordinate HAVING 'distance'<='10' ORDER BY 'distance' ASC"; $stmt =$ ...
Enter coordinates to find a place On your computer, open Google Maps. In the search box, enter your coordinates. Here are examples of formats that work: Decimal degrees (DD): 41.40338, 2.17403.
For this divide the values of longitude and latitude of both the points by 180/pi. The value of pi is 22/7. The value of 180/pi is approximately 57.29577951. If we want to calculate the distance between two places in miles, use the value 3, 963, which is the radius of Earth.
You need to map the distance of each item to the reference point first.
Then you sort the map and then you can tell which has the lowest (or highest if you reverse the search) distance:
$ref = array(49.648881, -103.575312);
$items = array(
'0' => array('item1','otheritem1details....','55.645645','-42.5323'),
'1' => array('item1','otheritem1details....','100.645645','-402.5323')
);
$distances = array_map(function($item) use($ref) {
$a = array_slice($item, -2);
return distance($a, $ref);
}, $items);
asort($distances);
echo 'Closest item is: ', var_dump($items[key($distances)]);
Output:
Closest item is: array(4) {
[0]=>
string(5) "item1"
[1]=>
string(21) "otheritem1details...."
[2]=>
string(9) "55.645645"
[3]=>
string(8) "-42.5323"
}
Take care you have the right order of lat and long.
The distance function (only the header slightly changed and units have been dropped):
function distance($a, $b)
{
list($lat1, $lon1) = $a;
list($lat2, $lon2) = $b;
$theta = $lon1 - $lon2;
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
$dist = acos($dist);
$dist = rad2deg($dist);
$miles = $dist * 60 * 1.1515;
return $miles;
}
Rather using the law of cosines for distance, you can use flat earth approximation. The flat earth equations reduce the number of trig functions in the calculation. The Δlat, Δlon is the difference between your reference point and the test point.
This formula would not be accurate for long distance navigation (thousands of miles) but for this particular problem, you aren't really interested in accurate distance, but who is the closest point to me. This is a simpler formulation that should give you that.
x = Δlon * cos(lat) // lat/lon are in radians!
y = Δlat
distance = R * sqrt( x² + y² ) // R is radius of the earth;
// typical value is 6371 km
Reference: http://www.movable-type.co.uk/scripts/latlong.html
Distance code
function distanceMeters($lat1, $lon1, $lat2, $lon2) {
$x = deg2rad( $lon1 - $lon2 ) * Math.cos( deg2rad( ($lat1+$lat2) /2 ) );
$y = deg2rad( $lat1 - $lat2 );
$dist = 6371000.0 * Math.sqrt( $x*$x + $y*$y );
return $dist;
}
function deg2rad(degrees) {
var pi = Math.PI;
return degrees * (pi/180);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With