Вопрос-Ответ

Haversine formula in Python (bearing and distance between two GPS points)

Формула Haversine на Python (азимут и расстояние между двумя точками GPS)

Проблема

Я хотел бы знать, как получить расстояние и азимут между двумя точками 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

Вот мой новый код:

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 "--------------------"
Переведено автоматически
Ответ 1

Вот версия для Python:

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

def haversine(lon1, lat1, lon2, lat2):
"""
Calculate the great circle distance in kilometers 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. Determines return value units.
return c * r
Ответ 2

Большинство этих ответов "округляют" радиус земли. Если вы проверите их с помощью других калькуляторов расстояний (таких как 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))
Ответ 3

Также существует векторизованная реализация, которая позволяет использовать 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))
Ответ 4

Вы можете попробовать пакет haversine:

Пример кода:

from haversine import haversine

haversine((45.7597, 4.8422), (48.8567, 2.3508), unit='mi')

Вывод:

243.71209416020253
python