Python中的Haversine公式(两个GPS点之间的轴承和距离)

avi*_*tex 108 python gps distance bearing haversine

问题

我想知道如何获得2个GPS点之间距离和方位.我研究了半胱氨酸配方.有人告诉我,我也可以使用相同的数据找到轴承.

编辑

一切都运转良好,但轴承还没有正常工作.轴承输出负值但应在0 - 360度之间.设定数据应该是水平方位,96.02166666666666 并且是:

Start point: 53.32055555555556 , -1.7297222222222221   
Bearing:  96.02166666666666  
Distance: 2 km  
Destination point: 53.31861111111111, -1.6997222222222223  
Final bearing: 96.04555555555555
Run Code Online (Sandbox Code Playgroud)

这是我的新代码:

from math import *

Aaltitude = 2000
Oppsite  = 20000

lat1 = 53.32055555555556
lat2 = 53.31861111111111
lon1 = -1.7297222222222221
lon2 = -1.6997222222222223

lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])

dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
c = 2 * atan2(sqrt(a), sqrt(1-a))
Base = 6371 * c


Bearing =atan2(cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(lon2-lon1), sin(lon2-lon1)*cos(lat2)) 

Bearing = degrees(Bearing)
print ""
print ""
print "--------------------"
print "Horizontal Distance:"
print Base
print "--------------------"
print "Bearing:"
print Bearing
print "--------------------"


Base2 = Base * 1000
distance = Base * 2 + Oppsite * 2 / 2
Caltitude = Oppsite - Aaltitude

a = Oppsite/Base
b = atan(a)
c = degrees(b)

distance = distance / 1000

print "The degree of vertical angle is:"
print c
print "--------------------"
print "The distance between the Balloon GPS and the Antenna GPS is:"
print distance
print "--------------------"
Run Code Online (Sandbox Code Playgroud)

Mic*_*unn 221

这是一个Python版本:

from math import radians, cos, sin, asin, sqrt

def haversine(lon1, lat1, lon2, lat2):
    """
    Calculate the great circle distance between two points 
    on the earth (specified in decimal degrees)
    """
    # convert decimal degrees to radians 
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])

    # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a)) 
    r = 6371 # Radius of earth in kilometers. Use 3956 for miles
    return c * r
Run Code Online (Sandbox Code Playgroud)

  • 可以使用math.radians()函数而不是乘以pi/180 - 相同的效果,但更多的自我记录. (9认同)
  • 你可以,但是如果你说'import math`那么你必须指定`math.pi`,`math.sin`等.使用`from math import*`你可以直接访问所有的模块内容.查看python教程中的"名称空间"(例如http://docs.python.org/tutorial/modules.html) (4认同)
  • 如果平均地球半径定义为6371 km,则相当于3959英里,而不是3956英里.有关计算这些值的各种方法,请参阅[全球平均半径](https://en.wikipedia.org/wiki/Earth_radius#Global_average_radii). (3认同)
  • 这是什么回事?方位还是距离? (3认同)
  • 你怎么用atan2(sqrt(a),sqrt(1-a))而不仅仅是asin(sqrt(a))?在这种情况下,atan2更准确吗? (2认同)
  • 应该是浮点除法以覆盖 dlat|dlon 是整数的罕见极端情况:a = sin(dlat/2.)**2 + cos(lat1) * cos(lat2) * sin(dlon/2.)**2 (2认同)

Cla*_*lay 7

这些答案大多数都是"四舍五入"地球的半径.如果您针对其他距离计算器(例如geopy)检查这些,则这些功能将关闭.

这很好用:

from math import radians, cos, sin, asin, sqrt

def haversine(lat1, lon1, lat2, lon2):

      R = 3959.87433 # this is in miles.  For Earth radius in kilometers use 6372.8 km

      dLat = radians(lat2 - lat1)
      dLon = radians(lon2 - lon1)
      lat1 = radians(lat1)
      lat2 = radians(lat2)

      a = sin(dLat/2)**2 + cos(lat1)*cos(lat2)*sin(dLon/2)**2
      c = 2*asin(sqrt(a))

      return R * c

# Usage
lon1 = -103.548851
lat1 = 32.0004311
lon2 = -103.6041946
lat2 = 33.374939

print(haversine(lat1, lon1, lat2, lon2))
Run Code Online (Sandbox Code Playgroud)

  • 这并没有解决两极 R. 6356.752 km 到赤道 6378.137 km 的变化 (5认同)
  • 该错误对您的应用程序真的很重要吗?https://cs.nyu.edu/visual/home/proj/tiger/gisfaq.html (3认同)
  • 这个比上面的例子准确得多! (2认同)

Ser*_*tin 7

还有一个向量化的实现,该实现允许使用4个numpy数组而不是标量值作为坐标:

def distance(s_lat, s_lng, e_lat, e_lng):

   # approximate radius of earth in km
   R = 6373.0

   s_lat = s_lat*np.pi/180.0                      
   s_lng = np.deg2rad(s_lng)     
   e_lat = np.deg2rad(e_lat)                       
   e_lng = np.deg2rad(e_lng)  

   d = np.sin((e_lat - s_lat)/2)**2 + np.cos(s_lat)*np.cos(e_lat) * np.sin((e_lng - s_lng)/2)**2

   return 2 * R * np.arcsin(np.sqrt(d))
Run Code Online (Sandbox Code Playgroud)


Vam*_*i G 6

您可以尝试以下操作:

from haversine import haversine
haversine((45.7597, 4.8422),(48.8567, 2.3508), unit='mi')
243.71209416020253
Run Code Online (Sandbox Code Playgroud)


小智 5

轴承计算不正确,您需要将输入交换为 atan2。

    bearing = atan2(sin(long2-long1)*cos(lat2), cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(long2-long1))
    bearing = degrees(bearing)
    bearing = (bearing + 360) % 360
Run Code Online (Sandbox Code Playgroud)

这将为您提供正确的方位。