不败君

前端萌新&初级后端攻城狮

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

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

2020-02-15 12:54:40

围观(4546)

在开发某些项目会遇到这样的需求:

一.提供两个经纬度计算出两个经纬度的距离.

二.提供当前位置的经纬度从数据库中取出一定范围内的数据


先说一下第一个需求, 在美团或者饿了么点外卖就经常见到, 比如点餐列表显示自己与店家相隔距离.

现实方法:

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)

也就是可以得到这两个坐标(经纬度)相距的直线距离,单位是"米".


接下来就是第二个需求, 第二个需求有个前提, 就是存放在数据库的记录中, 需要含有经纬度字段 lat 和 lng.

比如点外卖的 APP, 商家表需要有 lat 和 lng 字段.

然后先是计算出当前位置的矩形范围

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

代码中的 distance 变量定义的是获取范围, 单位为公里.

比如上方代码 默认范围为 两公里, 则根据当前经纬度计算出两公里范围内的矩形坐标.

得到的结果:

{
    "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"
    }
}

拿到了这个矩形范围的坐标, 就可以查询数据库取出该范围内的数据记录了.

比如 Laravel / TP 在模型中可以这样写一个方法并传递上面获取到的数组:

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

这样就可以从数据库中取出, 在该经纬度范围内的数据记录.

本文地址 : bubaijun.com/page.php?id=165

版权声明 : 未经允许禁止转载!

上一篇文章: Laravel开发微信小程序支付

下一篇文章: Laravel多表查询优化

评论:我要评论
发布评论:
Copyright © 不败君 粤ICP备18102917号-1

不败君

首 页 作 品 微 语