Option Strict Off
Option Explicit On
Module mdUtmLatLog
	Public Const Pi As Double = 3.14159265358979
	Public istrNorteSul As String
	Private iintZona As Short
	Private iintZonaCentralLongitude As Short
	Public istrOesteLeste As String
	'Calculo Pegada da Latitude
	Private idblPegadaLatitude As Double
	'
	'Coeficientes para Calcular a Latitude
	Private idblFact1 As Double
	Private idblFact2 As Double
	Private idblFact3 As Double
	Private idblFact4 As Double
	'
	'Auxiliar
	Private idblDeltaLongitudeDecimal As Double
	
	Private Sub InicializaVariaveis()
		istrNorteSul = "S"
		iintZona = 22
		iintZonaCentralLongitude = IIf(iintZona > 0, 6 * iintZona - 183, 3)
		istrOesteLeste = IIf(iintZona < 31, "W", "E")
		'Calculo Pegada da Latitude
		idblPegadaLatitude = 0
		'
		'Coeficientes para Calcular a Latitude
		idblFact1 = 0
		idblFact2 = 0
		idblFact3 = 0
		idblFact4 = 0
		'
		'Auxiliar
		idblDeltaLongitudeDecimal = 0
	End Sub
	
	Public Sub MontaCoordenadas(ByVal adblCoordenadaOesteLeste As Double, ByVal adblCoordenadaNorteSul As Double, ByRef pdblResultadoLatitude As Double, ByRef pdblResultadoLongitude As Double)
		Dim ldblCoordenadaOesteLeste As Double
		Dim ldblCoordenadaNorteSul As Double
		Dim ldblLatitudeD As Double 'latd
		Dim ldblLongitudeD As Double 'east 'lond
		Dim ldblPolarRadianos As Double 'b
		Dim ldblEquatorialRadianos As Double 'a
		Dim ldblExcentricidade As Double 'e 'ec
		Dim ldblEisq As Double 'e1sq
		Dim ldblFatorEscala As Double 'k0
		Dim ldblTamanhoArco As Double
		Dim ldblMu As Double
		Dim ldblEi As Double
		Dim ldblCa As Double 'C1
		Dim ldblCb As Double
		Dim ldblCcc As Double
		Dim ldblCd As Double
		Dim ldblQ0 As Double
		Dim ldblT0 As Double
		Dim ldblN0 As Double
		Dim ldblR0 As Double
		Dim ldblDD0 As Double
		Dim ldblLof1 As Double
		Dim ldblLof2 As Double
		Dim ldblLof3 As Double
		Dim ldblDeltaLongitude As Double
		
		Call InicializaVariaveis()
		
		ldblCoordenadaOesteLeste = adblCoordenadaOesteLeste
		ldblCoordenadaNorteSul = adblCoordenadaNorteSul
		'
		ldblLatitudeD = IIf(istrNorteSul = "N", ldblCoordenadaNorteSul, (10000000 - ldblCoordenadaNorteSul)) 'latd
		ldblLongitudeD = 500000 - ldblCoordenadaOesteLeste 'east 'lond
		
		'Datum Constantes
		ldblPolarRadianos = SelecionaRegiao(2) 'b
		ldblEquatorialRadianos = SelecionaRegiao(1) 'a
		ldblExcentricidade = Sqrt(1 - Pow(ldblPolarRadianos / ldblEquatorialRadianos, 2)) 'e 'ec
		
		ldblEisq = ldblExcentricidade * ldblExcentricidade / (1 - ldblExcentricidade * ldblExcentricidade) 'e1sq
		ldblFatorEscala = 0.9996 'k0
		'
		'Calculo Pegada da Latitude
		ldblTamanhoArco = (ldblLatitudeD / ldblFatorEscala) 'Arc Length
		ldblMu = ldblTamanhoArco / (ldblEquatorialRadianos * (1 - Pow(ldblExcentricidade, 2) / 4 - 3 * Pow(ldblExcentricidade, 4) / 64 - 5 * Pow(ldblExcentricidade, 6) / 256))
		'Ei
		ldblEi = (1 - Pow(1 - ldblExcentricidade * ldblExcentricidade, 1 / 2)) / (1 + Pow(1 - ldblExcentricidade * ldblExcentricidade, 1 / 2))
		'Ca
		ldblCa = 3 * ldblEi / 2 - 27 * Pow(ldblEi, 3) / 32 'C1
		ldblCb = 21 * Pow(ldblEi, 2) / 16 - 55 * Pow(ldblEi, 4) / 32
		ldblCcc = 151 * Pow(ldblEi, 3) / 96
		ldblCd = 1097 * Pow(ldblEi, 4) / 512
		'phi1
		idblPegadaLatitude = ldblMu + ldblCa * System.Math.Sin(2 * ldblMu) + ldblCb * System.Math.Sin(4 * ldblMu) + ldblCcc * System.Math.Sin(6 * ldblMu) + ldblCd * System.Math.Sin(8 * ldblMu)
		'
		'Constantes para as formulas
		ldblQ0 = ldblEisq * Pow(System.Math.Cos(idblPegadaLatitude), 2)
		ldblT0 = Pow(System.Math.Tan(idblPegadaLatitude), 2)
		ldblN0 = ldblEquatorialRadianos / Pow(1 - Pow(ldblExcentricidade * System.Math.Sin(idblPegadaLatitude), 2), 1 / 2)
		ldblR0 = ldblEquatorialRadianos * (1 - ldblExcentricidade * ldblExcentricidade) / Pow(1 - Pow(ldblExcentricidade * System.Math.Sin(idblPegadaLatitude), 2), 3 / 2)
		ldblDD0 = ldblLongitudeD / (ldblN0 * ldblFatorEscala)
		'
		'Coeficientes para Calcular a Latitude
		idblFact1 = ldblN0 * System.Math.Tan(idblPegadaLatitude) / ldblR0
		idblFact2 = (ldblDD0 * ldblDD0) / 2
		idblFact3 = (5 + 3 * ldblT0 + 10 * ldblQ0 - 4 * ldblQ0 * ldblQ0 - 9 * ldblEisq) * Pow(ldblDD0, 4) / 24
		idblFact4 = (61 + 90 * ldblT0 + 298 * ldblQ0 + 45 * ldblT0 * ldblT0 - 252 * ldblEisq - 3 * ldblQ0 * ldblQ0) * Pow(ldblDD0, 6) / 720
		'
		'Coeficientes para calcular a Longitude
		ldblLof1 = ldblDD0
		ldblLof2 = (1 + 2 * ldblT0 + ldblQ0) * Pow(ldblDD0, 3) / 6
		ldblLof3 = (5 - 2 * ldblQ0 + 28 * ldblT0 - 3 * Pow(ldblQ0, 2) + 8 * ldblEisq + 24 * Pow(ldblT0, 2)) * Pow(ldblDD0, 5) / 120
		'
		'Auxiliar
		ldblDeltaLongitude = (ldblLof1 - ldblLof2 + ldblLof3) / System.Math.Cos(idblPegadaLatitude)
		idblDeltaLongitudeDecimal = ldblDeltaLongitude * 180 / Pi
		
		'
		'
		'
		Call ResultadoLatitudeLongitude(pdblResultadoLatitude, pdblResultadoLongitude)
	End Sub
	
	Private Sub ResultadoLatitudeLongitude(ByRef pdblResultadoLatitude As Double, ByRef pdblResultadoLongitude As Double)
		Dim ldblResultadoLatitude As Double
		Dim ldblResultadoLongitude As Double
		ldblResultadoLatitude = 180 * (idblPegadaLatitude - idblFact1 * (idblFact2 + idblFact3 + idblFact4)) / Pi
		ldblResultadoLongitude = iintZonaCentralLongitude - idblDeltaLongitudeDecimal
		pdblResultadoLatitude = IIf(istrNorteSul = "N", ldblResultadoLatitude, (ldblResultadoLatitude * -1))
		pdblResultadoLongitude = ldblResultadoLongitude
		
		'Call MsgBox("Latitude: " & IIf(istrNorteSul = "N", ldblResultadoLatitude, (ldblResultadoLatitude * -1)) & vbCrLf & "Longitude: " & ldblResultadoLongitude)
	End Sub
	
	Private Function SelecionaRegiao(ByVal aintTipo As Short) As Double
		'WGS 84 - SIGARS 2000
		Dim ldblRet As Double
		Select Case aintTipo
			Case Is = 1
				ldblRet = 6378137#
			Case Is = 2
				ldblRet = 6356752.3142
			Case Is = 3
				ldblRet = 3.35281066474748E-03
			Case Is = 4
				ldblRet = (1 / 3.35281066474748E-03)
			Case Else
				ldblRet = 0
		End Select
		SelecionaRegiao = ldblRet
		
	End Function
	
	Private Function Sqrt(ByVal valor As Double) As Double
		Sqrt = valor ^ (1 / 2)
	End Function
	
	Private Function Pow(ByVal valor As Double, ByVal potencia As Double) As Double
		Pow = valor ^ potencia
	End Function
	
	Public Function Convert_Degree(ByRef Decimal_Deg As Object) As Object
		Dim Degrees As Object
		Dim Minutes As Object
		Dim Seconds As Object
		'With Application
		'Set degree to Integer of Argument Passed
		'UPGRADE_WARNING: Couldn't resolve default property of object Degrees. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
		Degrees = Int(CDbl(Decimal_Deg))
		'Set minutes to 60 times the number to the right
		'of the decimal for the variable Decimal_Deg
		'UPGRADE_WARNING: Couldn't resolve default property of object Degrees. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
		'UPGRADE_WARNING: Couldn't resolve default property of object Decimal_Deg. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
		'UPGRADE_WARNING: Couldn't resolve default property of object Minutes. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
		Minutes = (Decimal_Deg - Degrees) * 60
		'Set seconds to 60 times the number to the right of the
		'decimal for the variable Minute
		'UPGRADE_WARNING: Couldn't resolve default property of object Minutes. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
		'UPGRADE_WARNING: Couldn't resolve default property of object Seconds. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
		Seconds = VB6.Format((Minutes - Int(CDbl(Minutes))) * 60, "0")
		'Returns the Result of degree conversion
		'(for example, 10.46 = 10~ 27  ' 36")
		'UPGRADE_WARNING: Couldn't resolve default property of object Seconds. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
		'UPGRADE_WARNING: Couldn't resolve default property of object Degrees. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
		'UPGRADE_WARNING: Couldn't resolve default property of object Convert_Degree. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
		Convert_Degree = " " & Degrees & "° " & Int(CDbl(Minutes)) & "' " & Seconds + Chr(34)
		'End With
	End Function
End Module