Sunteți pe pagina 1din 4

4/15/2015

Microsoft Access Tips & Tricks: Great Circle Distance | The Blogannath Rolls On . . .

M O ND A Y, A P R I L 1 2 , 2 0 1 0

Microsoft Access Tips & Tricks: Great Circle Distance


The great circle distance or orthodromic distance is the shortest distance between any two points on the surface of a sphere measured along a path on
the surface of the sphere (as opposed to going through the sphere's interior). Because spherical geometry is rather different from ordinary Euclidean
geometry , the equations for distance take on a different form. The distance between two points in Euclidean space is the length of a straight line from
one point to the other. On the sphere, howev er, there are no straight lines. In non-Euclidean geometry , straight lines are replaced with geodesics.
Geodesics on the sphere are the great circles (circles on the sphere whose centers are coincident with the center of the sphere).
If y ou are interested, y ou can find my earlier posts on finding the median, the mode, the geometric and harmonic means, ranking ev ery row in a
query ,selecting random rows out of a table, calculating running sums and av erages, calculating running differences, creating histograms, calculating
probability masses out of giv en data, calculating cumulativ e distributions out of giv en data, finding percentile scores, percentile v alues, calculating
distinct counts, full outer joins, parameter queries,crosstab queries, working with sy stem objects, listing table fields, finding unmatched
rows, calculating statistics with grouping, job-candidate matching, andjob-candidate matching with skill lev els.
Between any two points on a sphere which are not directly opposite each other, there is a unique great circle. The two points separate the great circle
into two arcs. The length of the shorter arc is the great circle distance between the points.
Between two points which are directly opposite each other, called antipodal points, there are infinitely many great circles, but all great circle arcs
between antipodal points hav e the same length, i.e. half the circumference of the circle, or r, where r is the radius of the sphere.
Great circle distances are v ery useful for finding the shortest distances between points on a sphere. Since the shape of the earth can be approx imated
to be a sphere with negligible loss of accuracy , the distance between different points on the earth can be calculated to a great degree of accuracy using
great circle distance formulae.
If we hav e a database that has a table that lists the coordinates of v arious points on the earth (coordinates of cities, airports, etc.), then we may want to
use these formulae to calculate the great circle distance between them at some point. For the purpose of this post, we will assume that
our database contains coordinates in the form of degrees, minutes and seconds for both latitude and longitude.
We will also assume that latitude v alues can go from -90 to +90 degrees, with latitudes of points on the northern hemisphere of the earth being positiv e
and latitudes of points on the southern hemisphere being negativ e. All points on the equator will hav e a latitude of 0, while the north pole will hav e a
latitude of +90 and the south pole would hav e a latitude of -90.
Similarly , we will assume that longitudes range from -1 80 degrees to +1 80 degrees. Points on the prime meridian that passes through Greenwich,
England, would hav e a longitude of 0, while points on the opposite side of the earth from that line would hav e a longitude of either +1 80 or -1 80 (the
+1 80 and -1 80 lines of longitude coincide on top of each other). We will assume that points in the western hemisphere hav e negativ e longitudes while
points in the eastern hemisphere hav e positiv e longitudes.
Now, that we hav e established the basics of the table structure and conv entions regarding signs and quantities, we can look at the formulae used for
computing the great circle distance between two points. Let
point respectiv ely . Let
calculated in terms of
between the points is r*

be the coordinates (latitude, longitude) of the start point and final

be the differences in latitude and longitude respectiv ely between the two points. The distance between them is
, which represents the angular distance between the points subtended at the center of the sphere. The actual distance
, where r is the radius of the sphere.

In the case of the earth, r is 637 1 .01 km, 3958.7 6 statute miles or 3440.07 nautical miles.

The most common formula one encounters is called the ArcCosine formula. It calculates

as below:

Unfortunately , this formula has large rounding errors when the distances are v ery small, so it is not commonly used. One of the alternativ es to the
ArcCosine formula is the Hav ersine formula below:

Although this formula is accurate for most distances, it too suffers from rounding errors for the special (and somewhat unusual) case of antipodal
points (on opposite ends of the sphere). A more complicatedformula that is accurate for all distances is the following special case (a sphere, which is an
ellipsoid with equal major and minor ax es) of the V incenty formula (which more generally is a method to compute distances on ellipsoids):

http://blogannath.blogspot.com.au/2010/04/microsoft-access-tips-tricks-great.html

1/4

4/15/2015

Microsoft Access Tips & Tricks: Great Circle Distance | The Blogannath Rolls On . . .

In this post, I will prov ide code for V BA functions that implement each of these formulae to calculate the great circle distance between any two points,
whose coordinates are passed into these functions as arguments. Y ou can compare the performance of these functions against each other and use
whichev er one suits y our purpose best. In most cases, they will come up with the ex act same answer, so it is only a matter of preference which one is
chosen. But giv en the cav eat about errors in v ery short distances when using the ArcCosine formula, and the complex ity of the V incenty formula, I
prefer the Hav ersine formula.
Notice that Microsoft Access lacks functions for ArcCos() and ArcSin(), and therefore these quantities hav e to be deriv ed using other trigonometric
functions av ailable in Access. Therefore I will prov ide these functions first before I go on to the functions for the distance. Those functions for distance
will use the ArcCos and ArcSin functions below. The ArcCos and ArcSin functions are written based on the trigonometric identities below:
ArcCos(X) = ArcTan(-X / (-X * X + 1)) + 2 * ArcTan(1)
Arcsin(X) = ArcTan(X / (-X * X + 1))

Below is the function that implements ArcCos:


Function ArcCos(X As Double) As Double
If Abs(X) > 1# Then X = X - Fix(X)
ArcCos = Atn(-X / Sqr(-X * X + 1)) + 2 * Atn(1)
End Function
Note that the argument to the function must fall in the range between -1 and 1 inclusiv e (the cosine of any angle can not fall outside this range). When
the argument is outside this range I remov e the integer portion of the argument using the fix () function and use only the fractional part in
my calculations.
Below is the function that implements ArcSin:
Function ArcSin(X As Double) As Double
If Abs(X) > 1# Then X = X - Fix(X)
ArcSin = Atn(X / Sqr(-X * X + 1))
End Function
Note again, that the argument to this function must also fall in the range between -1 and 1 inclusiv e (the sin of any angle can not fall outside this range).
When the argument is outside this range, I remov e the integer portion of the argument using the fix () function and use only the fractional part in
my calculations.
Before we code up the great circle distancecalculations, we also need to conv ert the coordinates of the points into radians. Microsoft Access's
trigonometric functions ex pect angles to be in radians rather than degrees. Thus, we need the function below to conv ert any giv en coordinates into
radians.
Function DegToRad(Degrees As Double, Minutes As Double, Seconds As Double) As Double
Const Pi As Double = 3.14159265358979
Degrees = Degrees + Minutes / 60#
Degrees = Degrees + Seconds / 3600#
DegToRad = Degrees * Pi / 180#
End Function
Notice that we hav e defined a constant named pi to equal 3.1 41 5926535897 932, and we take adv antage of the identity that angle in radians = angle in
degrees*/1 80.0.
First we will code up the ArcCosine formula as below:
Function ArcCosineDistance(SourceLatDeg As Double, _
SourceLatMin As Double, SourceLatSec As Double, _
SourceLongDeg As Double, SourceLongMin As Double, _
SourceLongSec As Double, DestLatDeg As Double, _
DestLatMin As Double, DestLatSec As Double, _
DestLongDeg As Double, DestLongMin As Double, _
DestLongSec As Double) As Double
Const EarthRadiusKM As Double = 6371.01 'Kilometers
Const EarthRadiusSM As Double = 3958.76 'Statute Miles
Const EarthRadiusNM As Double = 3440.07 'Nautical Miles
Dim EarthRadius As Double
Dim SourceLatRad As Double

http://blogannath.blogspot.com.au/2010/04/microsoft-access-tips-tricks-great.html

2/4

4/15/2015

Microsoft Access Tips & Tricks: Great Circle Distance | The Blogannath Rolls On . . .

Dim SourceLongRad As Double


Dim DestLatRad As Double
Dim DestLongRad As Double
Dim DeltaLongRad As Double
EarthRadius = EarthRadiusKM
SourceLatRad = DegToRad(SourceLatDeg, SourceLatMin, SourceLatSec)
SourceLongRad = DegToRad(SourceLongDeg, SourceLongMin, SourceLongSec)
DestLatRad = DegToRad(DestLatDeg, DestLatMin, DestLatSec)
DestLongRad = DegToRad(DestLongDeg, DestLongMin, DestLongSec)
DeltaLongRad = Abs(SourceLongRad - DestLongRad)
ArcCosineDistance = Sin(SourceLatRad) * Sin(DestLatRad)
ArcCosineDistance = ArcCosineDistance + Cos(SourceLatRad) * Cos(DestLatRad) * Cos(DeltaLongRad)
ArcCosineDistance = ArcCos(ArcCosineDistance)
ArcCosineDistance = ArcCosineDistance * EarthRadius
End Function
Notice that we hav e constants for the radius of the earth in all three units. One can change the assignment statement to change the v ariable
EarthRadius, and therefore, the great circle distance calculated to any of the three units depending on one's preferences. Also notice how the same
v ariable (in this case, the name of the function, which is the return v ariable's name) is used to accumulate the calculation step by step all the way to the
final step.
Nex t we code up the Hav ersine formula for great circle distance as below:
Function HaversineDistance(SourceLatDeg As Double, _
SourceLatMin As Double, SourceLatSec As Double, _
SourceLongDeg As Double, SourceLongMin As Double, _
SourceLongSec As Double, DestLatDeg As Double, _
DestLatMin As Double, DestLatSec As Double, _
DestLongDeg As Double, DestLongMin As Double, _
DestLongSec As Double) As Double
Const EarthRadiusKM As Double = 6371.01 'Kilometers
Const EarthRadiusSM As Double = 3958.76 'Statute Miles
Const EarthRadiusNM As Double = 3440.07 'Nautical Miles
Dim EarthRadius As Double
Dim SourceLatRad As Double
Dim SourceLongRad As Double
Dim DestLatRad As Double
Dim DestLongRad As Double
Dim DeltaLatRad As Double
Dim DeltaLongRad As Double
EarthRadius = EarthRadiusKM
SourceLatRad = DegToRad(SourceLatDeg, SourceLatMin, SourceLatSec)
SourceLongRad = DegToRad(SourceLongDeg, SourceLongMin, SourceLongSec)
DestLatRad = DegToRad(DestLatDeg, DestLatMin, DestLatSec)
DestLongRad = DegToRad(DestLongDeg, DestLongMin, DestLongSec)
DeltaLatRad = Abs(SourceLatRad - DestLatRad)
DeltaLongRad = Abs(SourceLongRad - DestLongRad)
HaversineDistance = Sin(DeltaLatRad / 2#) * Sin(DeltaLatRad / 2#)
HaversineDistance = HaversineDistance + _
Cos(SourceLatRad) * Cos(DestLatRad) * Sin(DeltaLongRad / 2#) * Sin(DeltaLongRad / 2#)
HaversineDistance = 2 * ArcSin(Sqr(HaversineDistance))
HaversineDistance = HaversineDistance * EarthRadius
End Function
And, finally , the V incenty formula as below:
Function VincentyDistance(SourceLatDeg As Double, _
SourceLatMin As Double, SourceLatSec As Double, _
SourceLongDeg As Double, SourceLongMin As Double, _
SourceLongSec As Double, DestLatDeg As Double, _
DestLatMin As Double, DestLatSec As Double, _
DestLongDeg As Double, DestLongMin As Double, _
DestLongSec As Double) As Double

http://blogannath.blogspot.com.au/2010/04/microsoft-access-tips-tricks-great.html

3/4

4/15/2015

Microsoft Access Tips & Tricks: Great Circle Distance | The Blogannath Rolls On . . .

Const EarthRadiusKM As Double = 6371.01 'Kilometers


Const EarthRadiusSM As Double = 3958.76 'Statute Miles
Const EarthRadiusNM As Double = 3440.07 'Nautical Miles
Const Pi As Double = 3.14159265358979
Const Epsilon As Double = 0.000000000001
Dim EarthRadius As Double
Dim SourceLatRad As Double
Dim SourceLongRad As Double
Dim DestLatRad As Double
Dim DestLongRad As Double
Dim DeltaLongRad As Double
Dim Numerator1 As Double
Dim Numerator2 As Double
Dim Numerator As Double
Dim Denominator As Double
EarthRadius = EarthRadiusKM
SourceLatRad = DegToRad(SourceLatDeg, SourceLatMin, SourceLatSec)
SourceLongRad = DegToRad(SourceLongDeg, SourceLongMin, SourceLongSec)
DestLatRad = DegToRad(DestLatDeg, DestLatMin, DestLatSec)
DestLongRad = DegToRad(DestLongDeg, DestLongMin, DestLongSec)
DeltaLongRad = Abs(SourceLongRad - DestLongRad)
Numerator1 = Cos(DestLatRad) * Sin(DeltaLongRad)
Numerator1 = Numerator1 * Numerator1
Numerator2 = Cos(SourceLatRad) * Sin(DestLatRad)
Numerator2 = Numerator2 - Sin(SourceLatRad) * Cos(DestLatRad) * Cos(DeltaLongRad)
Numerator2 = Numerator2 * Numerator2
Numerator = Numerator1 + Numerator2
Numerator = Sqr(Numerator)
Denominator = Sin(SourceLatRad) * Sin(DestLatRad)
Denominator = Denominator + Cos(SourceLatRad) * Cos(DestLatRad) * Cos(DeltaLongRad)
If Abs(Denominator) < Epsilon Then
VincentyDistance = Pi / 2#
Else
VincentyDistance = Numerator / Denominator
VincentyDistance = Atn(VincentyDistance)
End If
VincentyDistance = VincentyDistance * EarthRadius
End Function
Notice that we hav e calculated the numerator and denominator of the V incenty formula separately rather than doing the calculations all at once. This
is not only a concession to the complex ity of the formula itself, but also to the fact that we need to deal with the special case of the denominator
becoming zero (this is the only one of the three formulae that has a denominator and inv olv es div ision). This is accomplished by checking the absolute
v alue of the denominator against a v ery small constant, Epsilon. When the denominator is less than epsilon, we assume that the denominator is zero,
and the ex pression inside the parentheses becomes infinity . As we know, the ArcTangent of infinity is /2 radians, so we set the subtended angle to
/2 when the denominator is close to zero rather than attempting a div ision by a number that close to zero, and risking a run-time error.
The code abov e (all functions) has been checked in Access 2003. It should work in any v ersion of Access from Access 97 on up, but please do let me
know through the comments if y ou hav e problems using the code.
Hope this post has been helpful in solv ing any problems y ou might hav e had with great circle distance calculations in Access. If y ou hav e any
problems or concerns with the V BA code in this lesson, please feel free to let me know by posting a comment. If y ou hav e other questions on Access
that y ou would like me to address in future lessons, please feel free to let me know through y our comments too. Good luck!

http://blogannath.blogspot.com.au/2010/04/microsoft-access-tips-tricks-great.html

4/4

S-ar putea să vă placă și