PHP中经纬度坐标距离计算及查询示例代码

近期有些网友想要了解PHP中经纬度坐标距离计算及查询示例代码的相关情况,小编通过整理给您分析,同时介绍一下有关信息。

在地理信息系统(GIS)和位置服务中,计算两点之间的距离是一个常见的需求。PHP作为一种广泛使用的服务器端脚本语言,提供了多种方法来计算经纬度坐标之间的距离。本文将详细介绍如何在PHP中计算两个经纬度坐标之间的距离,并提供示例代码,帮助开发者在实际项目中高效地实现这一功能。

1. 前言

想要测试本文提供的几个功能函数,可以使用下面这个数据表结构及其数据

CREATETABLE`user`(
`id`int(10)unsignedNOTNULLAUTO_INCREMENTCOMMENT'用户id',
`name`varchar(60)DEFAULTNULLCOMMENT'昵称',
`longitude`varchar(64)DEFAULTNULLCOMMENT'经度',
`latitude`varchar(64)DEFAULTNULLCOMMENT'纬度',
`remark`varchar(50)DEFAULTNULLCOMMENT'备注',
`distance`varchar(20)DEFAULTNULLCOMMENT'距离',
PRIMARYKEY(`id`)
)ENGINE=InnoDBCOMMENT='用户表';
INSERTINTO`user`(`name`,`longitude`,`latitude`,`remark`,`distance`)VALUES('中海九号公馆','113.899529','22.60063','深圳市宝安区中海九号公馆','3.66km');
INSERTINTO`user`(`name`,`longitude`,`latitude`,`remark`,`distance`)VALUES('平峦山公园','113.876462','22.608322','深圳市宝安区平峦山公园','2.88km');
INSERTINTO`user`(`name`,`longitude`,`latitude`,`remark`,`distance`)VALUES('铁仔山公园','113.86359','22.592355','深圳市宝安区铁仔山公园','1.16km');
INSERTINTO`user`(`name`,`longitude`,`latitude`,`remark`,`distance`)VALUES('宝安公园','113.902671','22.58621','深圳市宝安区宝安公园','3.45km');

本文内容测试各个功能函数时,使用的当前位置坐标均为:

//深圳市宝安区西乡街道九方广场
$longitude='113.869205';//经度
$latitude='22.583286';//纬度

2. 计算经纬度坐标间的距离

计算经纬度坐标间的距离功能函数 (前四个参数为两组经纬度坐标)

/**
*计算经纬度坐标间的距离
*@param$lng1经度
*@param$lat1纬度
*@param$lng2经度
*@param$lat2纬度
*@param$lang语言
*/
functionget_distance($lng1,$lat1,$lng2,$lat2,$lang='en')
{
//地球的近似半径(单位:米)
$earthRadius=6367000;
//将这些度数转换为弧度以使用公式
$lat1=($lat1*pi())/180;
$lng1=($lng1*pi())/180;
$lat2=($lat2*pi())/180;
$lng2=($lng2*pi())/180;
//使用Haversine公示计算距离
//http://en.wikipedia.org/wiki/Haversine_formula
$calcLongitude=$lng2-$lng1;
$calcLatitude=$lat2-$lat1;
$stepOne=pow(sin($calcLatitude/2),2)+cos($lat1)*cos($lat2)*pow(sin($calcLongitude/2),2);
$stepTwo=2*asin(min(1,sqrt($stepOne)));
//两个经纬度坐标的距离(单位:米)
$calculatedDistance=round($earthRadius*$stepTwo);
//距离单位
$language=[
'en'=>['m'=>'m','km'=>'km'],
'cn'=>['m'=>'米','km'=>'公里'],
];
if(!isset($language[$lang]))thrownew\Exception('不支持的语言:'.$lang);
foreach($language[$lang]as$key=>$value)$$key=$value;
//两个坐标间的距离,单位:米
$distance=round($calculatedDistance);
//距离单位转换:超出1000m时单位转为km
if($distance<1000){
$distance.=$m;
}else{
$distance=floatval(number_format($distance/1000,2)).$km;
}
return$distance;//返回单位转换后的距离
}

使用示例:

我在 九方广场,手机上的高德地图导航至 中海九号公馆 显示的距离为 3.6公里,计算结果还是很准确的

//深圳市宝安区西乡街道九方广场:113.869205,22.583286
//深圳市宝安区西乡街道中海九号公馆:113.899529,22.60063
$distance=get_distance(113.869205,22.583286,113.899529,22.60063);
echo$distance;//3.66km

3. 根据经纬度坐标距离排序

项目中经常有距离显示数据的场景,根据距离排序,越近越靠前显示;比如: 店铺地址、房源信息等。代码示例:

//当前坐标
$longitude='113.869205';
$latitude='22.583286';
//数据库中经纬度字段分别为:longitude、latitude
$field='*,(2*6378.137*ASIN(SQRT(POW(SIN(PI()*('.$longitude.'-longitude)/360),2)+COS(PI()*'.$latitude.'/180)*COS(latitude*PI()/180)*POW(SIN(PI()*('.$latitude.'-latitude)/360),2))))ASjuli';
//根据距离升序查询(越近越靠前)
$order='juliasc,iddesc';
//查询数据
Db::name('user')->field($field)->order($order)->select();

4. 经纬度范围查询

经纬度范围计算 功能函数

/**
*经纬度范围计算
*@param$longitude经度
*@param$latitude纬度
*@param$radius半径(米)
*@returnarray
*/
functionget_around($longitude,$latitude,$radius)
{
$PI=3.14159265;
$degree=(24901*1609)/360.0;
$dpmLat=1/$degree;
$radiusLat=$dpmLat*$radius;
$minLat=$latitude-$radiusLat;
$maxLat=$latitude+$radiusLat;
$mpdLng=$degree*cos($latitude*($PI/180));
$dpmLng=1/$mpdLng;
$radiusLng=$dpmLng*$radius;
$minLng=$longitude-$radiusLng;
$maxLng=$longitude+$radiusLng;
returncompact('minLat','maxLat','minLng','maxLng');
}

使用示例

查询 3 公里内的数据。首先,根据当前位置获取 3 公里内的经纬度范围,然后带上查询条件查询数据库即可

$longitude=113.869205;//经度
$latitude=22.583286;//纬度
$radius=3000;//单位:米
//经纬度范围
$around=get_around($longitude,$latitude,$radius);
//构造查询条件
//数据库经纬度字段分别为:longitude,latitude
$where=[
['longitude','>=',$around['minLng']],
['longitude','<=',$around['maxLng']],
['latitude','>=',$around['minLat']],
['latitude','<=',$around['maxLat']],
];
//按照经纬度范围查询数据
//建议使用where的闭包查询(TP6.0)
//因为闭包可以生成以下SQL,标明这几个查询条件是一个整体,便于后期维护
//SQL语句示例:SELECT*FROM`user`WHERE(经纬度查询条件)and其他条件
$data=Db::name('user')
->where(function($query)use($where){
$query->where($where);
})
->select();

总结

通过对PHP中经纬度坐标距离计算的详细解析,我们了解了多种计算方法及其应用场景。Haversine公式是最常用的方法,能够精确计算地球表面上两点之间的大圆距离。本文提供的示例代码展示了如何使用Haversine公式在PHP中计算两点之间的距离,并结合数据库查询实现了实际应用中的距离筛选功能。通过本文的学习,开发者可以掌握在PHP中处理经纬度坐标距离计算的方法,提高地理信息系统的开发效率和准确性。希望本文的内容能为读者在实际项目中提供有价值的参考和帮助。

发布于 2025-01-14 03:28:41
分享
海报
120
上一篇:PHP使用GD库实现webp转jpg的示例代码及方法详解 下一篇:Oracle数据库中保留小数点后两位的方法详解
目录

    忘记密码?

    图形验证码