Find closest longitude and latitude in array?

空扰寡人 提交于 2019-11-28 17:06:00

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 ) * cos( deg2rad( $lat1 ) );
  $y = deg2rad( $lat1 - $lat2 ); 
  $dist = 6371000.0 * sqrt( $x*$x + $y*$y );

  return $dist;
}

There is no quick and easy way to do that. You have to iterate through all elements and calculate distance between them and starting point, save the result and repeat, saving the result only if it is lower then previous.

Chris Sobolewski

Iterate through the array, comparing values to what you have. If the value is smaller than your currently stored value (or if you don't have a currently stored value), store that value instead, otherwise throw it away.

$closest = null;
foreach($array as $key => $value){
    $distance = //compare distance here;
    if ($closest === null || $closest > $distance) {
        $closest = $distance;
    };
};

Of course, this will be made more difficult by the fact that latitude and longitude are on a sphere, and longitudes 179 and -179 are closer than 90 and 179.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!