I have a question on using Microsoft Access to sort my clients (see first table below) by distance from a user-input zip code. I am using the great circle distance formula (see code below) to calculate the distance between between zip codes. I have a table of every current zip code in the US with its Latitude and Longitude Coordinate as well (see second table below).The function takes the Zip Code of each client and grabs the Latitude and Longitude from the first and second table and uses it to calculate the distance between each. Here is the SQL Query I am running that calls the GreatCircleDistance Formula:
PARAMETERS [Zip Code] IEEEDouble;
SELECT Clinics.Clinic, [US Zip Codes].ZIP,
[US Zip Codes].LAT, [US Zip Codes].LNG,
GreatCircleDistance([Zip Code],[LAT],[LNG],True,True) AS Distance
FROM [US Zip Codes] INNER JOIN Clinics ON [US Zip Codes].ZIP = Clinics.[Clinic ZIP];
The Great Circle Distance Formula used for this query is shown below:
Private Const C_RADIUS_EARTH_KM As Double = 6370.97327862
Private Const C_RADIUS_EARTH_MI As Double = 3958.73926185
Private Const C_PI As Double = 3.14159265358979
Function GreatCircleDistance(ZipCode As Double, _
Latitude2 As Double, Longitude2 As Double, _
ValuesAsDecimalDegrees As Boolean, _
ResultAsMiles As Boolean) As Double
Dim lat1 As Double
Dim lat2 As Double
Dim long1 As Double
Dim long2 As Double
Dim X As Long
Dim Delta As Double
If ValuesAsDecimalDegrees = True Then
X = 1
Else
X = 24
End If
' convert to decimal degrees
'POTENTIAL PROBLEM
lat1 = DLookup("[US Zip Codes].LAT", "[US Zip Codes]", "[US Zip Codes].ZIP = '" & ZipCode & "'") * X
long1 = DLookup("[US Zip Codes].LNG", "[US Zip Codes]", "[US Zip Codes].ZIP = '" & ZipCode & "'") * X
'POTENTIAL PROBLEM
lat2 = Latitude2 * X
long2 = Longitude2 * X
' convert to radians: radians = (degrees/180) * PI
lat1 = (lat1 / 180) * C_PI
lat2 = (lat2 / 180) * C_PI
long1 = (long1 / 180) * C_PI
long2 = (long2 / 180) * C_PI
' get the central spherical angle
Delta = ((2 * ArcSin(Sqr((Sin((lat1 - lat2) / 2) ^ 2) + _
Cos(lat1) * Cos(lat2) * (Sin((long1 - long2) / 2) ^ 2)))))
If ResultAsMiles = True Then
GreatCircleDistance = Delta * C_RADIUS_EARTH_MI
Else
GreatCircleDistance = Delta * C_RADIUS_EARTH_KM
End If
End Function
Function ArcSin(X As Double) As Double
' VBA doesn't have an ArcSin function. Improvise.
ArcSin = Atn(X / Sqr(-X * X + 1))
End Function
Here is the first table that has all of my clients. I only added three for simplicity but there are about 2000 records on file:
Clinic City State Clinic ZIP
Clinic #1 Lakeland FL 33809
Clinic #2 Smyrna TN 37167
Clinic #3 Kissimmee FL 34747
...
Here is the second table that has every US Zip Code. There are a little over 41,000 Zip Codes on record:
ID ZIP LAT LNG
1 00501 40.8133 -73.0476
2 00601 18.18 -66.7522
3 00602 18.3607 -67.1752
4 00603 18.4544 -67.122
...
Now this method works but it takes way to long to calculate the distance between the input Zip Code and the Zip Code of each of the 2000ish client Zip Codes. I think the problem is in the Great Circle Distance Formula when I use DLookUp function to get the latitude and longitude of the user-input Zip Code. Does anyone know how I can decrease computation time for this? Thanks