geo-distance 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +7 -9
- data/Gemfile.lock +30 -13
- data/README.textile +28 -8
- data/VERSION +1 -1
- data/geo-distance.gemspec +40 -32
- data/lib/geo-distance.rb +14 -132
- data/lib/geo-distance/class_methods.rb +71 -0
- data/lib/geo-distance/conversion.rb +67 -0
- data/lib/geo-distance/conversion/meters.rb +29 -0
- data/lib/geo-distance/conversion/radians.rb +36 -0
- data/lib/geo-distance/core_ext.rb +12 -23
- data/lib/geo-distance/distance.rb +24 -0
- data/lib/geo-distance/formula.rb +53 -7
- data/lib/geo-distance/formula/flat.rb +21 -0
- data/lib/geo-distance/{haversine.rb → formula/haversine.rb} +18 -14
- data/lib/geo-distance/formula/n_vector.rb +30 -0
- data/lib/geo-distance/formula/spherical.rb +44 -0
- data/lib/geo-distance/formula/vincenty.rb +80 -0
- data/lib/geo-distance/scale.rb +18 -0
- data/spec/geo_distance/class_methods_spec.rb +70 -0
- data/spec/geo_distance/core_ext_spec.rb +65 -0
- data/spec/geo_distance/distance_spec.rb +74 -0
- data/spec/geo_distance/formula/flat_spec.rb +31 -0
- data/spec/geo_distance/formula/haversine_spec.rb +33 -0
- data/spec/geo_distance/formula/n_vector.rb +33 -0
- data/spec/geo_distance/formula/spherical_spec.rb +33 -0
- data/spec/geo_distance/formula/vincenty_spec.rb +33 -0
- data/spec/spec_helper.rb +0 -10
- metadata +97 -96
- data/lib/geo-distance/spherical.rb +0 -24
- data/lib/geo-distance/vincenty.rb +0 -79
- data/spec/core_ext_spec.rb +0 -9
- data/spec/dist_default_spec.rb +0 -23
- data/spec/dist_haversine_spec.rb +0 -21
- data/spec/dist_spherical_spec.rb +0 -21
- data/spec/dist_vincenty_spec.rb +0 -21
@@ -0,0 +1,67 @@
|
|
1
|
+
class GeoDistance
|
2
|
+
module Conversion
|
3
|
+
autoload :Meters, 'geo-distance/conversion/meters'
|
4
|
+
autoload :Radians, 'geo-distance/conversion/radians'
|
5
|
+
|
6
|
+
def self.included(base)
|
7
|
+
base.send :include, Meters
|
8
|
+
base.send :include, Radians
|
9
|
+
end
|
10
|
+
|
11
|
+
# return new GeoDistance instance with distance converted to specific unit
|
12
|
+
::GeoDistance.units.each do |unit|
|
13
|
+
class_eval %{
|
14
|
+
def to_#{unit}
|
15
|
+
cloned = self.dup
|
16
|
+
un = GeoUnits.key :#{unit}
|
17
|
+
cloned.distance = in_meters * GeoUnits.meters_map[un]
|
18
|
+
cloned.unit = un
|
19
|
+
cloned
|
20
|
+
end
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
# in_ and as_ return distance as a Float
|
25
|
+
# to_xxx! and similar, modify distance (self) directly
|
26
|
+
(::GeoDistance.units - [:meters]).each do |unit|
|
27
|
+
class_eval %{
|
28
|
+
def in_#{unit}
|
29
|
+
dist = (unit == :radians) ? in_radians : distance
|
30
|
+
conv_unit = GeoUnits.key :#{unit}
|
31
|
+
convert_to_meters(dist) * GeoUnits.meters_map[conv_unit]
|
32
|
+
end
|
33
|
+
alias_method :as_#{unit}, :in_#{unit}
|
34
|
+
|
35
|
+
def to_#{unit}!
|
36
|
+
conv_unit = GeoUnits.key :#{unit}
|
37
|
+
self.distance = in_meters * GeoUnits.meters_map[conv_unit]
|
38
|
+
self.unit = conv_unit
|
39
|
+
self
|
40
|
+
end
|
41
|
+
alias_method :in_#{unit}!, :to_#{unit}!
|
42
|
+
alias_method :as_#{unit}!, :to_#{unit}!
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
::GeoDistance.all_units.each do |unit|
|
47
|
+
class_eval %{
|
48
|
+
def #{unit}
|
49
|
+
un = GeoUnits.key :#{unit}
|
50
|
+
send(:"as_\#{un}")
|
51
|
+
end
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
protected
|
56
|
+
|
57
|
+
# distance delta
|
58
|
+
GeoDistance.units.each do |unit|
|
59
|
+
class_eval %{
|
60
|
+
def delta_#{unit}
|
61
|
+
unit = GeoUnits.key(:#{unit})
|
62
|
+
GeoDistance.earth_radius[:#{unit}] * distance
|
63
|
+
end
|
64
|
+
}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class GeoDistance
|
2
|
+
module Conversion
|
3
|
+
module Meters
|
4
|
+
def in_meters
|
5
|
+
convert_to_meters distance
|
6
|
+
end
|
7
|
+
alias_method :to_meters, :in_meters
|
8
|
+
alias_method :as_meters, :in_meters
|
9
|
+
|
10
|
+
def to_meters!
|
11
|
+
self.distance = convert_to_meters distance
|
12
|
+
self.unit = :meters
|
13
|
+
self
|
14
|
+
end
|
15
|
+
alias_method :in_meters!, :to_meters!
|
16
|
+
alias_method :as_meters!, :to_meters!
|
17
|
+
|
18
|
+
def convert_to_meters dist
|
19
|
+
(unit == :meters) ? dist : distance / GeoUnits.meters_map[unit]
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_meters!
|
23
|
+
@distance = in_meters
|
24
|
+
@unit = :meters
|
25
|
+
self
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class GeoDistance
|
2
|
+
module Conversion
|
3
|
+
module Radians
|
4
|
+
def to_radians
|
5
|
+
cloned = self.dup
|
6
|
+
cloned.distance = in_radians
|
7
|
+
cloned.unit = :radians
|
8
|
+
cloned
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_radians! lat = 0
|
12
|
+
@distance = in_radians(lat)
|
13
|
+
@unit = :radians
|
14
|
+
end
|
15
|
+
|
16
|
+
def radians_conversion_factor
|
17
|
+
unit.radians_ratio
|
18
|
+
end
|
19
|
+
|
20
|
+
# calculate the distance in radians for the given latitude
|
21
|
+
def in_radians lat = 0
|
22
|
+
(unit != :radians) ? distance.to_f / earth_factor(lat) : distance # radians_conversion_factor
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
def earth_factor u = nil, lat = 0
|
28
|
+
(GeoDistance.earth_radius[u ||= unit] / 180) * latitude_factor(lat)
|
29
|
+
end
|
30
|
+
|
31
|
+
def latitude_factor latitude = 0
|
32
|
+
90 / (90 - latitude)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -1,31 +1,20 @@
|
|
1
|
-
|
2
|
-
def round_to(x)
|
3
|
-
(self * 10**x).round.to_f / 10**x
|
4
|
-
end
|
5
|
-
|
6
|
-
def ceil_to(x)
|
7
|
-
(self * 10**x).ceil.to_f / 10**x
|
8
|
-
end
|
9
|
-
|
10
|
-
def floor_to(x)
|
11
|
-
(self * 10**x).floor.to_f / 10**x
|
12
|
-
end
|
13
|
-
|
14
|
-
def rpd
|
15
|
-
self * GeoDistance.radians_per_degree
|
16
|
-
end
|
17
|
-
alias_method :to_radians, :rpd
|
18
|
-
end
|
1
|
+
require 'sugar-high/numeric'
|
19
2
|
|
20
|
-
|
21
|
-
|
22
|
-
class Integer
|
23
|
-
::GeoDistance.units.each do |unit|
|
3
|
+
module GeoDistanceExt
|
4
|
+
::GeoDistance.all_units.each do |unit|
|
24
5
|
class_eval %{
|
25
6
|
def #{unit}
|
26
|
-
GeoDistance
|
7
|
+
GeoDistance.new(self, :#{unit})
|
27
8
|
end
|
28
9
|
}
|
29
10
|
end
|
30
11
|
end
|
31
12
|
|
13
|
+
class Fixnum
|
14
|
+
include GeoDistanceExt
|
15
|
+
end
|
16
|
+
|
17
|
+
class Float
|
18
|
+
include GeoDistanceExt
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'geo-distance/class_methods'
|
2
|
+
|
3
|
+
class GeoDistance
|
4
|
+
include Comparable
|
5
|
+
|
6
|
+
include Conversion
|
7
|
+
|
8
|
+
attr_accessor :distance, :unit
|
9
|
+
|
10
|
+
def initialize distance, unit = :radians
|
11
|
+
@distance = distance
|
12
|
+
@unit = GeoUnits.key(unit)
|
13
|
+
end
|
14
|
+
|
15
|
+
alias_method :units, :unit
|
16
|
+
|
17
|
+
def <=> other
|
18
|
+
in_meters <=> other.in_meters
|
19
|
+
end
|
20
|
+
|
21
|
+
def number
|
22
|
+
distance.round_to(precision[unit])
|
23
|
+
end
|
24
|
+
end
|
data/lib/geo-distance/formula.rb
CHANGED
@@ -1,16 +1,62 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
EARTH_MAJOR_AXIS_RADIUS = { :kilometers => 6378.137, :miles => 3963.19059 }
|
5
|
-
EARTH_MINOR_AXIS_RADIUS = { :kilometers => 6356.7523142, :miles => 3949.90276 }
|
6
|
-
|
1
|
+
class GeoDistance
|
2
|
+
include GeoUnits
|
3
|
+
|
7
4
|
class DistanceFormula
|
8
|
-
include Math
|
9
5
|
extend Math
|
6
|
+
extend GeoUnits
|
10
7
|
|
11
8
|
def initialize
|
12
9
|
raise NotImplementedError
|
10
|
+
end
|
11
|
+
|
12
|
+
# use underlying distance formula
|
13
|
+
def self.geo_distance *args
|
14
|
+
GeoDistance.new distance(args), get_units(args.last_option)
|
15
|
+
end
|
16
|
+
|
17
|
+
# used to convert various argument types into GeoPoints
|
18
|
+
def self.get_points(*args)
|
19
|
+
args.flatten!
|
20
|
+
options = args.delete(args.last_option) || {}
|
21
|
+
units = options[:units] || GeoDistance.default_units
|
22
|
+
|
23
|
+
case args.size
|
24
|
+
when 2
|
25
|
+
[GeoPoint.new(args.first), GeoPoint.new(args.last), units]
|
26
|
+
when 4
|
27
|
+
[GeoPoint.new(args[0..1]), GeoPoint.new(args[2..3]), units]
|
28
|
+
else
|
29
|
+
raise "Distance from point A to B, must be given either as 4 arguments (lat1, lng1, lat2, lng2) or 2 arguments: (pointA, pointB), was: #{args}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# used to get the units for how to calculate the distance
|
34
|
+
def self.get_units options = {}
|
35
|
+
GeoUnits.key(options[:units] || :kms)
|
13
36
|
end
|
37
|
+
|
38
|
+
# def self.degrees_to_radians(degrees)
|
39
|
+
# # degrees.to_f / 180.0 * Math::PI
|
40
|
+
# degrees.to_f * radians_per_degree
|
41
|
+
# end
|
42
|
+
|
43
|
+
# def self.units_sphere_multiplier(units)
|
44
|
+
# earth_radius_map[GeoUnit.key units]
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# def self.units_per_latitude_degree(units)
|
48
|
+
# GeoUnits.radian_multiplier[units.to_sym]
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# def self.units_per_longitude_degree(lat, units)
|
52
|
+
# miles_per_longitude_degree = (latitude_degrees * Math.cos(lat * pi_div_rad)).abs
|
53
|
+
# case units
|
54
|
+
# when :kms
|
55
|
+
# miles_per_longitude_degree * kms_per_mile
|
56
|
+
# when :miles
|
57
|
+
# miles_per_longitude_degree
|
58
|
+
# end
|
59
|
+
# end
|
14
60
|
end
|
15
61
|
end
|
16
62
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'geo-distance/core_ext'
|
2
|
+
require 'geo-distance/formula'
|
3
|
+
|
4
|
+
class GeoDistance
|
5
|
+
class Flat < DistanceFormula
|
6
|
+
|
7
|
+
# Calculate distance using Flat earth formula, returns distance in whatever unit is specified (kms by default)
|
8
|
+
def self.distance *args
|
9
|
+
from, to, units = get_points(args)
|
10
|
+
|
11
|
+
return 0 if from == to # return 0.0 if points are have the same coordinates
|
12
|
+
|
13
|
+
Math.sqrt(
|
14
|
+
(units_per_latitude_degree(units) * (from.lat - to.lat))**2 +
|
15
|
+
(units_per_longitude_degree(from.lat, units) * (from.lng - to.lng))**2
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
@@ -33,24 +33,28 @@
|
|
33
33
|
require 'geo-distance/core_ext'
|
34
34
|
require 'geo-distance/formula'
|
35
35
|
|
36
|
-
|
36
|
+
class GeoDistance
|
37
37
|
class Haversine < DistanceFormula
|
38
38
|
# given two lat/lon points, compute the distance between the two points using the haversine formula
|
39
39
|
# the result will be a Hash of distances which are key'd by 'mi','km','ft', and 'm'
|
40
|
-
|
41
|
-
def self.distance
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
40
|
+
|
41
|
+
def self.distance *args
|
42
|
+
begin
|
43
|
+
from, to, units = get_points(args)
|
44
|
+
|
45
|
+
lat1, lon1, lat2, lon2 = [from.lat, from.lng, to.lat, to.lng]
|
46
|
+
dlon = lon2 - lon1
|
47
|
+
dlat = lat2 - lat1
|
48
|
+
|
49
|
+
a = (Math.sin(dlat.rpd/2))**2 + Math.cos(lat1.rpd) * Math.cos((lat2.rpd)) * (Math.sin(dlon.rpd/2))**2
|
50
|
+
c = (2 * Math.atan2( Math.sqrt(a), Math.sqrt(1-a)))
|
51
|
+
c = c.to_deg
|
52
|
+
|
53
|
+
units ? c.radians_to(units) : c
|
54
|
+
rescue Errno::EDOM
|
55
|
+
0.0
|
56
|
+
end
|
49
57
|
end
|
50
|
-
|
51
|
-
def self.calc dlat, lat1, lat2, dlon
|
52
|
-
(Math.sin(dlat.rpd/2))**2 + Math.cos(lat1.rpd) * Math.cos((lat2.rpd)) * (Math.sin(dlon.rpd/2))**2
|
53
|
-
end
|
54
58
|
end
|
55
59
|
|
56
60
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class GeoDistance
|
2
|
+
class NVector < DistanceFormula
|
3
|
+
def self.distance *args
|
4
|
+
from, to, units = get_points(args)
|
5
|
+
lat1, lon1, lat2, lon2 = [from.lat, from.lng, to.lat, to.lng]
|
6
|
+
|
7
|
+
sin_x1 = Math.sin(lon1)
|
8
|
+
cos_x1 = Math.cos(lon1)
|
9
|
+
|
10
|
+
sin_y1 = Math.sin(lat1)
|
11
|
+
cos_y1 = Math.cos(lat1)
|
12
|
+
|
13
|
+
sin_x2 = Math.sin(lon2)
|
14
|
+
cos_x2 = Math.cos(lon2)
|
15
|
+
|
16
|
+
sin_y2 = Math.sin(lat2)
|
17
|
+
cos_y2 = Math.cos(lat2)
|
18
|
+
|
19
|
+
cross_prod = (cos_y1*cos_x1 * cos_y2*cos_x2) + (cos_y1*sin_x1 * cos_y2*sin_x2) + (sin_y1 * sin_y2)
|
20
|
+
|
21
|
+
c = Math.acos(cross_prod)
|
22
|
+
|
23
|
+
# puts "c: #{c}"
|
24
|
+
# radians_per_degree
|
25
|
+
c = (c * 0.0201324).to_deg
|
26
|
+
|
27
|
+
units ? c.radians_to(units) : c
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'geo-distance/core_ext'
|
2
|
+
require 'geo-distance/formula'
|
3
|
+
|
4
|
+
# module GeoDistance
|
5
|
+
# class Spherical < DistanceFormula
|
6
|
+
# def self.distance( lat1, lon1, lat2, lon2)
|
7
|
+
# from_longitude = lon1.to_radians
|
8
|
+
# from_latitude = lat1.to_radians
|
9
|
+
# to_longitude = lon2.to_radians
|
10
|
+
# to_latitude = lat2.to_radians
|
11
|
+
#
|
12
|
+
# c = Math.acos(
|
13
|
+
# Math.sin(from_latitude) *
|
14
|
+
# Math.sin(to_latitude) +
|
15
|
+
#
|
16
|
+
# Math.cos(from_latitude) *
|
17
|
+
# Math.cos(to_latitude) *
|
18
|
+
# Math.cos(to_longitude - from_longitude)
|
19
|
+
# ) #* EARTH_RADIUS[units.to_sym]
|
20
|
+
#
|
21
|
+
# GeoDistance::Distance.new c
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
|
26
|
+
class GeoDistance
|
27
|
+
class Spherical < DistanceFormula
|
28
|
+
def self.distance *args
|
29
|
+
from, to, units = get_points(args)
|
30
|
+
|
31
|
+
return 0.0 if from == to #return 0.0 if points are have the same coordinates
|
32
|
+
|
33
|
+
c = Math.acos(
|
34
|
+
Math.sin(degrees_to_radians(from.lat)) * Math.sin(degrees_to_radians(to.lat)) +
|
35
|
+
Math.cos(degrees_to_radians(from.lat)) * Math.cos(degrees_to_radians(to.lat)) *
|
36
|
+
Math.cos(degrees_to_radians(to.lng) - degrees_to_radians(from.lng))
|
37
|
+
).to_deg
|
38
|
+
|
39
|
+
units ? c.radians_to(units) : c
|
40
|
+
rescue Errno::EDOM
|
41
|
+
0.0
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'geo-distance/core_ext'
|
2
|
+
require 'geo-distance/formula'
|
3
|
+
|
4
|
+
class GeoDistance
|
5
|
+
class Vincenty < DistanceFormula
|
6
|
+
|
7
|
+
# Calculate the distance between two Locations using the Vincenty formula
|
8
|
+
#
|
9
|
+
def self.distance *args
|
10
|
+
begin
|
11
|
+
from, to, units = get_points(args)
|
12
|
+
lat1, lon1, lat2, lon2 = [from.lat, from.lng, to.lat, to.lng]
|
13
|
+
|
14
|
+
from_longitude = lon1.to_radians
|
15
|
+
from_latitude = lat1.to_radians
|
16
|
+
to_longitude = lon2.to_radians
|
17
|
+
to_latitude = lat2.to_radians
|
18
|
+
|
19
|
+
earth_major_axis_radius = earth_major_axis_radius_map[:kilometers]
|
20
|
+
earth_minor_axis_radius = earth_minor_axis_radius_map[:kilometers]
|
21
|
+
|
22
|
+
f = (earth_major_axis_radius - earth_minor_axis_radius) / earth_major_axis_radius
|
23
|
+
|
24
|
+
l = to_longitude - from_longitude
|
25
|
+
u1 = atan((1-f) * tan(from_latitude))
|
26
|
+
u2 = atan((1-f) * tan(to_latitude))
|
27
|
+
sin_u1 = sin(u1)
|
28
|
+
cos_u1 = cos(u1)
|
29
|
+
sin_u2 = sin(u2)
|
30
|
+
cos_u2 = cos(u2)
|
31
|
+
|
32
|
+
lambda = l
|
33
|
+
lambda_p = 2 * Math::PI
|
34
|
+
iteration_limit = 20
|
35
|
+
while (lambda-lambda_p).abs > 1e-12 && (iteration_limit -= 1) > 0
|
36
|
+
sin_lambda = sin(lambda)
|
37
|
+
cos_lambda = cos(lambda)
|
38
|
+
sin_sigma = sqrt((cos_u2*sin_lambda) * (cos_u2*sin_lambda) +
|
39
|
+
(cos_u1*sin_u2-sin_u1*cos_u2*cos_lambda) * (cos_u1*sin_u2-sin_u1*cos_u2*cos_lambda))
|
40
|
+
return 0 if sin_sigma == 0 # co-incident points
|
41
|
+
cos_sigma = sin_u1*sin_u2 + cos_u1*cos_u2*cos_lambda
|
42
|
+
sigma = atan2(sin_sigma, cos_sigma)
|
43
|
+
sin_alpha = cos_u1 * cos_u2 * sin_lambda / sin_sigma
|
44
|
+
cosSqAlpha = 1 - sin_alpha*sin_alpha
|
45
|
+
cos2SigmaM = cos_sigma - 2*sin_u1*sin_u2/cosSqAlpha
|
46
|
+
|
47
|
+
cos2SigmaM = 0 if cos2SigmaM.nan? # equatorial line: cosSqAlpha=0 (§6)
|
48
|
+
|
49
|
+
c = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha))
|
50
|
+
lambda_p = lambda
|
51
|
+
lambda = l + (1-c) * f * sin_alpha *
|
52
|
+
(sigma + c*sin_sigma*(cos2SigmaM+c*cos_sigma*(-1+2*cos2SigmaM*cos2SigmaM)))
|
53
|
+
end
|
54
|
+
# formula failed to converge (happens on antipodal points)
|
55
|
+
# We'll call Haversine formula instead.
|
56
|
+
return Haversine.distance(from, to, units) if iteration_limit == 0
|
57
|
+
|
58
|
+
uSq = cosSqAlpha * (earth_major_axis_radius**2 - earth_minor_axis_radius**2) / (earth_minor_axis_radius**2)
|
59
|
+
a = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)))
|
60
|
+
b = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)))
|
61
|
+
delta_sigma = b*sin_sigma*(cos2SigmaM+b/4*(cos_sigma*(-1+2*cos2SigmaM*cos2SigmaM)-
|
62
|
+
b/6*cos2SigmaM*(-3+4*sin_sigma*sin_sigma)*(-3+4*cos2SigmaM*cos2SigmaM)))
|
63
|
+
|
64
|
+
c = earth_minor_axis_radius * a * (sigma-delta_sigma)
|
65
|
+
|
66
|
+
c = (c / unkilometer).to_deg
|
67
|
+
|
68
|
+
units ? c.radians_to(units) : c
|
69
|
+
rescue Errno::EDOM
|
70
|
+
0.0
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def self.unkilometer
|
77
|
+
6378.135
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|