如何在不使用Google Maps API的情况下计算两个GPS坐标之间的距离?

我想知道是否有办法计算两个GPS坐标的距离而不依赖于Google Maps API。

我的应用程序可能会收到float中的坐标,或者我必须在地址上执行反向GEO。

地球上两个坐标之间的距离通常使用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 

你可以使用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 

您还可以找到bearing_to (方向表示为0-360之间的浮点数)和midpoint_to (返回一个对象,您可以运行.latitude和.longitude方法)。

我不确定任何预先打包的解决方案,但它似乎是一个相当简单的计算: http : //www.movable-type.co.uk/scripts/latlong.html

只是一个更短和分离参数版本@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 

看看gem Geocoder ( railscast )

如果将坐标存储在db中,则使用数据库计算距离。 但在其他情况下效果也不错。

将接受的答案转换为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 } 

您可以像这样使用loc gem :

 require 'loc' loc1 = Loc::Location[49.1, 2] loc2 = Loc::Location[50, 3] loc1.distance_to(loc2) => 123364.76538823603 # km