Module: RVincenty

Defined in:
lib/rvincenty.rb

Class Method Summary collapse

Class Method Details

.distance(point_a, point_b) ⇒ Object

Calculates the distance between two given points. A point is a two-elmeent array containing the points coordinates (Latitude and Longitutde) experessed as a floating point number.



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/rvincenty.rb', line 5

def self.distance(point_a, point_b)
  lat1, lon1 = point_a
  lat2, lon2 = point_b

  # WGS-84 ellipsiod
  a = 6378137.0
  b = 6356752.3142
  f = 1.0/298.257223563

  l = deg_to_rad(lon2 - lon1)
  u1 = Math.atan((1.0-f) * Math.tan(deg_to_rad(lat1)));
  u2 = Math.atan((1.0-f) * Math.tan(deg_to_rad(lat2)));

  sinU1 = Math.sin(u1)
  cosU1 = Math.cos(u1)
  sinU2 = Math.sin(u2)
  cosU2 = Math.cos(u2)

  lambda = l

  iterLimit = 100
  lambdaP = nil
  while true
    sinLambda = Math.sin(lambda)
    cosLambda = Math.cos(lambda)

    sinSigma = Math.sqrt((cosU2*sinLambda) * (cosU2*sinLambda) +
      (cosU1*sinU2-sinU1*cosU2*cosLambda) * (cosU1*sinU2-sinU1*cosU2*cosLambda))

    # co-incident points
    return 0 if (sinSigma==0)

    cosSigma = sinU1*sinU2 + cosU1*cosU2*cosLambda;
    sigma = Math.atan2(sinSigma, cosSigma);
    sinalpha = cosU1 * cosU2 * sinLambda / sinSigma;
    cosSqalpha = 1.0 - sinalpha*sinalpha;
    cos2SigmaM = cosSigma - 2.0*sinU1*sinU2/cosSqalpha;
    if cos2SigmaM.nan?
      cos2SigmaM = 0
    end

    c = f/16*cosSqalpha*(4+f*(4-3*cosSqalpha));
    lambdaP = lambda;
    lambda = l + (1.0-c) * f * sinalpha * (sigma + c*sinSigma*(cos2SigmaM+c*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));
    iterLimit -= 1

    break if (lambda-lambdaP).abs < 1e-12 || iterLimit <= 0
  end

  #formula failed to converge
  return NaN if (iterLimit==0)

  uSq = cosSqalpha * (a*a - b*b) / (b*b);
  va = 1 + uSq/16384.0*(4096.0+uSq*(-768.0+uSq*(320.0-175.0*uSq)))
  vb = uSq/1024.0 * (256.0+uSq*(-128.0+uSq*(74.0-47.0*uSq)))
  deltaSigma = vb*sinSigma*(cos2SigmaM+vb/4.0*(cosSigma*(-1.0+2.0*cos2SigmaM*cos2SigmaM)-
    vb/6*cos2SigmaM*(-3.0+4.0*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)))
  s = b*va*(sigma-deltaSigma)

  return s;
end