如何不用谷歌地图API计算两个GPS坐标之间的距离?

时间:2021-04-30 15:24:16

I'm wondering if there's a way to calculate the distance of two GPS coordinates without relying on Google Maps API.

我想知道有没有一种不用谷歌Maps API就能计算两个GPS坐标距离的方法。

My app may receive the coordinates in float or I would have to do reverse GEO on the addresses.

我的应用程序可以接收到浮动的坐标,或者我必须在地址上做反向GEO。

6 个解决方案

#1


65  

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.

地球上两个坐标之间的距离通常用海弗赛公式计算。这个公式考虑了地球的形状和半径。这是我用来计算米的距离的代码。

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

#2


6  

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(以0-360度之间的浮点数表示的方向)和midpoint_to(返回一个可以运行.latitude和.longitude方法的对象)。

#3


4  

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

#4


3  

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

#5


2  

Look at gem Geocoder(railscast)

看看宝石Geocoder(railscast)

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

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

#6


1  

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
}

#1


65  

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.

地球上两个坐标之间的距离通常用海弗赛公式计算。这个公式考虑了地球的形状和半径。这是我用来计算米的距离的代码。

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

#2


6  

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(以0-360度之间的浮点数表示的方向)和midpoint_to(返回一个可以运行.latitude和.longitude方法的对象)。

#3


4  

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

#4


3  

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

#5


2  

Look at gem Geocoder(railscast)

看看宝石Geocoder(railscast)

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

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

#6


1  

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
}