ruby 如何在不使用 Google Maps API 的情况下计算两个 GPS 坐标之间的距离?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12966638/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to calculate the distance between two GPS coordinates without using Google Maps API?
提问by Chim Kan
I'm wondering if there's a way to calculate the distance of two GPS coordinates without relying on Google Maps API.
我想知道是否有一种方法可以在不依赖 Google Maps API 的情况下计算两个 GPS 坐标的距离。
My app may receive the coordinates in float or I would have to do reverse GEO on the addresses.
我的应用程序可能会接收浮点坐标,或者我必须对地址进行反向 GEO。
回答by Oto Brglez
Distance between two coordinates on earth is usually calculated using Haversine formula. This formula takes into consideration earth shape and radius. This is the code I use to calculate distance in meters.
地球上两个坐标之间的距离通常使用Haversine公式计算。这个公式考虑了地球的形状和半径。这是我用来计算以米为单位的距离的代码。
def distance loc1, loc2
rad_per_deg = Math::PI/180 # PI / 180
rkm = 6371 # Earth radius in kilometers
rm = rkm * 1000 # Radius in meters
dlat_rad = (loc2[0]-loc1[0]) * rad_per_deg # Delta, converted to rad
dlon_rad = (loc2[1]-loc1[1]) * rad_per_deg
lat1_rad, lon1_rad = loc1.map {|i| i * rad_per_deg }
lat2_rad, lon2_rad = loc2.map {|i| i * rad_per_deg }
a = Math.sin(dlat_rad/2)**2 + Math.cos(lat1_rad) * Math.cos(lat2_rad) * Math.sin(dlon_rad/2)**2
c = 2 * Math::atan2(Math::sqrt(a), Math::sqrt(1-a))
rm * c # Delta in meters
end
puts distance [46.3625, 15.114444],[46.055556, 14.508333]
# => 57794.35510874037
回答by Ira Herman
You can use the geokit ruby gem. It does these calculations internally, but also supports resolving addresses via google and other services if you need it to.
您可以使用geokit ruby gem。它在内部进行这些计算,但如果需要,也支持通过谷歌和其他服务解析地址。
require 'geokit'
current_location = Geokit::LatLng.new(37.79363,-122.396116)
destination = "37.786217,-122.41619"
current_location.distance_to(destination)
# Returns distance in miles: 1.211200074136264
You can also find out the bearing_to(direction expressed as a float in degrees between 0-360) and midpoint_to(returns an object you can run .latitude and .longitude methods on).
您还可以找出bearing_to(direction 表示为 0-360 度之间的浮点数) 和midpoint_to(返回一个可以运行 .latitude 和 .longitude 方法的对象)。
回答by Sebastian Kim
Just a little shorter & separated parameter version of @Lunivore's answer
只是@Lunivore 答案的更短和分离的参数版本
RAD_PER_DEG = Math::PI / 180
RM = 6371000 # Earth radius in meters
def distance_between(lat1, lon1, lat2, lon2)
lat1_rad, lat2_rad = lat1 * RAD_PER_DEG, lat2 * RAD_PER_DEG
lon1_rad, lon2_rad = lon1 * RAD_PER_DEG, lon2 * RAD_PER_DEG
a = Math.sin((lat2_rad - lat1_rad) / 2) ** 2 + Math.cos(lat1_rad) * Math.cos(lat2_rad) * Math.sin((lon2_rad - lon1_rad) / 2) ** 2
c = 2 * Math::atan2(Math::sqrt(a), Math::sqrt(1 - a))
RM * c # Delta in meters
end
回答by dantswain
I'm not sure of any prepackaged solution, but it seems a fairly straightforward calculation: http://www.movable-type.co.uk/scripts/latlong.html
我不确定任何预先打包的解决方案,但它似乎是一个相当简单的计算:http: //www.movable-type.co.uk/scripts/latlong.html
回答by caulfield
回答by bizz84
Converted the accepted answer to Swift 3.1 (works on Xcode 8.3), in case anyone needs it:
将接受的答案转换为 Swift 3.1(适用于 Xcode 8.3),以防有人需要它:
public static func calculateDistanceMeters(departure: CLLocationCoordinate2D, arrival: CLLocationCoordinate2D) -> Double {
let rad_per_deg = Double.pi / 180.0 // PI / 180
let rkm = 6371.0 // Earth radius in kilometers
let rm = rkm * 1000.0 // Radius in meters
let dlat_rad = (arrival.latitude - departure.latitude) * rad_per_deg // Delta, converted to rad
let dlon_rad = (arrival.longitude - departure.longitude) * rad_per_deg
let lat1_rad = departure.latitude * rad_per_deg
let lat2_rad = arrival.latitude * rad_per_deg
let sinDlat = sin(dlat_rad/2)
let sinDlon = sin(dlon_rad/2)
let a = sinDlat * sinDlat + cos(lat1_rad) * cos(lat2_rad) * sinDlon * sinDlon
let c = 2.0 * atan2(sqrt(a), sqrt(1-a))
return rm * c
}

