Tính khoảng cách trong Python

Hỏi:

Tôi muốn biết làm thế nào để có được khoảng cách và mang giữa 2 điểm GPS . Tôi đã nghiên cứu về công thức hasrsine. Có người nói với tôi rằng tôi cũng có thể tìm thấy ổ trục bằng cách sử dụng cùng một dữ liệu.

Biên tập

Mọi thứ đều hoạt động tốt nhưng ổ trục vẫn chưa hoạt động bình thường. Vòng bi đầu ra âm nhưng phải nằm trong khoảng 0 - 360 độ. Dữ liệu tập hợp nên làm cho ổ trục ngang 96.02166666666666 và là:

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

Đây là mã mới của tôi:

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 "--------------------"

Xem thêm:

Trả lời:

Đây là phiên bản 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

Trả lời:

Hầu hết các câu trả lời này là "làm tròn" bán kính trái đất. Nếu bạn kiểm tra chúng với các máy tính khoảng cách khác (chẳng hạn như geopy), các chức năng này sẽ bị tắt.

Điều này hoạt động tốt:

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))

Trả lời:

Ngoài ra còn có một triển khai vectơ hóa , cho phép sử dụng 4 mảng numpy thay vì các giá trị vô hướng cho tọa độ:

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))

Trả lời:

Tính toán ổ trục không chính xác, bạn cần hoán đổi các đầu vào thành 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

Điều này sẽ cung cấp cho bạn vòng bi chính xác.

Trả lời:

Bạn có thể thử những cách sau:

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

Trả lời:

Đây là một triển khai vectơ phức tạp của Công thức Haversine do @Michael Dunn đưa ra, cải thiện 10-50 lần so với các vectơ lớn.

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

Trả lời:

Bạn có thể giải quyết vấn đề ổ trục âm bằng cách thêm 360 °. Thật không may, điều này có thể dẫn đến vòng bi lớn hơn 360 ° đối với vòng bi dương. Đây là một ứng cử viên sáng giá cho toán tử modulo, vì vậy, nhìn chung, bạn nên thêm dòng

Bearing = (Bearing + 360) % 360

ở cuối phương pháp của bạn.

Trả lời:

Theo mặc định, Y trong atan2 là tham số đầu tiên. Đây là tài liệu . Bạn sẽ cần chuyển đổi các đầu vào để có được góc chịu lực chính xác.

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

Trả lời:

Trả lời:

Đây là hai hàm để tính toán khoảng cách và mang, dựa trên mã trong các tin nhắn trước và https://gist.github.com/jeromer/2005586 (đã thêm kiểu tuple cho các điểm địa lý ở định dạng vĩ độ, vĩ độ cho cả hai hàm để rõ ràng ). Tôi đã thử nghiệm cả hai chức năng và chúng dường như hoạt động bình thường.

#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)