【问题标题】:Get zipcodes within radius based on latitude and longitude根据经纬度获取半径范围内的邮政编码
【发布时间】:2015-07-07 00:13:13
【问题描述】:

我正在尝试获取所提供的纬度/经度坐标半径 160 公里内的邮政编码。我已经有一个邮政编码、纬度和经度的数据库,我的问题是计算半径。

我一直在寻找如何做到这一点的示例,这就是我想出的。但显然有些地方出了问题,因为根据 $dist 变量,我得到的距离约为 9000 公里。

public function getClose($latitude, $longitude) {
    $latitudes  = [floor($latitude)-2, ceil($latitude)+2];
    $locations  = Zipcode::whereBetween('latitude', $latitudes)->get();

    foreach ($locations as $location) {
        $venueLat = $location->latitude;
        $venueLng = $location->longititude;

        $latDistance = deg2rad($latitude - $venueLat);
        $lngDistance = deg2rad($longitude - $venueLng);
        $a = (sin($latDistance / 2) * sin($latDistance / 2)) + (cos(deg2rad($latitude))) * (cos(deg2rad($venueLat))) * (sin($lngDistance / 2)) * (sin($lngDistance / 2));
        $c = 2 * atan2(sqrt($a), sqrt(1 - $a));

        // Distance between 2 points in km. 6371 = Earths radius
        $dist = 6371 * $c;
        var_dump($dist); // This is the line saying it's about 9000km away

        if ($dist < 160){
            var_dump($location->zip);
        }
    }
}

该代码主要基于一个相关问题的答案:https://stackoverflow.com/a/18465217

但是,显然有些东西翻译不正确,或者我误解了某些东西。任何帮助将不胜感激!

【问题讨论】:

  • 您应该通过挑选出出现此问题的一对输入位置和场地位置来创建SSCCE。 If performance is an issue, you might want to filter using suitably chosen ranges for lat and long, so you have to do the trigonometry for only a few points.或者您完全省略三角函数,而改用this approximation,计算equirectangular projection 中的距离并将它们的平方长度与160² 进行比较。
  • 实际上并没有 1 个位置对是错误的,它们都已关闭。我将发布我最终使用的代码。
  • 好吧,如果所有对都关闭,那么任何一个都可以。顺便问一下,你读过Wikipedia吗?无论如何,发布可行的解决方案听起来是个好主意。

标签: php laravel math location


【解决方案1】:

这是我最终使用的代码。有几件事发生了变化,但最大的不同是公式。正如你所看到的,它们有很大的不同。我数学不是很好,所以我真的不知道有什么区别,但我知道这个有用。

public function getClose($latitude, $longitude) {
    $latitudes  = [floor($latitude)-2, ceil($latitude)+2];
    $longitudes = [floor($longitude)-1, ceil($longitude)+1];
    $locations  = Zipcode::whereBetween('latitude', $latitudes)->whereBetween('longitude', $longitudes)->get();
    $zips       = [];

    foreach ($locations as $location) {
        $theta = $longitude - $location->longitude;
        $dist = sin(deg2rad($latitude)) * sin(deg2rad($location->latitude)) +  cos(deg2rad($latitude)) * cos(deg2rad($location->latitude)) * cos(deg2rad($theta));
        $dist = acos($dist);
        $dist = rad2deg($dist);
        $miles = $dist * 60 * 1.1515;

        if ($miles <= 100){
            $zips[] = $location->zip;
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-17
    • 1970-01-01
    相关资源
    最近更新 更多