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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 05:27:52  来源:igfitidea点击:

How to calculate the distance between two GPS coordinates without using Google Maps API?

rubygoogle-maps

提问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

Look at gem Geocoder(railscast)

看看 gem Geocoder( railscast)

If you store your coordinates in db, it calculate distance using database. But works good in other cases too.

如果您将坐标存储在 db 中,它将使用数据库计算距离。但在其他情况下也能很好地工作。

回答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
}

回答by Hugo Barthelemy

You can use the loc gemlike this :

您可以像这样使用loc gem

require 'loc'

loc1 = Loc::Location[49.1, 2]
loc2 = Loc::Location[50, 3]

loc1.distance_to(loc2)
=> 123364.76538823603 # km