I've never posted a question on any site before, but after racking my head over this hurdle for days, I've caved. I'm working on a program that creates a kml file and exports it to Google Earth. In that file, I want to create a 5 mile radius circle around the placemark. To do that, I worked with the kml circlegen source I found online in php. It calculates the latitudes and longitudes of the points that make up the circle. The calculation works correrctly (as shown by printing to the immediate window or by calling the sub), but I can't get the function to return the array. As many different ways I've structured it, I keep getting a 'type mismatch'. Any help would be GREATLY appreciated! I believe I've included all the necessary function code:
Code:
Option Explicit
Private Const Radius5mls As Double = 8046.72 'in meters
Private Const PI As Double = 3.14159265358979
Public Sub FiveMileRadius(lat1 As Double, lon1 As Double)
Dim Arr As Variant
Dim i As Integer
Arr = FiveMileCircleGen(lat1, lon1)
If IsArrayAllocated(Arr:=Arr) = True Then
For i = LBound(Arr) To UBound(Arr)
Debug.Print Arr(i)
Next i
Else
MsgBox ("Not Allocated")
End If
End Sub
Code:
Public Function FiveMileCircleGen(lat1 As Double, lon1 As Double) As Variant()
Dim ResultArray() As Variant
Dim i As Integer
Dim radial As Double, angle As Double
Dim iNumSides As Integer
Dim lat2 As Double
Dim lon2 As Double
Dim dlon As Double
Dim modNum As Double
Dim modDiv As Double
Dim distance As Double
'convert coordinates to radians
lat1 = Deg2Rad(lat1)
lon1 = Deg2Rad(lon1)
iNumSides = 360
distance = Radius5mls / 6378137 'divided by radius of earth at the equator, in meters
' Create an array to hold all of the points:
ReDim ResultArray(i To (iNumSides / 2))
' trigonometry to calculate circles lat/lon points:
For i = 0 To iNumSides Step 2
angle = i
radial = Deg2Rad(angle)
lat2 = fnArcSineRad(sIn(lat1) * Cos(distance) + Cos(lat1) * sIn(distance) * Cos(radial))
dlon = ATan2(sIn(radial) * sIn(distance) * Cos(lat1), Cos(distance) - (sIn(lat1) * sIn(lat2)))
modNum = (lon1 + dlon + PI)
modDiv = 2 * PI
lon2 = (modNum - modDiv * Int(modNum / modDiv)) - PI
lat2 = CStr(Rad2Deg(lat2))
lon2 = CStr(Rad2Deg(lon2))
ResultArray(i) = lon2 & "," & lat2 & ",0 "
'Debug.Print lon2 & "," & lat2 & ",0 "
Next i
FiveMileCircleGen = ResultArray ' remove this line and the resultarray(i) line and open the debug line to work
End Function
Code:
Public Function IsArrayAllocated(Arr As Variant) As Boolean
On Error Resume Next
IsArrayAllocated = Not (IsError(LBound(Arr))) And IsArray(Arr) And (LBound(Arr) <= UBound(Arr))
End Function
' Name: ARC SINE IN RADIANS
' Purpose: This function determines the ArcSine of the passed argument.
' Inputs: vntSine The sine of an angle.
' Assumptions: None.
' Effects: Will raise "Overflow" error if vntSine is not a valid sine or
' if any other error occurs during execution.
' Returns: The angle in radians.
' If an error occurs fnArcSine is indeterminate.
'
Public Function fnArcSineRad(vntSine As Variant) As Double
On Error GoTo ERROR_ArcSine ' Trap strangeness.
Const cOVERFLOW = 6 ' "Overflow" message #.
Dim blnEditPassed As Boolean ' Edit results variable.
Dim dblTemp As Double ' Temporary double.
blnEditPassed = False ' It hasn't passed yet!
If IsNumeric(vntSine) Then ' Is arg numeric?
If vntSine >= -1 And vntSine <= 1 Then ' Yup, is it within limits?
blnEditPassed = True ' Yup, employ Derived Math Function:
' Arcsin(X) = Atn(X / Sqr(-X * X + 1))
dblTemp = Sqr(-vntSine * vntSine + 1) ' Calculate denominator.
If dblTemp = 0 Then ' Is it 0? Can only happen if arg is +1 or -1.
fnArcSineRad = Sgn(vntSine) * PI / 2 ' Yup, assign +Pi/2 or -Pi/2 based on sign of arg.
Else
fnArcSineRad = Atn(vntSine / dblTemp) ' Complete derived math function.
End If
End If
End If
EXIT__ArcSine:
If Not blnEditPassed Then Err.Raise cOVERFLOW ' Raise overflow error if arg failed edits.
Exit Function
ERROR_ArcSine:
On Error GoTo 0 ' Turn off error trapping.
blnEditPassed = False ' Should never happen!
Resume EXIT__ArcSine ' But if it does give overflow error.
End Function
Comment