PHP使用经纬度获取两个位置的距离以及范围查询

需求背景:能源运输物流系统中司机加油, 比如加油站列表显示自己与油站相隔距离;根据司机当前位置的经纬度从数据库中取出一定范围内的油站数据。

技术需求:A、提供两个经纬度计算出两个经纬度的距离;B、提供当前位置的经纬度从数据库中取出一定范围内的数据。

A实现方法

    /**
     * @param $start_lat
     * @param $start_end
     * @param $end_lat
     * @param $end_lng
     * @return float
     */
    function get_distance_by_coords($start_lat, $start_end, $end_lat, $end_lng)
    {
        // 将角度转为狐度 deg2rad() 函数将角度转换为弧度
        $rad_start_lat = deg2rad($start_lat);
        $rad_end_lat = deg2rad($end_lat);
        $rad_start_lng = deg2rad($start_end);
        $rad_end_lng = deg2rad($end_lng);
        $a_coords = $rad_start_lat - $rad_end_lat;
        $b_coords = $rad_start_lng - $rad_end_lng;
        $distance = 2 * asin(sqrt(pow(sin($a_coords / 2),2) + cos($rad_start_lat) * cos($rad_end_lat)
                * pow(sin($b_coords / 2),2))) * 6378.137 * 1000;
        return $distance;
    }

    //打印调试
    var_dump(get_distance_by_coords('23.11349200900413', '113.36568827514647',             '23.115386579166856', '113.3728980529785'));

打印结果:

float(767.69700011894)

 B实现方法

    /**
     * @param $lat
     * @param $lng
     * @param $distance
     * @return array[]
     */
    function get_coord_by_lat_lng($lat, $lng, $distance = 2)
    {
        // 定义地球的半径
        define('EARTH_RADIUS', 6371);
        $new_lng =  2 * asin(sin($distance / (2 * EARTH_RADIUS)) / cos(deg2rad($lat)));
        $new_lng = rad2deg($new_lng);

        $new_lat = $distance / EARTH_RADIUS;
        $new_lat = rad2deg($new_lat);

        return [
            'left-top' => ['lat' => $lat + $new_lat,'lng' => $lng-$new_lng],
            'right-top' => ['lat' => $lat + $new_lat, 'lng' => $lng + $new_lng],
            'left-bottom' => ['lat' => $lat - $new_lat, 'lng' => $lng - $new_lng],
            'right-bottom' => ['lat' => $lat - $new_lat, 'lng' => $lng + $new_lng]
        ];
    }
    //打印调试
     var_dump(get_coord_by_lat_lng('23.11349200900413', '113.36568827514647'));

打印结果:


{
    "left-top": {
        "lat": "23.131478441122503",
        "lng": "113.34613204664485"
    },
    "right-top": {
        "lat": "23.131478441122503",
        "lng": "113.38524450364808"
    },
    "left-bottom": {
        "lat": "23.095505576885756",
        "lng": "113.34613204664485"
    },
    "right-bottom": {
        "lat": "23.095505576885756",
        "lng": "113.38524450364808"
    }
}

然后根据这个坐标数据查询数据库取出该范围内的数据记录。

    /**
     * @param $coord
     * @return mixed
     */
    public function coordinate_range($coord)
    {
        return $this
            ->where('lat', '>', $coord['right-bottom']['lat'])
            ->where('lat', '<', $coord['left-top']['lat'])
            ->where('lng', '>', $coord['left-top']['lng'])
            ->where('lng', '<', $coord['right-bottom']['lng'])
            ->paginate();
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值