项目中用到的,计算用户到门店列表中所有门店对应的距离。其中难点两个:
①如何计算距离
②如何根据距离排序分页
坐标点计算距离
任意两点对应的经纬度A(lat0,long0),B(lat1,long1)
则C(lat1,long0),D(lat0,long1)。通过A、B、C、D四个点可以确定一个四边形平面。同意维度相互平行,可知连接ACBD四点构成了一个等腰梯形。
设地球半径R,
AO'=Rcos(lat0)
△AO'D中∠AO'D=long1-long0=∆long,
AD=2AO'sin(∆long/2)=2Rcos(lat0)sin(∆long/2)
同理:CO''=Rcos(lat1)
CB=2CO''sin(∆long)=2Rcos(lat1)sin(∆long/2)
∠AOC=lat0-lat1=∆lat
可知:AC=BD=2Rsin(∆lat/2)
现在求AB的长度,得知AB的长度后,可以求得对应的圆心角,进而求得
求得AB的长度,就可以求得以AB为弦的同心圆的圆心角,从而求得
sin(∠AOB/2)=AB/2:AO=AB:2R
在这里要反三角给出的是弧度值
距离公式
PHP给出的计算方法
/**入参坐标点坐标,为角度值,计算要转化为弧度制
* 计算两点地理坐标之间的距离
* @param Decimal $long0 起点经度
* @param Decimal $lat0 起点纬度
* @param Decimal $long1 终点经度
* @param Decimal $lat1 终点纬度
* @param Int $unit 单位 1:米 2:公里
* @param Int $decimal 精度 保留小数位数
* @return distance 返回距离
**/
public function getdistance(lat0,long0,lat1,long1,$unit=1,$decimal=2){
$R = 6370.996; // 地球半径系数(米)
$PI = 3.1415926;
//经纬度角度转弧度
rad_lat0 = $lat0 * $PI / 180.0;
rad_long0 = $long0 * $PI / 180.0;
rad_lat1 = $lat1 * $PI / 180.0;
rad_long1 = $ong1 * $PI / 180.0;
//纬度差的一般
$rad_lat_minus_half = (rad_lat0 - rad_lat1)/2
//经度差的一般
$rad_long_minus_half = (rad_lat0 - rad_lat1)/2
$distance = 2*$R.arcsin(sqrt(pow(sin($rad_lat_minus_half),2)+cos($rad_lat0) * cos($rad_lat1) * pow(sin($rad_long_minus_half),2)));
if($unit==2){
$distance = $distance / 1000;//转化为千米
}
return round($distance, $decimal);//函数对浮点数进行四舍五入。decimal决定小数点后的位数
}