任意两个GPS坐标测距计算公式推导

项目中用到的,计算用户到门店列表中所有门店对应的距离。其中难点两个:
①如何计算距离
②如何根据距离排序分页
坐标点计算距离
任意两点对应的经纬度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,

\frac{1}{2}AD:AO'=sin(\Delta long/2)
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的长度后,可以求得对应的圆心角,进而求得\widehat{AB}


CH=\frac{1}{2}(CB-AD)
AH^{2}+BH^{2}=AB^{2}
AC^{2}-CH^{2}+(CB-CH)^{2}=AB^{2}
AC^{2}-CH^{2}+CB^{2}-2CB*CH+CH^{2}=AB^{2}
AC^{2}+CB^{2}-2CB*CH=AB^{2}
AC^{2}+CB^{2}-2CB*\frac{1}{2}(CB-AD)=AB^{2}
AC^{2}+CB^{2}-CB(CB-AD)=AB^{2}
AC^{2}+CB^{2}-CB^{2}+CB*AD=AB^{2}
AC^{2}+CB*AD=AB^{2}
(2Rsin(\Delta lat/2))2+2Rcos(lat1)sin(\Delta long/2)*2Rcos(lat0)sin(\Delta long/2)=AB^{2}


4R^{2}sin^{2}(\Delta lat/2)+4R^{2}sin^{2}(\Delta long/2)cos(lat0)cos(lat1)=AB^{2}
AB=2R\sqrt{sin^{2}(\Delta lat/2)+sin^{2}(\Delta long/2)cos(lat0)cos(lat1)}

求得AB的长度,就可以求得以AB为弦的同心圆的圆心角,从而求得\widehat{AB}

sin(∠AOB/2)=AB/2:AO=AB​:2R
在这里要反三角给出的是弧度值
rad(\widehat{AOB} )=2arcsin(\frac{AB}{2R})

AB=Rrad(\widehat{AOB})=2Rarcsin(\frac{AB}{2R}) =2Rarcsin(\sqrt{sin^{2}(\Delta lat/2)+sin^{2}(\Delta long/2)cos(lat0)cos(lat1)})
距离公式

AB=2Rarcsin(\sqrt{sin^{2}(\Delta lat/2)+sin^{2}(\Delta long/2)cos(lat0)cos(lat1)})

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决定小数点后的位数
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值