tp5.1根据经纬度测距并排序,获取附近多少公里内的数据
$order = ['distance' => 'asc']; // 按距离排序
$this->lat = '24.88513100'; // 用户经度
$this->lon = '102.82413200';//用户纬度
$workerAll = $this->user
->field("id,name,headimg,lat,lon,order_accept_num,telephone,topworktype_id,busy_status,(6378.138 * 2 * asin(sqrt(pow(sin((lat * pi() / 180 - " . $this->lat . " * pi() / 180) / 2),2) + cos(lat * pi() / 180) * cos(" . $this->lat . " * pi() / 180) * pow(sin((lon * pi() / 180 - " . $this->lon . " * pi() / 180) / 2),2))) * 1000) as distance")
->where($where)
->order($order)
->page($page, $pageSize)->select();
接着就得到了,这里显示的米,单位根据自己需要来转换
{
"id": 212,
"headimg": "",
"orderAcceptNum": 1,
"worktypeId": 493,
"worktypeText": "综合工",
"busyStatus": 0,
"lon": "102.82409200",
"lat": "24.88512400",
"distance": "4.11m"
},
{
"id": 2,
"headimg": "",
"orderAcceptNum": 0,
"worktypeId": 1,
"worktypeText": "木工",
"busyStatus": 0,
"lon": "0.00000000",
"lat": "0.00000000",
"distance": "11311.84km"
}
单位转换
// 当距离小于1km,单位显示米
$postData["distance"] = round($worker->distance / 1000, 2) < 1 ? round($worker->distance, 2) . 'm' : round($worker->distance / 1000, 2) . 'km';
根据当前坐标查询5公里以内的信息,加入having
having = 'distance < 5000'
$workerAll = $this->user
->field("id,name,headimg,lat,lon,order_accept_num,telephone,topworktype_id,busy_status,(6378.138 * 2 * asin(sqrt(pow(sin((lat * pi() / 180 - " . $this->lat . " * pi() / 180) / 2),2) + cos(lat * pi() / 180) * cos(" . $this->lat . " * pi() / 180) * pow(sin((lon * pi() / 180 - " . $this->lon . " * pi() / 180) / 2),2))) * 1000) as distance")
->where($where)
->group('id')
->having($having)
->order($order)
->page($page, $pageSize)->select();当然分页可以使用paginate(20)的方式
根据经纬度计算两点之间的距离
$lat1 起始纬度
$lng1 起始经度
$lat2 终点纬度
$lng2 终点经度
# 计算两点之间距离
public function getDistance($lat1, $lng1, $lat2, $lng2)
{
$radLat1 = deg2rad(floatval($lat1));// deg2rad()函数将角度转换为弧度
$radLat2 = deg2rad(floatval($lat2));
$radLng1 = deg2rad(floatval($lng1));
$radLng2 = deg2rad(floatval($lng2));
$a = $radLat1 - $radLat2;
$b = $radLng1 - $radLng2;
$s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2))) * 6378.137;
if ($s * 1000 < 1000) {
return round($s * 1000, 2) . "m";
} else {
return round($s, 2) . "km";
}
}