在指定纬度和经度的指定距离内查找人物

时间:2014-05-20 05:13:36

标签: php google-maps google-maps-api-3

我正在编写PHP应用程序,我需要在给定纬度和经度的指定距离内找到所有人。 注意:我知道,其他/所有人的纬度和经度,

但是,我怎样才能找到距离我的纬度和经度一定英里/公里范围内的所有经度和纬度。

我该怎么计算? 请注意:不建议我计算给定纬度和经度内的所有人的距离,因为可能有1000人注册并计算每个人的距离并且与我的半径匹配将是非常耗时的。

我希望有这样的反向公式: - 我知道距离,我知道我的纬度和经度,我做了一些计算,我得到了我指定的纬度和经度范围内的所有其他人。

示例: - 对于一个实例,我的纬度是15,经度是30,所以半径5公里范围内的所有其他人都应该显示在列表中。

以下几个存储在我的数据库中的人: - (人们拉特和长期经常变化)

人A: - 长(20)长(24)

人B: - 长(15)长(19)

人C: - 长(22)长(19)

人D: - 长(220)长(24)

人E: - 长(15)长(19)

人F: - 长(22)长(19)

人G: - 长(20)长(24)

人H: - 长(15)长(19)

人I: - 长(22)长(19)

使用aprox 1000+用户列表

依旧等等。

从纬度和长度来看,我的意思是分别在纬度和经度之上。

以下是harversine公式,但对我来说没用,因为这需要很长的时间来实现我的目标。

    <?php
    function getLatLong($address) {
        $address = str_replace(' ', '+', $address);
        $url = 'http://maps.googleapis.com/maps/api/geocode/json?address='.$address.'&sensor=false';
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $geoloc = curl_exec($ch);
        $json = json_decode($geoloc);

        return array($json->results[0]->geometry->location->lat, $json->results[0]->geometry->location->lng);
    }

    $address = getLatLong('Guildford');
    $address = getLatLong('BH15 2BT');
    $address = getLatLong('10 Downing Street, London');

    function Haversine($start, $finish) {
        $theta = $start[1] - $finish[1];

        $distance = (sin(deg2rad($start[0])) * sin(deg2rad($finish[0]))) + (cos(deg2rad($start[0])) * cos(deg2rad($finish[0])) * cos(deg2rad($theta))); 
        $distance = acos($distance); 
        $distance = rad2deg($distance); 
        $distance = $distance * 60 * 1.1515;

        return round($distance, 2);
    }

    $start = getLatLong('Guildford');
    $finish = getLatLong('BH15 2BT'); 
    $distance = Haversine($start, $finish);

    print('<p>The distance between ['.$start[0].', '.$start[1].'] and ['.$finish[0].', '.$finish[1].'] is '.$distance.' miles ('.($distance * 1.609344).' km).</p>');
?>

由于

2 个答案:

答案 0 :(得分:1)

看看这里:

选择边界圆内的点 http://www.movable-type.co.uk/scripts/latlong-db.html

答案 1 :(得分:0)

如果积分位于数据库中,您可以查看提供两种备选方案的this out(pdf链接)。对于一个简单的替代方案,演示文稿建议从远处有一个边界框。任何不在框内的点都会被过滤掉,留下较少的点来进行Haversine。如下所示:

$address=[1.352083,103.81983600000001];

$distancePerDegree= 111.045; //km. 63 for miles
$withinDistance=1;

$latRange=[
    $address[0]-$withinDistance/$distancePerDegree,
    $address[0]+$withinDistance/$distancePerDegree
];

$lonRange=[
    $address[1]-$withinDistance/abs(cos(deg2rad($address[0]))*$distancePerDegree),
    $address[1]+$withinDistance/abs(cos(deg2rad($address[0]))*$distancePerDegree)
];

//gets rough points
$points=DB::fetchAll( //lets say this class queries the database.
 "SELECT lat,lon FROM points WHERE
  lat between ? and ? AND
  lon between ? and ?",
  [$latRange[0],$latRange[1],$lonRange[0],$lonRange[1]]
);

//filters using harversine
$points=array_filter($points,function($p){ 
    return Haversine($address,[$p->lat,$p->lon])<=$withinDistance;
});

这可能很清楚,但应该是一个好的开始。