My code works but is WAY WAY to slow. Please help me to find a better/faster way to find the closest record to given cordinates.
Currently I have code that when given a latitude and longitude it will go record by record thru a table with latitudes and longitudes calculating the distance between the 2 cordinates. As is cycles thru the records it keeps the closest distance records information. At the end of the function it returns the closest "job info" to the given latitude and longitude.
Table is something like
C_JobNum C_PhaseNumber C_Latitude C_Longitude
2345 2.2 34.4356 -123.456
2432 1 25.4653 -435.1231
.
.
.
Thanks In Advance,
Mark
Currently I have code that when given a latitude and longitude it will go record by record thru a table with latitudes and longitudes calculating the distance between the 2 cordinates. As is cycles thru the records it keeps the closest distance records information. At the end of the function it returns the closest "job info" to the given latitude and longitude.
Table is something like
C_JobNum C_PhaseNumber C_Latitude C_Longitude
2345 2.2 34.4356 -123.456
2432 1 25.4653 -435.1231
.
.
.
Code:
Option Compare Database
Option Explicit
Dim MyDB As DAO.Database
Dim MyRS As DAO.Recordset
Dim MySQL As String
Dim RC As Integer
Dim RI As Integer
Dim CompareDistance As Double
Dim StoreDistance As Double
Dim StoreJobNumber As String
Dim StorePhaseNumber As String
Public Function GeoFence(SearchLatitude As Variant, SearchLongitude As Variant) As Variant
If SearchLatitude > 0 Or SearchLongitude > 0 Then
Set MyDB = CurrentDb
MySQL = "SELECT C_JobNum, C_PhaseNumber, C_Latitude, C_Longitude FROM dbo_TblContract"
Set MyRS = MyDB.OpenRecordset(MySQL, dbOpenDynaset, dbSeeChanges)
While Not MyRS.EOF
MyRS.MoveLast
RC = MyRS.RecordCount
MyRS.MoveFirst
StoreDistance = Distance(CDbl(SearchLatitude), CDbl(SearchLongitude), MyRS.Fields("C_Latitude").Value, MyRS.Fields("C_Longitude").Value)
StoreJobNumber = MyRS.Fields("C_JobNum").Value
StorePhaseNumber = MyRS.Fields("C_PhaseNumber").Value
For RI = 1 To RC
CompareDistance = Distance(CDbl(SearchLatitude), CDbl(SearchLongitude), MyRS.Fields("C_Latitude").Value, MyRS.Fields("C_Longitude").Value)
If StoreDistance > CompareDistance Then
StoreDistance = CompareDistance
StoreJobNumber = MyRS.Fields("C_JobNum").Value
StorePhaseNumber = MyRS.Fields("C_PhaseNumber").Value
End If
MyRS.MoveNext
Next RI
Wend
MyRS.Close
Set MyRS = Nothing
MyDB.Close
Set MyDB = Nothing
GeoFence = StoreJobNumber & " " & StorePhaseNumber & " " & StoreDistance
End If
End Function
Public Function Distance(lat1 As Double, Long1 As Double, lat2 As Double, Long2 As Double) As Double
lat1 = lat1 / 57.29577951
lat2 = lat2 / 57.29577951
Long1 = Long1 / 57.29577951
Long2 = Long2 / 57.29577951
If lat1 = lat2 And Long1 = Long2 Then
Distance = 0
Else
If (Sin(lat1) * Sin(lat2) + Cos(lat1) * Cos(lat2) * Cos(Long1 - Long2)) > 1 Then
Distance = 3963.1 * ArcCos(1)
Else
Distance = 3963.1 * ArcCos(Sin(lat1) * Sin(lat2) + Cos(lat1) * Cos(lat2) * Cos(Long1 - Long2))
End If
End If
End Function
Function ArcCos(ByVal X As Double) As Double
If X <> 1 Then
ArcCos = Atn(-X / Sqr(-X * X + 1)) + 2 * Atn(1)
Else
ArcCos = 0
End If
End Function
Thanks In Advance,
Mark