检查坐标是否距离其他坐标在特定范围内

3

好的,我有一组特定坐标的目标,以及一些其他坐标上的人员,我想要检查这些人员的坐标是否距离目标坐标在2公里(2000米)以内。

下面的代码只是为了更清楚地说明我的需求,问题当然是如何实现这个功能?我非常感谢能够提供解决方案,谢谢!

$person0 = Array('56.34342', '49.324523');
$person1 = Array('57.49544', '47.421524');
$person2 = Array('56.74612', '48.722323');

$target = Array('56.35343', '49.342343');

for (var $i = 0; $i < 4; i$++) {
    CheckIfMatch($person + i$);
}

function CheckIfMatch($person) {
    if($person is within 2km from target) {
        echo 'Match!';
    }
}

6
请搜索“Haversine”或“Vincenty”。 - Mark Baker
你试过使用欧氏距离吗? - mamdouh alramadan
3个回答

4
你可以使用大圆算法来完成这个任务。http://en.wikipedia.org/wiki/Great-circle_distance 下面是如何计算距离的方法。 编辑 以下是完整的代码,供您使用!
<?php
$persons = Array();

$persons[] = Array('52.00951','4.36052');//Delft is more than 2 km from den haag
$persons[] = Array('52.03194','4.31769');//Rijswijk is less than 2 km from den haag
$persons[] = Array('52.07097','4.29945');//A place near den Haag almost 2 streets from center and my favourite coffee shop
$persons[] = Array('52.37022','4.89517');//Amsterdamn is about 60 km *DRIVING* from the hagues according to Gmaps

$target = Array('52.07050', '4.30070');//Den Haag
$i = 0;
foreach($persons as $person){
    $i++;
    $distance = calculate_distance($person, $target);
    if($distance <= 2 ){ 
        echo "Person $i is within 2km with a distance to taget of $distance</br>";
    }else{
        echo "Person $i is <b>not</b> within 2km with a distance to taget of $distance</br>";
    }

}

function calculate_distance($person, $target){

    $lat1 = $person[0];
    $lng1 = $person[1];
    $lat2 = $target[0];
    $lng2 = $target[1];
    $pi = 3.14159;
    $rad = doubleval($pi/180.0);

    $lon1 = doubleval($lng1)*$rad;
    $lat1 = doubleval($lat1)*$rad; 
    $lon2 = doubleval($lng2)*$rad; 
    $lat2 = doubleval($lat2)*$rad; 
    $theta = $lng2 - $lng1; 

    $dist = acos(sin($lat1) * sin($lat2) + cos($lat1) * cos($lat2) * cos($theta)); 

    if ($dist < 0) 
        $dist += $pi;


    $miles = doubleval($dist * 69.1); 
    $inches = doubleval($miles * 63360); 
    $km  =  doubleval($dist * 115.1666667);

    $dist = sprintf( "%.2f",$dist); 
    $miles = sprintf( "%.2f",$miles); 
    $inches = sprintf( "%.2f",$inches); 
    $km = sprintf( "%.2f",$km);
    //Here you can return whatever you please
    return $km;
}

?>

当然还有结果:

Person 1 is not within 2km with a distance to taget of 4.24
Person 2 is within 2km with a distance to taget of 1.21
Person 3 is within 2km with a distance to taget of 0.09
Person 4 is not within 2km with a distance to taget of 41.56

1
@holyredbeard的回答已更新,包含了你想要的代码。我相信它非常完整和易懂。 - Jimmy Kane
我知道这是一个旧的堆栈,但我找到了这个脚本,当我使用它时,它会返回0.00。无论我插入哪个纬度和经度都是如此。有人可以帮帮我吗? - Daniel
@DanielLundahl 我刚刚重新运行了代码,一切正常。你能详细说明一下吗? - Jimmy Kane
@JimmyKane 我知道我的变量具有纬度和经度的值,但在 $dist = acos(..... 返回 0 后打印 $dist。在设置 $dist 变量时出了问题。 - Daniel
@DanielLundahl,请提出一个问题,说明您如何使用此算法,我很乐意帮助您。请先粘贴您使用的代码,然后在此处提及链接。我无法通过评论来帮助您,也不理解您的变量表示什么,它们的结构和类型是什么。这太抽象了。 - Jimmy Kane
显示剩余5条评论

3

我有一个函数,它计算点1和点2之间的距离差。该函数返回英里数,因此我将其乘以1.609344来转换为公里。

<?php
function lat_long_dist($lat1, $long1, $lat2, $long2){
    $pi = pi();
    $x  = sin($lat1 * $pi/180) * 
          sin($lat2 * $pi/180) + 
          cos($lat1 * $pi/180) * 
          cos($lat2 * $pi/180) * 
          cos(($long2 * $pi/180) - ($long1 * $pi/180));
    $x  = atan((sqrt(1 - pow($x, 2))) / $x);
    return (1.852 * 60.0 * (($x/$pi) * 180)) / 1.609344;
}

$people   = array();
$people[] = array(56.34342, 49.324523);
$people[] = array(57.49544, 47.421524);
$people[] = array(56.74612, 48.722323);

foreach($people as $person){
    $lat1 = $person[0];
    $lon1 = $person[1];
    $distance = lat_long_dist($lat1, $lon1, 56.35343, 49.342343) * 1.609344;
    if($distance <= 2){
        echo "$i is within 2km!\n";
    }
}

1
非常感谢您分享您的代码!我会立即尝试它。 - holyredbeard

0
使用勾股定理来依次计算目标和每个人之间的距离,并检查是否小于2公里。 如果x,y是目标的坐标,p,q是其中一个人的坐标,则两者之间的距离为: ((x-p)^2 + (y-q)^2)^(1/2) 符号^表示“乘方”。

1
如果它们是平面上的点,那么这个方法可行,但如果它们是地理坐标(球面上的点),你需要使用Haversine函数。 - Mark Reed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接