문제
2 개의 GPS 지점 사이 의 거리와 방위 를 확인하는 방법을 알고 싶습니다 . 나는 haversine 공식에 대해 연구했습니다. 누군가 저에게 동일한 데이터를 사용하여 베어링을 찾을 수 있다고 말했습니다.
편집하다
모든 것이 잘 작동하지만 베어링은 아직 제대로 작동하지 않습니다. 베어링 출력은 음수이지만 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 "--------------------"
답변
다음은 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
답변
이러한 답변의 대부분은 지구 반경을 “반올림”합니다. 다른 거리 계산기 (예 : 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))
답변
좌표에 스칼라 값 대신 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))
답변
베어링 계산이 잘못되었습니다. 입력을 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
이것은 당신에게 정확한 방위를 줄 것입니다.
답변
다음을 시도 할 수 있습니다.
from haversine import haversine
haversine((45.7597, 4.8422),(48.8567, 2.3508), unit='mi')
243.71209416020253
답변
@Michael Dunn이 제공 한 Haversine 공식의 수많은 벡터화 된 구현은 큰 벡터에 비해 10 ~ 50 배 향상되었습니다.
from numpy import radians, cos, sin, arcsin, 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 = np.radians(lon1.values)
lat1 = np.radians(lat1.values)
lon2 = np.radians(lon2.values)
lat2 = np.radians(lat2.values)
#Implementing Haversine Formula:
dlon = np.subtract(lon2, lon1)
dlat = np.subtract(lat2, lat1)
a = np.add(np.power(np.sin(np.divide(dlat, 2)), 2),
np.multiply(np.cos(lat1),
np.multiply(np.cos(lat2),
np.power(np.sin(np.divide(dlon, 2)), 2))))
c = np.multiply(2, np.arcsin(np.sqrt(a)))
r = 6371
return c*r
답변
360 °를 추가하여 부정적인 베어링 문제를 해결할 수 있습니다. 불행히도 이것은 포지티브 베어링의 경우 360 °보다 큰 베어링이 될 수 있습니다. 이것은 모듈로 연산자에 대한 좋은 후보이므로 모두 다음 줄을 추가해야합니다.
Bearing = (Bearing + 360) % 360
당신의 방법의 끝에.