VB .net Online: Projeção de Mercator
Atualizado: 30 de jul. de 2023
Acesse o site https://onecompiler.com/vb/3z5xwszek e teste o código abaixo. Para detalhes históricos sobre esta projeção, consulte https://geozyx.com/blog/f/projeção-de-mercator?blogcategory=Projeção+Cilíndrica.
Imports System.Math
Public Class Elipsoide
Public SemiEixoMaior As double
Public Excentricidade As double
Public Nome As String
Public Sub New(nome as String, a as Double, f as Double)
Dim fi as Double = 1/f
SemiEixoMaior = a
Excentricidade = Sqrt(2*fi - fi^2)
Nome = nome
End Sub
End Class
Public Class Mercator
Public Elip As Elipsoide
Public x As Double
Public y As Double
Public k As Double
Public m As Double
Public ReadOnly Property c As Double
Get
Return 0 ' convergência meridiana é sempre zero
End Get
End Property
Public Sub New(el As Elipsoide, lat As Double, lon As Double, Optional ByVal l0 As Double = 0)
Elip = el
m = l0
x = Calcular_X(lon * PI / 180)
y = Calcular_Y(lat * PI / 180)
k = Calcular_K(lat * PI / 180)
End Sub
Public Function Calcular_X(ByVal longitude As Double) As Double
Return Elip.SemiEixoMaior * (longitude - m * PI / 180)
End Function
Public Function Calcular_Y(ByVal latitude As Double) As Double
Dim termo1 As Double = Tan(PI / 4 + latitude / 2)
Dim termo2 As Double = (1 - Elip.Excentricidade * Sin(latitude)) / (1 + Elip.Excentricidade * Sin(latitude))
Dim termo3 As Double = Pow(termo2, Elip.Excentricidade / 2)
Return Elip.SemiEixoMaior * Log(termo1 * termo3)
End Function
Public Function Calcular_K(ByVal latitude As Double) As Double
Dim N As Double = Elip.SemiEixoMaior / Sqrt(1 - Pow(Elip.Excentricidade, 2) * Pow(Sin(latitude), 2))
Return Elip.SemiEixoMaior / (N * Cos(latitude))
End Function
Public Shared Function ProblemaInverso(el As Elipsoide, x As Double, y As Double, m As Double) As Double()
Dim e As Double = el.Excentricidade
Dim a As Double = el.SemiEixoMaior
Dim l As Double = (x / a + m * PI / 180)
Dim t As Double = Exp(-y / a)
Dim o0 As Double = PI / 2 - 2 * Atan(t)
Dim o(50) As Double
o(0) = o0
Dim i As Integer
For i = 1 To o.Length - 1
o(i) = PI / 2 - 2 * Atan(t * (((1 - e * Sin(o(i - 1))) / (1 + e * Sin(o(i - 1)))) ^ (e / 2)))
If Abs(o(i - 1) - o(i)) <= 0.00000001 Then
Exit For
End If
Next
Return New Double() {o(i) * 180 / PI, l * 180 / PI}
End Function
End Class
Module Teste
Public Sub Main()
Dim lat = -8.5 'Latitude em graus decimais
Dim lon = -32.2 'Longitude em graus decimais
Dim m = -33 'Meridiano Central
Dim el As New Elipsoide("GRS80", 6378137, 298.257222101)
Dim mer As New Mercator(el, lat, lon, m) 'PROBLEMA DIRETO
Dim mer_inv1 = Mercator.ProblemaInverso(el, mer.x, mer.y, m) 'PROBLEMA INVERSO
Dim str as String = "Coord. de Entrada (lat, lon, merid central):" & vbNewLine & "(" & lat & "," & lon & "," & m & ")"
Console.Write(str)
Console.Write(vbNewLine & "Problema Direto:")
str = vbNewLine & "(x, y, fator escala):" & vbNewLine & "(" & Round(mer.x,3) & "," & Round(mer.y,3) & "," & Round(mer.k,8) & ")"
Console.Write(str)
Console.Write(vbNewLine & "Problema Inverso:")
str = vbNewLine & "(lat, lon):" & vbNewLine & "(" & Round(mer_inv1(0),4) & "," & Round(mer_inv1(1),4) & ")"
Console.Write(str)
End Sub
End Module
Para acessar o formulário matemático da Projeção de Mercator clique aqui.
No código abaixo, altere os valores das coordenadas de entrada e clique em "Run". Aproveite!
Comments