Haversine Formula in Python (Bearing and Distance between two GPS points)

匿名 (未验证) 提交于 2019-12-03 01:58:03

问题:

Problem

I would like to know how to get the distance and bearing between 2 GPS points. I have researched on the haversine formula. Someone told me that I could also find the bearing using the same data.

Edit

Everything is working fine but the bearing doesn't quite work right yet. The bearing outputs negative but should be between 0 - 360 degrees. The set data should make the horizontal bearing 96.02166666666666 and is:

Start point: 53.32055555555556 , -1.7297222222222221    Bearing:  96.02166666666666   Distance: 2 km   Destination point: 53.31861111111111, -1.6997222222222223   Final bearing: 96.04555555555555 

Here is my new code:

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:

Here's a Python version:

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 


回答2:

The bearing calculation is incorrect, you need to swap the inputs to 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 

This will give you the correct bearing.



回答3:

You can solve the negative bearing problem by adding 360°. Unfortunately, this might result in bearings larger than 360° for positive bearings. This is a good candidate for the modulo operator, so all in all you should add the line

Bearing = (Bearing + 360) % 360 

at the end of your method.



回答4:

You can try the following:

from haversine import haversine haversine((45.7597, 4.8422),(48.8567, 2.3508),miles = True) 243.71209416020253 


回答5:

The Y in atan2 is, by default, the first parameter. Here is the documentation. You will need to switch your inputs to get the correct bearing angle.

bearing = atan2(sin(lon2-lon1)*cos(lat2), cos(lat1)*sin(lat2)in(lat1)*cos(lat2)*cos(lon2-lon1)) bearing = degrees(bearing) bearing = (bearing + 360) % 360 


回答6:

Refer to this link :https://gis.stackexchange.com/questions/84885/whats-the-difference-between-vincenty-and-great-circle-distance-calculations

this actually gives two ways of getting distance. They are Haversine and Vincentys. From my research I came to know that Vincentys is relatively accurate. Also use import statement to make the implementation.



回答7:

Most of these answers are "rounding" the radius of the earth. If you check these against other distance calculators (such as geopy), these functions will be off.

This works well:

lon1 = -103.548851 lat1 = 32.0004311 lon2 = -103.6041946 lat2 = 33.374939   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  print(haversine(lat1, lon1, lat2, lon2)) 


回答8:

Here are two functions to calculate distance and bearing, which are based on the code in previous messages and https://gist.github.com/jeromer/2005586 (added tuple type for geographical points in lat, lon format for both functions for clarity). I tested both functions and they seem to work right.

#coding:UTF-8 from math import radians, cos, sin, asin, sqrt, atan2, degrees  def haversine(pointA, pointB):      if (type(pointA) != tuple) or (type(pointB) != tuple):         raise TypeError("Only tuples are supported as arguments")      lat1 = pointA[0]     lon1 = pointA[1]      lat2 = pointB[0]     lon2 = pointB[1]      # convert decimal degrees to radians      lat1, lon1, lat2, lon2 = map(radians, [lat1, lon1, lat2, lon2])       # 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   def initial_bearing(pointA, pointB):      if (type(pointA) != tuple) or (type(pointB) != tuple):         raise TypeError("Only tuples are supported as arguments")      lat1 = radians(pointA[0])     lat2 = radians(pointB[0])      diffLong = radians(pointB[1] - pointA[1])      x = sin(diffLong) * cos(lat2)     y = cos(lat1) * sin(lat2) - (sin(lat1)             * cos(lat2) * cos(diffLong))      initial_bearing = atan2(x, y)      # Now we have the initial bearing but math.atan2 return values     # from -180° to + 180° which is not what we want for a compass bearing     # The solution is to normalize the initial bearing as shown below     initial_bearing = degrees(initial_bearing)     compass_bearing = (initial_bearing + 360) % 360      return compass_bearing  pA = (46.2038,6.1530) pB = (46.449, 30.690)  print haversine(pA, pB)  print initial_bearing(pA, pB) 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!