dongliao6777 2015-07-07 00:13
浏览 57
已采纳

根据纬度和经度获取半径范围内的拉链码

I am trying to get zipcodes within a radius of 160km of the provided latitude/longitude coordinates. I already have a database of zipcodes, latitudes & longitudes, my problem is calculate the radius.

I have been looking at examples of how to do this, and this is what I came up with. But evidently something is wrong, because I'm getting distances that are ~9000km away according to the $dist variable.

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);
        }
    }
}

That code was mostly based on this answer on a related question: https://stackoverflow.com/a/18465217

But, obviously something didn't translate right, or I misunderstood something. Any help would be vastly appreciated!

  • 写回答

1条回答 默认 最新

  • dongya8378 2015-07-08 16:32
    关注

    Here is the code that I ended up using that works. A couple things changed, but the biggest difference is the formula. As you can see they're significantly different. I'm not very good at math, so I don't really know what the differences are, but I do know this one works.

    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;
            }
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 电脑出问题了,说是usbmom注册表没
  • ¥20 需要步骤截图(标签-服务器|关键词-map)
  • ¥50 gki vendor hook
  • ¥15 灰狼算法和蚁群算法如何结合
  • ¥15 这是一个利用ESP32自带按键和LED控制的录像代码,编译过程出现问题,请解决并且指出错误,指导如何处理 ,协助完成代码并上传代码
  • ¥20 stm32f103,hal库 hal_usart_receive函数接收不到数据。
  • ¥20 求结果和代码,sas利用OPTEX程序和D-efficiency生成正交集
  • ¥50 adb连接不到手机是怎么回事?
  • ¥20 抓取数据时发生错误: get_mooncake_data() missing 1 required positional argument: 'driver'的问题,怎么改出正确的爬虫代码?
  • ¥15 vs2022无法联网