Sub Class_Globals
Private Root As B4XView
Private xui As XUI
Private Const Airy1830_A As Double = 6377563.396
Private Const Airy1830_B As Double = 6356256.909
Private Const WGS84_a As Double = 6378137
Private Const WGS84_b As Double = 6356752.3142
Private Const MathPIdiv180 As Double = cPI / 180
Private Const Deg2Rad As Double = 2*cPI/360
Private Const Rad2Deg As Double = 360 / (2 * cPI)
Type eGPSLocation(Latitude As Double, Longitude As Double)
Type eProjCoordinate(Easting As Double, Northing As Double, Elevation As Double)
End Sub
Public Sub Initialize
' B4XPages.GetManager.LogEvents = True
End Sub
'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
Root = Root1
Root.LoadLayout("MainPage")
Log("EPSG:27700 to WGS84")
Dim Easting As Double = 533717
Dim Northing As Double = 170818
Dim eg As eGPSLocation = GetLatLonFromEPSG2770Coordinate(Easting, Northing)
Log("EPSG:27700: " & Easting & " " & Northing)
Log("WGS84: " & NumberFormat2(eg.Latitude, 1, 6, 1, False) & " " & NumberFormat2(eg.Longitude, 1, 6, 1, False))
Log(" ")
Log("WGS84 to EPSG:27700")
Dim Latitude As Double = 51.420611
Dim Longitude As Double = -0.078301
Dim ec As eProjCoordinate = GetEPSG2770CoordinateFromLatLon(Latitude, Longitude)
Log("WGS84: " & Latitude & " " & Longitude)
Log("EPSG:27700: " & NumberFormat2(ec.Easting, 0, 0, 0, False) & " " & NumberFormat2(ec.Northing, 0, 0, 0, False))
End Sub
Public Sub GetEPSG2770CoordinateFromLatLon(Latitude As Double, Longitude As Double) As eProjCoordinate
Dim eg As eGPSLocation = HelmertTransformation(Latitude, Longitude, Airy1830_A, Airy1830_B, WGS84_a, WGS84_b, _
446.448, -125.157, 542.06, _
0.1502 / 3600 * cPI / 180, 0.247 / 3600 * cPI / 180, 0.8421 / 3600 * cPI / 180, -20.4894 / 1000000 + 1, _
False)
Dim e As eProjCoordinate = GPS_GetTransverseMercator_FromLatLon(eg.Latitude, eg.Longitude, 400000, -100000, -2, 0.9996012717, 49, Airy1830_A, Airy1830_B)
Return e
End Sub
Public Sub GetLatLonFromEPSG2770Coordinate(Easting As Double, Northing As Double) As eGPSLocation
Dim e As eGPSLocation = GPS_GetLatLon_FromTransverseMercator(Easting, Northing, 400000, -100000, -2, 0.9996012717, 49, Airy1830_A, Airy1830_B)
Dim eg As eGPSLocation = HelmertTransformation(e.Latitude, e.Longitude, Airy1830_A, Airy1830_B, WGS84_a, WGS84_b, _
446.448, -125.157, 542.06, _
0.1502 / 3600 * cPI / 180, 0.247 / 3600 * cPI / 180, 0.8421 / 3600 * cPI / 180, -20.4894 / 1000000 + 1, _
True)
Return eg
End Sub
Private Sub HelmertTransformation(Latitude As Double, _
Longitude As Double, _
a_in As Double, b_in As Double, a_out As Double, b_out As Double, tx As Double, ty As Double, tz As Double, _
rx As Double, ry As Double, rz As Double, s1 As Double, _
bToWGS84 As Boolean) As eGPSLocation
If bToWGS84 = False Then
Dim temp_a_in As Double = a_in
Dim temp_b_in As Double = b_in
Dim temp_a_out As Double = a_out
Dim temp_b_out As Double = b_out
a_in = temp_a_out
b_in = temp_b_out
a_out = temp_a_in
b_out = temp_b_in
rx = (-1)*rx
ry = (-1)*ry
rz = (-1)*rz
tx = (-1)*tx
ty = (-1)*ty
tz = (-1)*tz
s1 = (-(s1 - 1) * 1000000) / 1000000 + 1
End If
Dim lat As Double = Latitude * Deg2Rad
Dim lon As Double = Longitude * Deg2Rad
Dim a As Double = a_in
Dim b As Double = b_in
Dim sinPHI As Double = Sin(lat)
Dim cosPHI As Double = Cos(lat)
Dim sinLambda As Double = Sin(lon)
Dim cosLambda As Double = Cos(lon)
Dim H As Double = 0 ' Höhe, wird hier nicht verwendet
Dim eSq As Double = (a * a - b * b) / (a * a)
Dim nu As Double = a / Sqrt(1 - eSq * sinPHI * sinPHI)
Dim x1 As Double = (nu + H) * cosPHI * cosLambda
Dim y1 As Double = (nu + H) * cosPHI * sinLambda
Dim z1 As Double = ((1 - eSq) * nu + H) * sinPHI
Dim x2 As Double = tx + x1 * s1 - y1 * rz + z1 * ry
Dim y2 As Double = ty + x1 * rz + y1 * s1 - z1 * rx
Dim z2 As Double = tz - x1 * ry + y1 * rx + z1 * s1
a = a_out
b = b_out
Dim precision As Double = 2 / a
eSq = (a * a - b * b) / (a * a)
Dim p As Double = Sqrt(x2 * x2 + y2 * y2)
Dim phi As Double = ATan2(z2, p * (1 - eSq))
Dim phiP As Double = 2 * cPI
Do While (Abs(phi - phiP) > precision)
nu = a / Sqrt(1 - eSq * Sin(phi) * Sin(phi))
phiP = phi
phi = ATan2(z2 + eSq * nu * Sin(phi), p)
Loop
Dim lambda As Double = ATan2(y2, x2)
H = p / Cos(phi) - nu
Dim egps As eGPSLocation
egps.Latitude = phi * Rad2Deg
egps.Longitude = lambda * Rad2Deg
Return egps
End Sub
Private Sub GPS_GetTransverseMercator_FromLatLon(Latitude As Double, _
Longitude As Double, _
FalseEasting As Double, _
FalseNorthing As Double, _
CentralMeridian As Double, _
CentralMeridianScaleFactor As Double, _
LatitudeOfOrigin As Double, _
Ellipsoid_A As Double, _
Ellipsoid_B As Double) As eProjCoordinate
Dim Northing, Easting, eccPrimeSquared, nu, T, C, A, M, M0 As Double
Dim eccSquared As Double = Ellipsoid_B / Ellipsoid_A
eccSquared = 1 - eccSquared * eccSquared
If Longitude < -180 Then Longitude = Longitude + 360
If Longitude > 180 Then Longitude = Longitude - 360
Dim LatRad As Double = Latitude * MathPIdiv180
Dim LongRad As Double = Longitude * MathPIdiv180
Dim LongOriginRad As Double = CentralMeridian * MathPIdiv180
Dim LatOriginRad As Double = LatitudeOfOrigin * MathPIdiv180
eccPrimeSquared = eccSquared / (1 - eccSquared)
nu = Ellipsoid_A / Sqrt(1 - eccSquared * Sin(LatRad) * Sin(LatRad))
T = Tan(LatRad) * Tan(LatRad)
C = eccPrimeSquared * Cos(LatRad) * Cos(LatRad)
A = Cos(LatRad) * (LongRad - LongOriginRad)
M = Ellipsoid_A * ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256) * LatRad - (3 * eccSquared / 8 + 3 * eccSquared * eccSquared / 32 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Sin(2 * LatRad) + (15 * eccSquared * eccSquared / 256 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Sin(4 * LatRad) - (35 * eccSquared * eccSquared * eccSquared / 3072) * Sin(6 * LatRad))
M0 = Ellipsoid_A * ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256) * LatOriginRad - (3 * eccSquared / 8 + 3 * eccSquared * eccSquared / 32 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Sin(2 * LatOriginRad) + (15 * eccSquared * eccSquared / 256 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Sin(4 * LatOriginRad) - (35 * eccSquared * eccSquared * eccSquared / 3072) * Sin(6 * LatOriginRad))
Easting = (CentralMeridianScaleFactor * nu * (A + (1 - T + C) * A * A * A / 6 + (5 - 18 * T + T * T + 72 * C - 58 * eccPrimeSquared) * A * A * A * A * A / 120))
Northing = (CentralMeridianScaleFactor * (M - M0 + nu * Tan(LatRad) * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24 + (61 - 58 * T + T * T + 600 * C - 330 * eccPrimeSquared) * A * A * A * A * A * A / 720)))
Dim Coord As eProjCoordinate
Coord.Easting = Easting + FalseEasting
Coord.Northing = Northing + FalseNorthing
Return Coord
End Sub
Private Sub GPS_GetLatLon_FromTransverseMercator(Easting As Double, _
Northing As Double, _
FalseEasting As Double, _
FalseNorthing As Double, _
CentralMeridian As Double, _
CentralMeridianScaleFactor As Double, _
LatitudeOfOrigin As Double, _
Ellipsoid_A As Double, _
Ellipsoid_B As Double) As eGPSLocation
Dim Lat, Lon, N1, T1, C1, R1, D, M1, mu1, phi1Rad As Double
Dim LongOriginRad As Double = CentralMeridian * MathPIdiv180
Dim LatOriginRad As Double = LatitudeOfOrigin * MathPIdiv180
Dim eccSquared As Double = Ellipsoid_B / Ellipsoid_A
eccSquared = 1 - eccSquared * eccSquared
Dim e1 As Double = (1 - Sqrt(1 - eccSquared)) / (1 + Sqrt(1 - eccSquared))
Dim eccPrimeSquared As Double = (eccSquared) / (1 - eccSquared)
Dim M0 As Double = Ellipsoid_A * ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256) * LatOriginRad - (3 * eccSquared / 8 + 3 * eccSquared * eccSquared / 32 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Sin(2 * LatOriginRad) + (15 * eccSquared * eccSquared / 256 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Sin(4 * LatOriginRad) - (35 * eccSquared * eccSquared * eccSquared / 3072) * Sin(6 * LatOriginRad))
M1 = M0 + (Northing - FalseNorthing) / CentralMeridianScaleFactor
mu1 = M1 / (Ellipsoid_A * (1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256))
phi1Rad = mu1 + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Sin(2 * mu1) + (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32) * Sin(4 * mu1) + (151 * e1 * e1 * e1 / 96) * Sin(6 * mu1)
N1 = Ellipsoid_A / Sqrt(1 - eccSquared * Sin(phi1Rad) * Sin(phi1Rad))
T1 = Tan(phi1Rad) * Tan(phi1Rad)
C1 = eccPrimeSquared * Cos(phi1Rad) * Cos(phi1Rad)
R1 = Ellipsoid_A * (1 - eccSquared) / Power(1 - eccSquared * Sin(phi1Rad) * Sin(phi1Rad), 1.5)
D = (Easting - FalseEasting) / (N1 * CentralMeridianScaleFactor)
Lat = phi1Rad - (N1 * Tan(phi1Rad) / R1) * (D * D / 2 - (5 + 3 * T1 + 10 * C1 - 4 * C1 * C1 - 9 * eccPrimeSquared) * D * D * D * D / 24 + (61 + 90 * T1 + 298 * C1 + 45 * T1 * T1 - 252 * eccPrimeSquared - 3 * C1 * C1) * D * D * D * D * D * D / 720)
Lon = (D - (1 + 2 * T1 + C1) * D * D * D / 6 + (5 - 2 * C1 + 28 * T1 - 3 * C1 * C1 + 8 * eccPrimeSquared + 24 * T1 * T1) * D * D * D * D * D / 120) / Cos(phi1Rad)
Dim e As eGPSLocation
e.Latitude = Lat * (180.0 / cPI)
e.Longitude = (Lon + LongOriginRad) * (180.0 / cPI)
Return e
End Sub