经纬度求实际距离

计算距离时有3种地球模型可供选择.

  • 平面
  • 球体
  • 椭球体
import math

#勾股定理求取 误差最大
def CalcPythagorean(Lat_A,Lng_A,Lat_B,Lng_B):
    # lat 维度
    # lng 经度
    EARTH_RADIUS=6378137
    x1=Lat_A
    y1=Lng_A
    x2=Lat_B
    y2=Lng_B
    x_dist=math.radians(x1-x2)  #角度转成弧度
    y_dist=math.radians(y1-y2)  #角度转成弧度
    dist_sq=x_dist**2+y_dist**2
    dist_rad=math.sqrt(dist_sq)
    distance=dist_rad*EARTH_RADIUS
    return distance

#半正矢公式 误差在1km以内
def calcDistance(Lat_A,Lng_A,Lat_B,Lng_B):
    # lat 维度
    # lng 经度
    EARTH_RADIUS=6378137
    x1=Lat_A
    y1=Lng_A
    x2=Lat_B
    y2=Lng_B
    x_dist=math.radians(x1-x2)
    y_dist=math.radians(y1-y2)
    y1_rad=math.radians(y1)
    y2_rad=math.radians(y2)
    a=math.sin(y_dist/2)**2+(math.sin(x_dist/2)**2)*math.cos(y1_rad)*math.cos(y2_rad)
    c=2*math.asin(math.sqrt(a))
    distance=c*EARTH_RADIUS
    return distance

#Vincenty公式 精度最高 远远小于1km
def VincentyDistance(Lat_A,Lng_A,Lat_B,Lng_B):
    # lat 维度
    # lng 经度
    x1=Lat_A
    y1=Lng_A
    x2=Lat_B
    y2=Lng_B
    f=1/298.257222101
    a = 6378137  #半长轴
    b=abs((f*a)-a) #半短轴
    L=math.radians(x2-x1)
    U1=math.atan((1-f)*math.tan(math.radians(y1)))
    U2=math.atan((1-f)*math.tan(math.radians(y2)))
    sinU1=math.sin(U1)
    cosU1=math.cos(U1)
    sinU2=math.sin(U2)
    cosU2=math.cos(U2)
    lam=L
    for i in range(100):
        sinLam=math.sin(lam)
        cosLam=math.cos(lam)
        sinSigma=math.sqrt((cosU2*sinLam)**2+(cosU1*sinU2-sinU1*cosU2*cosLam)**2)
        if(sinSigma==0):
            distance=0
            break
        cosSigma=sinU1*sinU2+cosU1*cosU2*cosLam
        sigma=math.atan2(sinSigma,cosSigma)
        sinAlpha=cosU1*cosU2*sinLam/sinSigma
        cosSqAlpha=1-sinAlpha**2
        cos2SigmaM=cosSigma-2*sinU1*sinU2/cosSqAlpha
        if math.isnan(cos2SigmaM):
            cos2SigmaM=0 #赤道线
        C=f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha))
        LP=lam
        lam=L+(1-C)*f*sinAlpha*(sigma+C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)))
        if not abs(lam-LP)>1e-12:
            break
    uSq=cosSqAlpha*(a**2-b**2)/b**2
    A=1+uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)))
    B=uSq/1024*(256+uSq*(-128+uSq*(74-47*uSq)))
    delteSigma=B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)))
    s=b*A*(sigma-delteSigma)
    distance=s
    return distance
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值